【问题标题】:Mouse wheel event鼠标滚轮事件
【发布时间】:2011-04-09 17:29:53
【问题描述】:

我有一个包含许多控件(树视图、备忘录、列表框、面板等)的表单。

当鼠标悬停在组件上并滚动滚轮时,我想自动移动这些控件的滚动条。

就像 rad studios 检查栏、工具箱、项目经理的工作方式一样。

并且在每个控件上都输入相同的代码是不可能的(到目前为止超过 11 个控件)

[已编辑]

感谢您的所有回答,但是

按钮等控件没有 滚动条,所以他们的父母(比如 面板,框架)必须移动时 鼠标滚轮在按钮上移动(子控件)

【问题讨论】:

  • 所以你想覆盖默认行为(最常见的是,控件也需要键盘焦点)?
  • 另外我想将键盘焦点更改为鼠标悬停
  • 这听起来是个坏主意,但如果你这样做了,你就不必玩转轮消息了。我猜只需在 MouseEnter 中调用 SetFocus。还是个坏主意!
  • @PIGP - 正如@David 所说,这是一个非常糟糕的主意。用户可能有打字时将指针移到一边的习惯,如果失去焦点,他们将无法打字……

标签: windows delphi controls scroll mousewheel


【解决方案1】:

在表单中添加TApplicationEvents,并添加OnMessage 处理程序:

procedure TForm1.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
    begin
      SendMessage(ctrl.Handle, Msg.message, Msg.wParam, Msg.lParam);
      Handled := true; // or maybe Msg.message := WM_NULL;
    end;
  end;
end;

更新

David Heffernan [参见 cmets] 提出了一种改进此代码的聪明方法:

procedure TForm1.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;

【讨论】:

  • 鼠标滚轮事件转到输入焦点的窗口而不是光标下的窗口。
  • @David:是的,我们都知道。这也是为什么 OP 确实首先提出了他的问题。 (如果反过来是真的,OP 永远不会问他的问题。)我并不是说改变这种行为是一个好主意,而只是提供了有关如何做到这一点的技术细节,因为那是确切的问题的重点。如果您想投反对票,我建议您对 OP 的问题投反对票,而不是对问题的(严格来说)正确答案。
  • (Delphi 2009 IDE 的行为是这样的:当滚轮旋转时,光标下方的控件会滚动,与键盘焦点无关。)
猜你喜欢
  • 1970-01-01
  • 2010-10-03
  • 2014-12-30
  • 2011-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多