如何让我的组件检测鼠标位置?

发布于 2024-11-27 15:29:34 字数 1149 浏览 0 评论 0原文

我想编写一个小组件来显示当前控制鼠标所在的位置。 当它发现所选控件时,它应该触发消息(例如)。

但我不知道该怎么做才能始终获得鼠标的位置。 这就是我所得到的:

  TMouseOverControl = class(TComponent)
  private
    fActive: Boolean;
    fControl: TWinControl;
  public
    constructor Create(AOwner: TComponent); override;
    procedure Loaded; override;
    procedure SpotIt;
  published
    property Active: Boolean read fActive write fActive;
    property Control: TWinControl read fControl write fControl; // when mouse is over this control show me the message
  end;

constructor TMouseOverControl.Create(AOwner: TComponent);
begin
  // nothing interesting here
  // don't have control property here - so overrided the loaded method
  inherited;
end;

procedure TMouseOverControl.Loaded;
begin
  inherited;

  //  TForm(Owner).Mo.... := SpotIt.... 
  //  what should i do to make it work?
 end;

 procedure TMouseOverControl.SpotIt;
 begin
// IsMouseOverControl is easy to implement
// http://delphi.about.com/od/delphitips2010/qt/is-some-delphi-tcontrol-under-the-mouse.htm
       if IsMouseOverControl(Control) then 
         ShowMessage('Yep, U got it!');
     end;

有什么想法吗?

I want to write a little component which shows me on which control mouse is currently over.
When it spot the choosen control it should fire the messaage (for example).

But I don't know what should I do to form to get the position of the mouse all the time.
This is what I've got:

  TMouseOverControl = class(TComponent)
  private
    fActive: Boolean;
    fControl: TWinControl;
  public
    constructor Create(AOwner: TComponent); override;
    procedure Loaded; override;
    procedure SpotIt;
  published
    property Active: Boolean read fActive write fActive;
    property Control: TWinControl read fControl write fControl; // when mouse is over this control show me the message
  end;

constructor TMouseOverControl.Create(AOwner: TComponent);
begin
  // nothing interesting here
  // don't have control property here - so overrided the loaded method
  inherited;
end;

procedure TMouseOverControl.Loaded;
begin
  inherited;

  //  TForm(Owner).Mo.... := SpotIt.... 
  //  what should i do to make it work?
 end;

 procedure TMouseOverControl.SpotIt;
 begin
// IsMouseOverControl is easy to implement
// http://delphi.about.com/od/delphitips2010/qt/is-some-delphi-tcontrol-under-the-mouse.htm
       if IsMouseOverControl(Control) then 
         ShowMessage('Yep, U got it!');
     end;

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

紙鸢 2024-12-04 15:29:34

那么你只需要在鼠标移动时检查/更新。因此,您可以使用 TApplicationEvents 跟踪 WM_MOUSEMOVE 消息。

// Edit: these variables are intended to be private fields of the component class
var
  FAppEvents: TApplicationEvents;
  FFoundControl: Boolean;
  FCurrentControl: TWinControl;

procedure TMyComponent.HandleAppMessage(var Msg: tagMSG; var Handled: Boolean);
var
  Control: TWinControl;
begin
  if (Msg.message = WM_MOUSEMOVE) and not FFoundControl then
  begin
    Control:= FindControl(Msg.hwnd);
    if Assigned(Control) then
    begin
      FCurrentControl:= Control;
      FFoundControl:= True;
    end;
  end else
  if (Msg.message = WM_MOUSELEAVE) then
    FFoundControl:= False;
end;

procedure TMyComponent.FormCreate(Sender: TObject);
begin
  FAppEvents:= TApplicationEvents.Create(nil);
  FAppEvents.OnMessage:= HandleAppMessage;
end;

这当然可以优化,例如还可以检查 WM_MOUSELEAVE,这样您就不必在每次鼠标移动时FindControl。此解决方案适用于 TWinControls 及其后代。

编辑:使用WM_MOUSELEAVE。

Well you only need to check/update when the mouse moves. So you could track WM_MOUSEMOVE messages by using TApplicationEvents.

// Edit: these variables are intended to be private fields of the component class
var
  FAppEvents: TApplicationEvents;
  FFoundControl: Boolean;
  FCurrentControl: TWinControl;

procedure TMyComponent.HandleAppMessage(var Msg: tagMSG; var Handled: Boolean);
var
  Control: TWinControl;
begin
  if (Msg.message = WM_MOUSEMOVE) and not FFoundControl then
  begin
    Control:= FindControl(Msg.hwnd);
    if Assigned(Control) then
    begin
      FCurrentControl:= Control;
      FFoundControl:= True;
    end;
  end else
  if (Msg.message = WM_MOUSELEAVE) then
    FFoundControl:= False;
end;

procedure TMyComponent.FormCreate(Sender: TObject);
begin
  FAppEvents:= TApplicationEvents.Create(nil);
  FAppEvents.OnMessage:= HandleAppMessage;
end;

This could certainly be optimized, e.g. by also checking for WM_MOUSELEAVE so you don't have to FindControl on every mouse move. This solution works for TWinControls and descendants.

Edit: Made use of WM_MOUSELEAVE.

╰つ倒转 2024-12-04 15:29:34

像这样的事情怎么样:

// rectangle where you are interested to check if the mouse is into..
targetRect := Rect(0, 0, ImageZoom.Width, ImageZoom.Height);

// find out where the mouse is..
mousePosition := Point(0, 0);
GetCursorPos(mousePosition);

// find out if the point.. from screen to client.. is inside that rectangle
isMouseInside := (PtInRect(targetRect, ScreenToClient(mousePosition)));

How about something like this:

// rectangle where you are interested to check if the mouse is into..
targetRect := Rect(0, 0, ImageZoom.Width, ImageZoom.Height);

// find out where the mouse is..
mousePosition := Point(0, 0);
GetCursorPos(mousePosition);

// find out if the point.. from screen to client.. is inside that rectangle
isMouseInside := (PtInRect(targetRect, ScreenToClient(mousePosition)));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文