In a 32-bit VCL Application in Windows 10 in Delphi 11 Alexandria, I need to repaint a whole TListView column while resizing the column. The ListView items and subitems are being displayed with ListView.OwnerDraw.
So I subclassed the ListView to be notified when the column resizes:
TListView = class(Vcl.ComCtrls.TListView)
private
FHeaderHandle: HWND;
procedure WMNotify(var AMessage: TWMNotify); message WM_NOTIFY;
protected
procedure CreateWnd; override;
...
procedure TListView.CreateWnd;
begin
inherited;
FHeaderHandle := ListView_GetHeader(Handle);
end;
procedure TListView.WMNotify(var AMessage: TWMNotify);
begin
if (AMessage.NMHdr.hwndFrom = FHeaderHandle) and ((AMessage.NMHdr.code = HDN_ENDTRACK) or (AMessage.NMHdr.code = HDN_TRACK)) then
begin
TMessage(AMessage).Result := 0;
InvalidateRect(FHeaderHandle, nil, true);
CodeSite.Send('TListView.WMNotify: HDN_ENDTRACK');
end
else
inherited;
end;
Unfortunately, it reacts only at the END of column resizing, and not WHILE resizing the column! Also, the column is not repainted!
The issue with
HDN_TRACKnot being delivered is well known. A solution is to look forHDN_ITEMCHANGINGinstead.Regarding the repainting issue, notice that you do
This requests a repaint of the list view header. The header is a separate window, a header control, which occupies the top row of your list view and contains only the column captions.
You want to invalidate not the header, but the actual column in the list view.
Just invalidate the entire list view.