How to detect if the mouse is inside the whole form and child controls?

c#, detection, mouseevent, winforms

Solution

You can hook the main message loop and preprocess/postprocess any (WM_MOUSEMOVE) message what you want.

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

Problem

I need to detect when the user moves the mouse over the Form and all its child controls and also when it leaves the Form. I tried the `MouseEnter` and `MouseLeave` events of the Form, I tried the `WM_MOUSEMOVE` & `WM_MOUSELEAVE` and `WM_NCMOUSEMOVE` & `WM_NCMOUSELEAVE` pairs of windows messages but none seem to work as I want... Most of my Form is occupied by child controls of many sorts, there's not much client area visible. This means that if I move the mouse very quickly the mouse movement will not be detected, although the mouse is inside the Form. For instance, I have a TextBox that is docked at the bottom and between the desktop and the TextBox, there's only a very small border. If I quickly move the mouse from the bottom into the TextBox, the mouse movement won't be detected, but the mouse is inside the TextBox, therefore, inside the Form. How can I achieve what I need?

Original source