如何在调整列大小时重新绘制 TListView 列?
How to repaint a TListView column while resizing the column?
在 Windows 10 in Delphi 11 Alexandria 中的 32 位 VCL 应用程序中,我需要在调整列大小时重新绘制整个 TListView
列。 ListView 项目和子项目显示为 ListView.OwnerDraw
。
所以我将 ListView 子类化为在列调整大小时收到通知:
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;
不幸的是,它仅在调整列大小时结束时做出反应,而不是在调整列大小时时!另外,该列未重新绘制!
HDN_TRACK
未交付的问题 is well known。一个解决方案是寻找 HDN_ITEMCHANGING
代替。
关于重绘的问题,注意你有
InvalidateRect(FHeaderHandle, nil, true);
这要求重新绘制 列表视图 header。 header 是一个单独的 window,一个 header control,它占据列表视图的顶行并且仅包含列标题。
您不想使 header 无效,而是要使列表视图中的实际列无效。
只是使整个列表视图无效。
在 Windows 10 in Delphi 11 Alexandria 中的 32 位 VCL 应用程序中,我需要在调整列大小时重新绘制整个 TListView
列。 ListView 项目和子项目显示为 ListView.OwnerDraw
。
所以我将 ListView 子类化为在列调整大小时收到通知:
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;
不幸的是,它仅在调整列大小时结束时做出反应,而不是在调整列大小时时!另外,该列未重新绘制!
HDN_TRACK
未交付的问题 is well known。一个解决方案是寻找 HDN_ITEMCHANGING
代替。
关于重绘的问题,注意你有
InvalidateRect(FHeaderHandle, nil, true);
这要求重新绘制 列表视图 header。 header 是一个单独的 window,一个 header control,它占据列表视图的顶行并且仅包含列标题。
您不想使 header 无效,而是要使列表视图中的实际列无效。
只是使整个列表视图无效。