Delphi 如果鼠标未在VirtualTreeView(TVirtualStringTree)上,如何禁用鼠标滚轮
TVirtualStringTree在默认情况下会在聚焦状态下运行-即使鼠标未处于控制上方,它也会在鼠标滚轮上滚动(除非它位于另一个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检查了控件是否在控件上,但我觉得有更好的方法来完成这项工作,因为这样我就必须为我添加的每个树视图定义一个新事件,并处理何时聚焦/取消聚焦控件,所以我希望如此必须有更好的方法来禁用
onmouseheel
事件完成了这项工作,并用PtInRect
ifMouse.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的这段视频还显示了鼠标滚轮的这种情况:看到了吗