-
Михаил Соколов (05.08.15 11:15) [0]OnLVSubItemDraw всегда присылает SubItemIdx=0
Где в KOL починить - не нашел. Подозреваю что в районе WndProc_LVSubitemDraw но там вроде все нормально, полный перебор идет.
Пример кода:
(по-идее должен раскрасить в шахматном порядке, а красит полосами)Uses Windows, KOL;
type
PForm1=^TForm1;
TForm1=object(Tobj)
Form, lv : pControl;
public
function SubitemDraw( Sender: PControl; DC: HDC; Dummy {always 0 !}: DWORD;
ItemIdx, SubItemIdx: Integer; const Rect: TRect;
ItemState: TDrawState; var TextColor, BackColor: TColor ): Boolean;
end;
function TForm1.SubItemDraw( Sender: PControl; DC: HDC; Dummy {always 0 !}: DWORD;
ItemIdx, SubItemIdx: Integer; const Rect: TRect;
ItemState: TDrawState; var TextColor, BackColor: TColor ): Boolean;
begin
//if SubItemIdx>0 then MsgOk('Catch!'); // ни разу не выстреливает
BackColor:=$FFFFFF*((ItemIdx+SubItemIdx) and 1); // шахматная раскраска
Result:=true; // Что true, что false возвращаем, разницы нет
end;
var
Form1:pForm1;
x, y, n : Integer;
begin
New(Form1,Create);
with Form1^ do begin
Form:= NewForm(nil, 'Test ListView Subitem Draw');
Applet:=Form;
Form.Add2AutoFree(Form1);
lv:=NewListView(Form, lvsDetail, [lvoNoSortHeader, lvoRowSelect], nil, nil, nil).SetAlign(caClient);
for x:=0 to 9 do
lv.LVColAdd('xxx', taCenter, 100);
for y:=0 to 100 do begin
n:=lv.LVItemAdd('xxx');
for x:=1 to 9 do
lv.lvItems[n,x]:='xxx';
end;
lv.OnLVSubItemDraw:=SubItemDraw;
end;
Run(Form1.Form);
end. -
DWorker (06.08.15 07:24) [1]Если по-быстрому то правится так:
function WndProc_LVSubitemDraw( Sender: PControl; var Msg: TMsg;
var Rslt: LRESULT ): Boolean;
var NMCustDraw: PNMLVCustomDraw;
NMHdr: PNMHdr;
ItemIdx, SubItemIdx: Integer;
S: TListViewItemState;
ItemState: TDrawState;
//was_clrText, was_clrTextBk: DWORD;
R: TRect;
begin
Result := FALSE;
if Msg.message = WM_NOTIFY then
begin
NMHdr := Pointer( Msg.lParam );
if (Longint(NMHdr.code) = NM_CUSTOMDRAW)
{$IFDEF NIL_EVENTS} and Assigned( Sender.EV.fOnLVCustomDraw ) {$ENDIF}
then
begin
NMCustDraw := Pointer( Msg.lParam );
CASE NMCustDraw.nmcd.dwDrawStage OF
CDDS_PREPAINT:
begin
Rslt := CDRF_NOTIFYITEMDRAW;
Result := TRUE;
Exit;
end;
CDDS_ITEMPREPAINT:
begin
Rslt := CDRF_NOTIFYITEMDRAW or CDRF_DODEFAULT;
end;
END;
ItemIdx := NMCustDraw.nmcd.dwItemSpec;
ItemState := [ ];
if ItemIdx >= 0 then
begin
S := Sender.LVItemState[ ItemIdx ];
if lvisFocus in S then
include( ItemState, odsFocused );
if lvisSelect in S then
include( ItemState, odsSelected );
if lvisBlend in S then
include( ItemState, odsGrayed );
if lvisHighlight in S then
include( ItemState, odsMarked );
end;
if LongBool(NMCustDraw.nmcd.dwDrawStage and CDDS_SUBITEM) then
SubItemIdx := NMCustDraw.iSubItem
else
SubItemIdx := -1;
//was_clrText := NMCustDraw.clrText;
//was_clrTextBk := NMCustDraw.clrTextBk;
//for SubItemIdx := 0 to Sender.LVColCount-1 do
//begin
R := Sender.LVSubItemRect( ItemIdx, SubItemIdx );
if 0 = Sender.EV.FOnLVCustomDraw( Sender, NMCustDraw.nmcd.hdc, 0,
ItemIdx, SubItemIdx, R,
ItemState, TColor( NMCustDraw.clrText ), TColor( NMCustDraw.clrTextBk ) )
then
begin
Rslt := CDRF_DODEFAULT; { вернули FALSE - не хотят рисовать, тогда по умолчанию }
//break;
end;
// else
//if (was_clrText <> NMCustDraw.clrText) or
// (was_clrTextBk <> NMCustDraw.clrTextBk) then
//begin
//Rslt := CDRF_NEWFONT; { поменяли цвет текста или фона - рисование по умолчанию, но с новыми цветами }
//break;
//end;
//end;
Result := TRUE;
end;
end;
end;
А если надо правильнее, то лучше разобраться с другим событием OnLVCustomDraw, даже демо проект должен быть DemoLVCustomDraw -
Михаил Соколов (06.08.15 07:49) [2]Спасибо! Заработало!
С OnLVCustomDraw не стал связываться, потому что с OnLVSubItemDraw показалось быстрее и проще, кто ж знал что он не работает как следует...