Delphi 如果鼠标未在VirtualTreeView(TVirtualStringTree)上,如何禁用鼠标滚轮

Delphi 如果鼠标未在VirtualTreeView(TVirtualStringTree)上,如何禁用鼠标滚轮,delphi,delphi-2010,c++builder,virtualtreeview,c++builder-2010,Delphi,Delphi 2010,C++builder,Virtualtreeview,C++builder 2010,TVirtualStringTree在默认情况下会在聚焦状态下运行-即使鼠标未处于控制上方,它也会在鼠标滚轮上滚动(除非它位于另一个TVirtualStringTree上方) 有没有一种快速而优雅的方法来禁用这种行为 我已经用onmouseheel事件完成了这项工作,并用PtInRectifMouse.CursorPos检查了控件是否在控件上,但我觉得有更好的方法来完成这项工作,因为这样我就必须为我添加的每个树视图定义一个新事件,并处理何时聚焦/取消聚焦控件,所以我希望如此必须有更好的方法来禁用

TVirtualStringTree在默认情况下会在聚焦状态下运行-即使鼠标未处于控制上方,它也会在鼠标滚轮上滚动(除非它位于另一个TVirtualStringTree上方)

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

我已经用
onmouseheel
事件完成了这项工作,并用
PtInRect
if
Mouse.CursorPos
检查了控件是否在控件上,但我觉得有更好的方法来完成这项工作,因为这样我就必须为我添加的每个树视图定义一个新事件,并处理何时聚焦/取消聚焦控件,所以我希望如此必须有更好的方法来禁用此功能


为了清楚起见,我希望mousewheel功能像往常一样工作,但仅当鼠标位于VirtualTreeView上时才工作。

将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;

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

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;

不幸的是,这两种解决方案我都不太喜欢,我宁愿坚持自己的解决方案。我想VirtualTreeView中可能已经内置了一些更简单的功能。如果有人提出其他建议,我会再等几天,如果没有,我会接受这个解决方案。@coder,是的,你的意图是正确的,但不幸的是,我认为没有比你得到的答案更简单的方法。@coder,VT中没有内置的功能。请注意,所有控件都是这样运行的。如果您将在表单上显示备忘,并且您将滚动鼠标,则即使您不在控制范围内,也会执行滚动。这可能就是你要接受这篇文章的原因,因为它会影响所有控件,而不仅仅是VT。@TLama是的,你完全正确,其他控件也会发生这种情况,所以这不是VT独有的事情。Embarcadero的这段视频还显示了鼠标滚轮的这种情况:看到了吗