如何确定鼠标光标是否在控件内 [英] How to determine if the mouse cursor is inside a control

查看:265
本文介绍了如何确定鼠标光标是否在控件内的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆