如果鼠标不在 VirtualTreeView (TVirtualStringTree) 上,如何禁用 MouseWheel

发布于 2024-12-19 06:23:52 字数 397 浏览 3 评论 0原文

如果 TVirtualStringTree 获得焦点,则默认情况下它会在鼠标滚轮上滚动,即使鼠标未超出控制范围(除非它位于另一个 TVirtualStringTree 上方)。

有没有一种快速而优雅的方法来禁用这种行为?

我已经使用 OnMouseWheel 事件执行此操作,并使用 PtInRect 检查 Mouse.CursorPos 是否在控件上,但我有一种感觉一个更好的方法来做同样的事情,因为这样我必须为我添加的每个 TreeView 定义一个新事件,并且还要处理何时聚焦/取消聚焦控件,所以我希望必须有更好的方法来禁用它。

因此,需要明确的是,我希望鼠标滚轮功能能够像往常一样工作,但仅当鼠标位于 VirtualTreeView 上时才有效。

TVirtualStringTree behaves by default if it is focused - it will scroll on mouse wheel even if mouse is not over control (except if it is over another TVirtualStringTree).

Is there a quick and elegant way to disable this behaviour?

I already did this with OnMouseWheel event and checking with PtInRect if Mouse.CursorPos if it is over a control but I have a feeling that there is a better way to do the same because this way I'd have to define a new event for each TreeView I add and also handle when to focus/unfocus the control so I hope there must be a better way to disable this.

So to be clear, I want mousewheel function to work as usual, but only when mouse is over VirtualTreeView.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

や三分注定 2024-12-26 06:23:52

表单

将 TApplicationEvents 控件下拉到TApplicationEvents onMessage 中的

 procedure TForm5.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
 var
  pnt: TPoint;
  ctrl: TWinControl;
 begin
  if Msg.message = WM_MOUSEWHEEL then
  begin
    if not GetCursorPos(pnt) then Exit;
    ctrl := FindVCLWindow(pnt);
    if Assigned(ctrl) then
      Msg.hwnd := ctrl.Handle;
  end;
 end;

Drop down a TApplicationEvents control to the form

in TApplicationEvents onMessage

 procedure TForm5.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
 var
  pnt: TPoint;
  ctrl: TWinControl;
 begin
  if Msg.message = WM_MOUSEWHEEL then
  begin
    if not GetCursorPos(pnt) then Exit;
    ctrl := FindVCLWindow(pnt);
    if Assigned(ctrl) then
      Msg.hwnd := ctrl.Handle;
  end;
 end;
哑剧 2024-12-26 06:23:52

或者您可以尝试稍微修改 VirtualTree。在下面的示例中使用了插入类。如果您将此代码粘贴到您的单元中,那么您的所有 VirtualTree 都将在表单中以这种方式运行。

uses
  VirtualTrees;

type
  TVirtualStringTree = class(VirtualTrees.TVirtualStringTree)
  private
    FMouseInside: Boolean;
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure CMMouseWheel(var Message: TCMMouseWheel); message CM_MOUSEWHEEL;
  end;

implementation

procedure TVirtualStringTree.CMMouseEnter(var Message: TMessage);
begin
  inherited;
  // SetFocus will set the focus to the tree which is entered by mouse
  // but it's probably what you don't want to, if so, just remove the
  // following line. If you want to scroll the tree under mouse without
  // stealing the focus from the previous control then this is not the
  // right way - the tree must either be focused or you can steal it by
  // the SetFocus. This only resolves the case when you have a focused
  // tree and leave it with the mouse, then no scrolling is performed,
  // if you enter it, you can scroll again.
  SetFocus;
  // set the flag which tells about mouse inside
  FMouseInside := True;
end;

procedure TVirtualStringTree.CMMouseLeave(var Message: TMessage);
begin
  // reset the flag about mouse inside
  FMouseInside := False;
  inherited;
end;

procedure TVirtualStringTree.CMMouseWheel(var Message: TCMMouseWheel);
begin
  // if mouse is inside then let's wheel the mouse otherwise nothing
  if FMouseInside then
    inherited;
end;

Or you might try to modify the VirtualTree a bit. In the following example is used the interposed class. If you paste this code into your unit, then all of your VirtualTrees will behave this way in the form.

uses
  VirtualTrees;

type
  TVirtualStringTree = class(VirtualTrees.TVirtualStringTree)
  private
    FMouseInside: Boolean;
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure CMMouseWheel(var Message: TCMMouseWheel); message CM_MOUSEWHEEL;
  end;

implementation

procedure TVirtualStringTree.CMMouseEnter(var Message: TMessage);
begin
  inherited;
  // SetFocus will set the focus to the tree which is entered by mouse
  // but it's probably what you don't want to, if so, just remove the
  // following line. If you want to scroll the tree under mouse without
  // stealing the focus from the previous control then this is not the
  // right way - the tree must either be focused or you can steal it by
  // the SetFocus. This only resolves the case when you have a focused
  // tree and leave it with the mouse, then no scrolling is performed,
  // if you enter it, you can scroll again.
  SetFocus;
  // set the flag which tells about mouse inside
  FMouseInside := True;
end;

procedure TVirtualStringTree.CMMouseLeave(var Message: TMessage);
begin
  // reset the flag about mouse inside
  FMouseInside := False;
  inherited;
end;

procedure TVirtualStringTree.CMMouseWheel(var Message: TCMMouseWheel);
begin
  // if mouse is inside then let's wheel the mouse otherwise nothing
  if FMouseInside then
    inherited;
end;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文