Сегодня почти целый день убил разбираясь как сам компонент перерисовывает строки. Испробовал с десяток способов борьбы.
В итоге понял что без обработки сообщения NM_CUSTOMDRAW ничего путного не получится.
Вот что у меня получилось в итоге:
procedure TForm1.FormCreate(Sender: TObject);
begin
OldWindowProc:=ListView1.WindowProc;
ListView1.WindowProc:=NewWindowProc;
end;
function TForm1.CustomDrawLV(nmlvcd:TNMLVCustomDraw):Integer;
var SubItem:Boolean;
begin
Result := CDRF_DODEFAULT;
if (nmlvcd.nmcd.dwDrawStage and CDDS_ITEM) = 0 then
begin
if nmlvcd.nmcd.dwDrawStage=CDDS_PREPAINT then
Result := CDRF_NOTIFYITEMDRAW or CDRF_NOTIFYPOSTPAINT or CDRF_NOTIFYPOSTERASE or CDRF_NOTIFYSUBITEMDRAW;
end else
begin
SubItem := (nmlvcd.nmcd.dwDrawStage and CDDS_SUBITEM) <> 0;
if SubItem and (nmlvcd.iSubItem = 0) then Exit;
if nmlvcd.nmcd.dwDrawStage and CDDS_ITEMPREPAINT <> 0 then
begin
if not SubItem then
begin
//рисую 1-ю колонку (Caption)
CustomDrawItem(ListView1,ListView1.Items[nmlvcd.nmcd.dwItemSpec]);
//Result := Result or CDRF_SKIPDEFAULT; //Если здесь убрать слеши то не рисуются СубИтемы
Result := Result or CDRF_NOTIFYSUBITEMDRAW or CDRF_NOTIFYPOSTPAINT or CDRF_NOTIFYPOSTERASE;
end
else
begin
//рисую SubItem (2-я и последующие колонки)
CustomDrawSubItem(ListView1,ListView1.Items[nmlvcd.nmcd.dwItemSpec],nmlvcd.iSubItem);
Result := Result or CDRF_SKIPDEFAULT or CDRF_NOTIFYPOSTPAINT or CDRF_NOTIFYPOSTERASE;
end;
end;
end;
end;
procedure TForm1.NewWindowProc(var Message: TMessage);
begin
case Message.Msg of
CN_NOTIFY:
with TWMNotify(Message) do
if NMHdr^.code=NM_CUSTOMDRAW then
begin result:=CustomDrawLV(PNMLVCustomDraw(NMHdr)^);
Exit;
end;
end;
OldWindowProc(Message);
end;
Все красиво и хорошо, но...
До совершенства не дотягивает. Получается мелькание первой колонки, т.к. ListView тоже ее перерисовывает из-за вот этой строки:
Result := Result or CDRF_NOTIFYSUBITEMDRAW or CDRF_NOTIFYPOSTPAINT or CDRF_NOTIFYPOSTERASE;
если же ее заменить на:
Result := Result or CDRF_SKIPDEFAULT;
то мелькание исчезает, но не рисуются остальные колонки.
кто-нибудь знает как объяснить ListView что я сам рисую содержимое первой колонки и при этом чтоб можно было рисовать и SubItem?