当鼠标悬停在控件上时,如何获得绝对鼠标坐标

时间:2014-09-10 17:46:29

标签: delphi mouseevent

当鼠标悬停在已放置在主机控件上的控件上时,我想得到鼠标的绝对坐标。例如。主机控制是面板按钮放置在面板上。当鼠标悬停在按钮上时,我希望相对于面板获得鼠标坐标。

我已经尝试过显而易见的事情,看看我得到了什么:

procedure TfmWorkingScreen.pnlScreenAreaMouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
begin
   StatusBar1.SimpleText := 'Left ' + IntToStr(X) + '  Right ' + IntToStr(Y);
end;

显然,这仅在鼠标位于面板控件上时才有效。有没有办法获得所需的坐标?

2 个答案:

答案 0 :(得分:6)

OnMouseMove事件处理程序添加到子控件,即示例中的按钮。在OnMouseMove事件处理程序中,您会收到与子控件的客户端区域相关的XY光标坐标。如果主机控件是其OnMouseMove事件已触发的控件的直接父级,则使用控件的ClientToParent方法:

var
  PosRelParent: TPoint:
....
PosRelParent := (Sender as TControl).ClientToParent(Point(X, Y));

如果父控件可能在父/子关系的进一步向上,则可以将父控件传递给ClientToParent

PosRelParent := (Sender as TControl).ClientToParent(Point(X, Y), TheParent);

如果您希望表达相对于某个任意控件客户区的位置,那么您可以通过屏幕坐标转换,这是一个全局参考框架。

var
  PosRelScreen, PosRelOtherControl: TPoint:
  OtherControl: TWinControl;
....
PosRelScreen := (Sender as TControl).ClientToScreen(Point(X, Y));
PosRelOtherControl := OtherControl.ScreenToClient(PosRelScreen);

作为最终产品,您可以使用GetMessagePos获取通过调用GetMessage检索到的最后一条消息的鼠标屏幕相对坐标。

var
  MsgPos: TPoint;
....
MsgPos := TSmallPoint(GetMessagePos());

此时,您可以使用SomeControl.ScreenToClient(MsgPos)获取光标相对于该控件的客户区域的坐标。显然,如果您处于由排队的鼠标消息触发的事件处理程序中,则调用GetMessagePos才有意义。

答案 1 :(得分:0)

如果你想在你的程序之外听你的鼠标,你需要创建一个鼠标钩。

我早些时候向About.com提交了一篇文章和源代码:http://delphi.about.com/od/windowsshellapi/a/delphi-hooks.htm

如果这有你的兴趣,我很乐意深入研究。