2012-03-08 90 views
2

我需要一種檢測光標何時進入或離開窗體的方法。當控件填充表單時,Form.MouseEnter/MouseLeave不起作用,因此我還必須訂閱控件的MouseEnter事件(例如表單上的面板)。任何其他跟蹤形式光標進入/退出全球?WinForms:光標進入/離開窗體或其控件時檢測

+2

你會發現你的[答案](http://stackoverflow.com/questions/986529/how-to-detect-if-the-mouse-is-inside-the-whole-form-and-child-controls -in-c) – David 2012-03-08 13:53:29

+0

另一種方法是切換到WPF來解決路由事件的這個特定問題。 – 2012-03-08 13:58:04

+0

簡單的200毫秒Timer,Mouse.Position和窗體的PointToClient()方法通常是一種有效的方法。 IMessageFilter也可以。 – 2012-03-08 14:29:02

回答

1

你可以用win32的做到像這樣的回答: How to detect if the mouse is inside the whole form and child controls in C#?

或者你可以只鉤出來頂層控件形式的OnLoad:

 foreach (Control control in this.Controls) 
      control.MouseEnter += new EventHandler(form_MouseEnter); 
+1

關於你的第二種選擇:你還必須擔心有兒童控制的兒童控制(他們也有兒童控制,他們也有......)。我不會推薦實施。 – ean5533 2012-03-08 14:26:28

4

你可以試試這個:

private void Form3_Load(object sender, EventArgs e) 
{ 
    MouseDetector m = new MouseDetector(); 
    m.MouseMove += new MouseDetector.MouseMoveDLG(m_MouseMove); 
} 

void m_MouseMove(object sender, Point p) 
{ 
    Point pt = this.PointToClient(p); 
    this.Text = (this.ClientSize.Width >= pt.X && 
       this.ClientSize.Height >= pt.Y && 
       pt.X > 0 && pt.Y > 0)?"In":"Out";  
} 

的MouseDetector類:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Runtime.InteropServices; 
using System.Windows.Forms; 
using System.Drawing; 

class MouseDetector 
{ 
    #region APIs 

    [DllImport("gdi32")] 
    public static extern uint GetPixel(IntPtr hDC, int XPos, int YPos); 

    [DllImport("user32.dll", CharSet = CharSet.Auto)] 
    public static extern bool GetCursorPos(out POINT pt); 

    [DllImport("User32.dll", CharSet = CharSet.Auto)] 
    public static extern IntPtr GetWindowDC(IntPtr hWnd); 

    #endregion 

    Timer tm = new Timer() {Interval = 10}; 
    public delegate void MouseMoveDLG(object sender, Point p); 
    public event MouseMoveDLG MouseMove; 
    public MouseDetector() 
    {     
    tm.Tick += new EventHandler(tm_Tick); tm.Start(); 
    } 

    void tm_Tick(object sender, EventArgs e) 
    { 
    POINT p; 
    GetCursorPos(out p); 
    if (MouseMove != null) MouseMove(this, new Point(p.X,p.Y)); 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct POINT 
    { 
    public int X; 
    public int Y; 
    public POINT(int x, int y) 
    { 
     X = x; 
     Y = y; 
    } 
    } 
}