2009-06-12 59 views
7

我需要检测何时用户将鼠标移动到窗体及其所有子控件上以及它何时离开窗体。我试过形式的MouseEnterMouseLeave事件,我尝试了WM_MOUSEMOVE & WM_MOUSELEAVEWM_NCMOUSEMOVE 双Windows消息,但没有似乎工作,因为我想...如何检测鼠标是否在整个窗体和子控件中?

我大部分的表格是由子控件占据很多种类,没有太多的客户区可见。这意味着如果我非常快地移动鼠标,鼠标移动将不会被检测到,尽管鼠标在表格内。例如,我有一个TextBox停靠在底部,桌面和TextBox之间,只有一个非常小的边框。如果我将鼠标从底部快速移动到文本框中,将无法检测到鼠标移动,但鼠标位于文本框内,因此位于表格内。

我该如何实现我所需要的?

回答

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); 
    } 

    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; 
     } 

    } 
} 
+0

这不仅使得它的工作另一种方式......我的意思是,现在它检测到当鼠标移动到窗体的孩子控制,但没有形式本身。我想检测整个事情。我还需要检测鼠标何时进入窗体,何时离开,而不仅仅是它在内部移动。 – 2009-06-12 13:27:25

+0

嗯,我在这个例子中发现了我正在寻找的东西:http://netcode.ru/dotnet/?lang=&katID=30&skatID=283&artID=7862。它使用与您的答案IMessageFilter相同的原则。它允许我检测鼠标何时进入和离开表单。我只需将代码调整到我想要的状态。无论如何,如果你能在IMessageFilter上详细说明你的答案,它是什么,它是如何工作的以及所有这些,我将把这个答案标记为已接受的答案。并且请添加注释以查看其他人寻找解决完全相同问题的注释。 – 2009-06-12 14:19:51

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); 
    } 
} 
0

在用户控件创建一个MouseHover事件为控制这个样子,(或其他事件类型)这样

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

在您WinFrom它承载的用户控件有这样的用户控件来处理在Designer.cs

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

鼠标悬停在你的WinForm调用该方法

private void ThumbnailMouseHover(object sender, EventArgs e) 
{ 

    ThumbImage thumb = (ThumbImage) sender; 

} 

哪里ThumbImage是用户控件的类型

0

快速和肮脏的解决方案:

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