0

在 VCL 应用程序中,我试图在TListView使用此插入器类代码结束水平滚动时收到通知:

type  
  TListView = class(Vcl.ComCtrls.TListView)
  private
    procedure WMNotify(var AMessage: TWMNotify); message WM_NOTIFY; // used for other purposes
    procedure CNCommand(var Message: TWMCommand); message CN_COMMAND;
    procedure WMVScroll(var Msg: TWMHScroll); message WM_VSCROLL;
    procedure WMHScroll(var Msg: TWMHScroll); message WM_HSCROLL;
  protected
    procedure CreateWnd; override;  
  end;

implementation

procedure TListView.CNCommand(var Message: TWMCommand);
begin
   case Message.NotifyCode of
    EN_VSCROLL: CodeSite.Send('TListView.CNCommand: EN_VSCROLL'); // does not work
    EN_HSCROLL: CodeSite.Send('TListView.CNCommand: EN_HSCROLL'); // does not work
   end;
   inherited ;
end;

procedure TListView.WMHScroll(var Msg: TWMHScroll);
begin
   CodeSite.Send('TListView.WMHScroll: WM_HSCROLL'); // does work
   inherited;
end;

procedure TListView.WMVScroll(var Msg: TWMHScroll);
begin
   CodeSite.Send('TListView.WMVScroll: WM_VSCROLL'); // does work
   inherited;
end;

但是,只有在滚动时,我才会不断收到通知WM_HSCROLLWM_VSCROLL生成大量消息。

但我只需要在水平滚动结束时收到通知!这可能吗?

4

1 回答 1

4

给 Q 的评论非常相关。

首先,正如 Remy Lebeau 所说,WM_HSCROLL消息会告诉您操作是否完成:

procedure TListView.WMHScroll(var Msg: TWMHScroll);
begin
  inherited;
  if Msg.ScrollCode = SB_ENDSCROLL then
    ShowMessage('End scroll')
end;

但是,这只会让您知道由水平滚动条启动的滚动操作何时完成。目前,这包括以下滚动条操作:

  • 拇指松开
  • 单击滚动条向左或向右按​​钮
  • 单击滚动条空白区域(用于页面滚动)
  • 已选择滚动条上下文菜单项

但是列表视图控件还有很多其他的滚动方式,与滚动条无关:

  • 使用鼠标的水平滚轮(如果只有水平滚动条而没有垂直滚动条,则使用标准垂直滚轮)
  • 使用键盘的左右箭头键(或 Ctrl+Left/Right 进行页面滚动)
  • 使用MultiSelect = True, 用鼠标创建一个选择矩形(开始拖动到任何列表视图项之外)

因此,仅对 做出反应WM_HSCROLL,您将不会检测到这些滚动事件。几乎可以肯定,您想在滚动位置发生变化时做出反应,无论它是如何变化的。

而且,正如 AmigoJack 所写,“结束”的含义并不完全清楚(除了在拖动滚动条拇指后释放鼠标按钮时)。例如,如果您使用鼠标滚轮滚动,结果是一个大滚动操作还是几个小滚动操作?毕竟,在任何情况下,即使是拇指跟踪,控件都会在每一个小步骤中重新绘制自己。

所以可能你最好的选择是使用

procedure TListView.CNNotify(var Message: TMessage);
begin
  inherited;
  if PNMHDR(Message.lParam).code = LVN_ENDSCROLL then
    // Scrolled
end;

根据文件

当滚动操作结束时通知列表视图控件的父窗口。

请注意,文档说在操作结束时发送通知。不过,当您拖动滚动条拇指时,您会发现每次小的更新都会发送它。如上所述,这是有道理的:在每一个小步骤之后确实执行了滚动。

于 2022-02-13T00:06:48.920 回答