如何在TListView中水平滚动结束时得到通知?
How to be notified at the END of Horizontal Scrolling in TListView?
在 VCL 应用程序中,我试图在使用此插入器 class 代码在 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_HSCROLL
和 WM_VSCROLL
的通知,生成大量消息。
但我只需要在水平滚动结束时得到通知!这可能吗?
给Q的评论很中肯。
首先,正如 Remy Lebeau 所说,WM_HSCROLL
消息会告诉您操作是否完成:
procedure TListView.WMHScroll(var Msg: TWMHScroll);
begin
inherited;
if Msg.ScrollCode = SB_ENDSCROLL then
ShowMessage('End scroll')
end;
但是,这仅让您知道水平滚动条发起的滚动操作何时完成。目前,这包括这些 scroll-bar 操作:
- 拇指松开
- 单击滚动条向左或向右按钮
- 点击滚动条空白区域(页面滚动)
- 已选择滚动条上下文菜单项
但列表视图控件还有很多其他方式可以滚动,与滚动条无关:
- 使用鼠标的水平滚轮(如果只有水平滚动条而没有垂直滚动条,则使用标准垂直滚轮)
- 使用键盘的左右箭头键(或 Ctrl+Left/Right 滚动页面)
- 使用
MultiSelect = True
,用鼠标制作一个选择矩形(开始拖动到任何 list-view 项目之外)
因此,仅对 WM_HSCROLL
作出反应,您将不会检测到这些滚动事件。几乎可以肯定的是,无论 如何 发生变化,您都希望在滚动位置发生变化时做出反应。
而且,正如 AmigoJack 所写,“结束”的含义并不完全清楚(除非您在拖动滚动条拇指后松开鼠标按钮)。例如,如果您使用鼠标滚轮滚动,结果是单个大滚动操作还是几个小滚动操作?毕竟,在任何情况下,即使是拇指跟踪,控件也会在每一个小步骤重新绘制自己。
所以最好的选择可能是使用
procedure TListView.CNNotify(var Message: TMessage);
begin
inherited;
if PNMHDR(Message.lParam).code = LVN_ENDSCROLL then
// Scrolled
end;
Notifies a list-view control's parent window when a scrolling operation ends.
请注意,文档说通知是在操作 结束 时发送的。尽管如此,当您拖动滚动条滑块时,您会发现每次小更新都会发送它。如上所述,这是合理的:滚动 确实在每一个这样的小步骤之后执行。
在 VCL 应用程序中,我试图在使用此插入器 class 代码在 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_HSCROLL
和 WM_VSCROLL
的通知,生成大量消息。
但我只需要在水平滚动结束时得到通知!这可能吗?
给Q的评论很中肯。
首先,正如 Remy Lebeau 所说,WM_HSCROLL
消息会告诉您操作是否完成:
procedure TListView.WMHScroll(var Msg: TWMHScroll);
begin
inherited;
if Msg.ScrollCode = SB_ENDSCROLL then
ShowMessage('End scroll')
end;
但是,这仅让您知道水平滚动条发起的滚动操作何时完成。目前,这包括这些 scroll-bar 操作:
- 拇指松开
- 单击滚动条向左或向右按钮
- 点击滚动条空白区域(页面滚动)
- 已选择滚动条上下文菜单项
但列表视图控件还有很多其他方式可以滚动,与滚动条无关:
- 使用鼠标的水平滚轮(如果只有水平滚动条而没有垂直滚动条,则使用标准垂直滚轮)
- 使用键盘的左右箭头键(或 Ctrl+Left/Right 滚动页面)
- 使用
MultiSelect = True
,用鼠标制作一个选择矩形(开始拖动到任何 list-view 项目之外)
因此,仅对 WM_HSCROLL
作出反应,您将不会检测到这些滚动事件。几乎可以肯定的是,无论 如何 发生变化,您都希望在滚动位置发生变化时做出反应。
而且,正如 AmigoJack 所写,“结束”的含义并不完全清楚(除非您在拖动滚动条拇指后松开鼠标按钮)。例如,如果您使用鼠标滚轮滚动,结果是单个大滚动操作还是几个小滚动操作?毕竟,在任何情况下,即使是拇指跟踪,控件也会在每一个小步骤重新绘制自己。
所以最好的选择可能是使用
procedure TListView.CNNotify(var Message: TMessage);
begin
inherited;
if PNMHDR(Message.lParam).code = LVN_ENDSCROLL then
// Scrolled
end;
Notifies a list-view control's parent window when a scrolling operation ends.
请注意,文档说通知是在操作 结束 时发送的。尽管如此,当您拖动滚动条滑块时,您会发现每次小更新都会发送它。如上所述,这是合理的:滚动 确实在每一个这样的小步骤之后执行。