【问题标题】:Components on top of components block the mouse position组件顶部的组件挡住鼠标位置
【发布时间】:2013-09-12 20:42:45
【问题描述】:

我的 Delphi 7 应用程序有两个 TPageControls,它们之间有一个 TSplitter。每个 TPageControl 上有两个 TTabSheets。每个 TTabSheet 是一个 TWebBrowser。有图片吗?

这种组件排列的问题是无法跟踪鼠标的位置,因为TWebBrowser没有OnMouseMove事件,而且在这堆ClientAligned组件下也永远不会触发TForm的OnMouseMove事件。

我需要知道的是鼠标在任何时候都相对于应用程序的 XY 位置。 IOW,我需要知道鼠标何时移动,何时移动,一个函数会:

GetMouseLocationNow(var X, Y : Integer);

我该怎么做?

【问题讨论】:

  • 为什么需要坐标追踪?您在这些浏览器中显示的内容是什么?我要求建议您比一些定期询问坐标更好的方法,因为例如滚动偏移,这些坐标甚至可能与显示的 Web 浏览器的内容不匹配。
  • 我需要知道何时将焦点设置在鼠标下方的 TWebBrowser 上。这样,当用户使用鼠标滚轮时,TWebBrowser 内容将滚动。由于始终有两个 TWebBrowser 可见,因此我需要一些方法来知道将焦点设置在哪个 TWebBrowser 上。我只能通过跟踪鼠标位置来做到这一点。
  • 如果您的目标是具有鼠标滚动控件功能,我认为您需要全局捕获鼠标滚动事件并询问光标下哪个控件而不是鼠标移动跟踪。
  • 您的建议很有趣,但我想知道捕捉鼠标滚动事件是否为时已晚,看看在触发滚动事件后仍然需要关注 TWebBrowser。
  • 不,你不会设置焦点。您只需将WM_MOUSEWHEEL 消息发送到光标下的控件。我已经看到此功能仅在没有窃取焦点的情况下实现。当用户只是将鼠标悬停并滚动滚轮时,他们会窃取控件的焦点,这很烦人。但是没关系。总之祝你好运! ;-)

标签: delphi


【解决方案1】:

要在应用程序范围内跟踪鼠标移动,您必须跟踪 WM_MOUSEMOVE 消息。您可以为此使用TApplicationEvents 组件。因此,将TApplicationEvents 放在表单上,​​并在OnMessage 事件中处理WM_MOUSEMOVELParam 中的低位字指定X 光标的坐标(相对于发布消息的窗口),高位字Y 坐标。

procedure TfrmMain.ApplicationEventsMessage(var Msg: tagMSG; var Handled: Boolean);
var
  Pt: TPoint;
begin
  if Msg.message = WM_MOUSEMOVE then begin
    Pt := Point(WORD(Msg.lParam), HiWord(Msg.lParam));
    windows.ClientToScreen(Msg.hwnd, Pt);
    windows.ScreenToClient(Handle, Pt);
    MouseMoved(Pt.X, Pt.Y);
  end;
end;

procedure TfrmMain.MouseMoved(const AX, AY: Integer);
begin
  // do the work here
end;

【讨论】:

  • 谢谢,但您的代码没有告诉我鼠标何时移动。使用我上面描述的组件布局,我不知道鼠标已经移动。在我知道鼠标已经移动之前,我不会调用该函数。
  • 谢谢@RobKennedy,不知道这个!我编辑了上面的函数。 user1527613,这不是您在原始问题中提出的问题。也许您可以显式处理WM_MOUSEMOVE 消息。
  • @user1527613,我编辑了上面的答案以包含WM_MOUSEMOVE tracking。
  • LOWORD 和 HIWORD 在 Delphi 7 中不是有效函数。我还应该澄清一下,我需要相对于 TForm 的客户区域的 XY 位置。
猜你喜欢
  • 2021-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-19
相关资源
最近更新 更多