如何检测鼠标是否在整个表单和子控件内?

我需要检测用户何时将鼠标移动到Form及其所有子控件上以及何时离开Form。 我尝试了Form的MouseEnterMouseLeave事件,我尝试了WM_MOUSEMOVEWM_MOUSELEAVEWM_NCMOUSEMOVEWM_NCMOUSELEAVE对的Windows消息,但似乎没有任何工作,因为我想…

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

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

我怎样才能实现我的需要?

您可以挂钩主消息循环并预处理/后处理您想要的任何(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 ); } 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:{0}, Y:{1}", Control.MousePosition.X, Control.MousePosition.Y ); } return false; } } } 

怎么样:在你的表单的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); } } 

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

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

在托管UserControl的WinFrom上,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是usercontrol的类型

快速又脏的解决方案:

 private bool MouseInControl(Control ctrl) { return ctrl.Bounds.Contains(ctrl.PointToClient(MousePosition)); }