8

我需要检测用户何时将鼠标移到表单及其所有子控件上,以及何时离开表单。我尝试了表单的MouseEnterMouseLeave事件,我尝试了WM_MOUSEMOVE&WM_MOUSELEAVEWM_NCMOUSEMOVE&WM_NCMOUSELEAVE对 Windows 消息,但似乎没有一个按我想要的那样工作......

我的大部分表单都被各种子控件占据,没有太多可见的客户区。这意味着如果我非常快速地移动鼠标,则不会检测到鼠标移动,尽管鼠标在窗体内。

例如,我有一个文本框,它停靠在底部,位于桌面和文本框之间,只有一个非常小的边框。如果我将鼠标从底部快速移动到 TextBox 中,则不会检测到鼠标移动,但鼠标在 TextBox 内部,因此在 Form 内部。

我怎样才能达到我所需要的?

4

4 回答 4

13

您可以挂钩主消息循环并预处理/后处理您想要的任何(WM_MOUSEMOVE)消息。

public class Form1 : Form {
    private MouseMoveMessageFilter mouseMessageFilter;
    protected override void OnLoad(EventArgs e) {
        base.OnLoad( e );

        this.mouseMessageFilter = new MouseMoveMessageFilter();
        this.mouseMessageFilter.TargetForm = this;
        Application.AddMessageFilter(this.mouseMessageFilter);
    }

    protected override void OnClosed(EventArgs e) {
        base.OnClosed(e);
        Application.RemoveMessageFilter(this.mouseMessageFilter);
    }

    private class MouseMoveMessageFilter : IMessageFilter {
        public Form TargetForm { get; set; }

        public bool PreFilterMessage( ref Message m ) {
            int numMsg = m.Msg;
            if ( numMsg == 0x0200 /*WM_MOUSEMOVE*/)
                this.TargetForm.Text = string.Format($"X:{Control.MousePosition.X}, Y:{Control.MousePosition.Y}");

            return false;
        }
    }
}
于 2009-06-12T13:12:59.657 回答
2

怎么样:在表单的 OnLoad 中,递归遍历所有子控件(及其子控件)并连接 MouseEnter 事件。

然后每当鼠标进入任何后代时,都会调用事件处理程序。同样,您可以连接 MouseMove 和/或 MouseLeave 事件。

protected override void OnLoad()
{
   HookupMouseEnterEvents(this);
}

private void HookupMouseEnterEvents(Control control)
{
   foreach (Control childControl in control.Controls)
   {
      childControl.MouseEnter += new MouseEventHandler(mouseEnter);

      // Recurse on this child to get all of its descendents.
      HookupMouseEnterEvents(childControl);
   }
}
于 2009-06-12T14:13:17.767 回答
1

快速而肮脏的解决方案:

private bool MouseInControl(Control ctrl)
{
    return ctrl.Bounds.Contains(ctrl.PointToClient(MousePosition));
}
于 2015-07-01T09:13:05.037 回答
0

在您的用户控件上为您的控件创建一个鼠标悬停事件,像这样(或其他事件类型)像这样

private void picBoxThumb_MouseHover(object sender, EventArgs e)
{
    // Call Parent OnMouseHover Event
    OnMouseHover(EventArgs.Empty);
}

在您的 WinFrom 主机上,UserControl 有这个供 UserControl 处理 Designer.cs 中的 MouseOver

this.thumbImage1.MouseHover += new System.EventHandler(this.ThumbnailMouseHover);

在您的 WinForm 上调用此方法

private void ThumbnailMouseHover(object sender, EventArgs e)
{

    ThumbImage thumb = (ThumbImage) sender;

}

其中 ThumbImage 是用户控件的类型

于 2011-04-08T19:23:19.487 回答