0

在 Delphi 11 Alexandria 的 Windows 10 中的 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;

不幸的是,它只在调整列大小的末尾做出反应,而不是在调整列大小时做出反应!此外,该列没有重新粉刷!

4

1 回答 1

2

HDN_TRACK不交付的问题是众所周知的。一个解决方案是寻找HDN_ITEMCHANGING

关于重绘问题,请注意您这样做

InvalidateRect(FHeaderHandle, nil, true);

这请求重绘列表视图标题。标题是一个单独的窗口,一个标题控件,它占据列表视图的顶行并且只包含列标题。

您不想使标题无效,而是使列表视图中的实际列无效。

只是使整个列表视图无效。

于 2022-01-26T20:19:55.023 回答