2009-06-12 28 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)); 
} 
相關問題