如何确定鼠标光标是否在控件内 [英] How to determine if the mouse cursor is inside a control
问题描述
我要在TScrollBox中添加对鼠标滚轮移动的支持(使用FormMouseWheel过程),并且需要确定鼠标是否在组件内部。
I'm adding support for mouse wheel movement to a TScrollBox (using the FormMouseWheel procedure) and I need to determine if the mouse is inside the component.
我需要确定鼠标是否在TScrollBox中,以便随后相应地处理滚动代码。
Basically I need to determine if the mouse is inside the TScrollBox so that I then handle the scrolling code accordingly.
任何有关如何执行此操作的想法?
Any idea on how to do this?
编辑:这是代码(包括此问题的答案),因为它可能会帮助其他人:
Here's the code (including the answer to this question) as it might help others:
procedure TForm1.FormMouseWheel(Sender: TObject;
Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint;
var Handled: Boolean);
var
Msg: Cardinal;
Code: Cardinal;
I, ScrollLines: Integer;
ScrollBoxCursosPos: TPoint;
begin
//position of the mouse cursor related to TScrollBox
ScrollBoxCursosPos := ScrollBox1.ScreenToClient(Mouse.CursorPos);
if (PtInRect(ScrollBox1.ClientRect, ScrollBoxCursosPos)) then
begin
Handled := True;
If ssShift In Shift Then
msg := WM_HSCROLL
Else
msg := WM_VSCROLL;
If WheelDelta < 0 Then
code := SB_LINEDOWN
Else
code := SB_LINEUP;
ScrollLines:= Mouse.WheelScrollLines * 3;
for I:= 1 to ScrollLines do
ScrollBox1.Perform(Msg, Code, 0);
ScrollBox1.Perform(Msg, SB_ENDSCROLL, 0);
end;
end;
推荐答案
Mouse.CursorPos
返回屏幕坐标中的鼠标位置。您可以通过调用控件的 ScreenToClient
方法。
因此,您将获得如下代码:
So you'll have code something like this:
var
MyPoint : TPoint;
begin
MyPoint := ScrollBox1.ScreenToClient(Mouse.CursorPos);
if PtInRect(ScrollBox1.ClientRect, MyPoint) then
begin
// Mouse is inside the control, do something here
end;
end;
这会让您知道它是否在控件内。
That will let you know if it's inside the control.
从外观上看,您是使用鼠标滚轮实现滚动吗?如果是这样,别忘了致电 SystemParametersInfo
和 SPI_GETWHEELSCROLLLINES
,或者,如果在您的Delphi版本中,则为 Mouse.WheelScrollLines
来找出每个鼠标滚轮滚动多少行增量。这对您的应用程序意味着什么,可能取决于您在滚动框中获得的内容。
From the look of it you're implementing scrolling with the mousewheel? If so don't forget to call SystemParametersInfo
with SPI_GETWHEELSCROLLLINES
or possibly, if it's in your version of Delp Mouse.WheelScrollLines
to find out how many lines to scroll per mousewheel increment. What that means to your app probably depends on what you've got in the scrollbox.
如果您还打算实现鼠标中键并拖动滚动(我在这里推测,这已经超出了您的要求),例如,在鼠标离开控件或窗体直到用户放开按钮之前,您可能希望获取鼠标事件。如果是这样,请查看 SetCapture
和 ReleaseCapture
和本文。 (该文章使用这些代码来查看鼠标是否位于控件(窗体)上,尽管我认为我上面编写的代码对于该特定问题是更好的解决方案-一点是,即使在鼠标不在您的窗体或控件上。)
If you're planning to also implement middle-click-and-drag scrolling (I'm speculating here, this is well past what you asked about) you might want to get mouse events after the mouse has left the control or form until the user lets go the button, for example. If so, have a look at SetCapture
and ReleaseCapture
and this article. (That article uses those to see if the mouse is over a control (there, a form) although I think the code I wrote above is a better solution to that specific problem - point is they're handy for getting mouse information even when the mouse is not over your form or control.)
(编辑:我刚刚注意到Delphi 2010的 TMouse
具有属性封装了这些API调用的 WheelScrollLines
和 捕获
。我不确定它们是最近添加的-我以前可能没有注意到它们-但是假设它们是新的,并且因为您不说您是什么版本的Delphi我将保留上面的文本和WinAPI参考。如果您使用的是最新版本,请查看 TMouse
文档。)
( I just noticed that Delphi 2010's TMouse
has properties that wrap these API calls, WheelScrollLines
and Capture
. I'm not sure how recently they were added - I might just not have noticed them before - but on the assumption they're new-ish and because you don't say what version of Delphi you're using I'm leaving the above text and WinAPI references. If you're using a recent version have a look at the TMouse
documentation.)
这篇关于如何确定鼠标光标是否在控件内的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!