Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to capture mousemove events beneath child controls

I am trying to handle a mouseclick event on a particular form that should fire if the mouse cursor falls between a set of coordinates - lets say a square.

I understand that if I had an empty form I could simply tie in to the mousemove event and off I go. But in reality there may be up to 10 different overlapping controls and in my test app the mousemove event only fires if the cursor is on the actual form itself and not if its over a child control.

Does anyone know how to handle this event when there are an unknown number of child controls at design time?

Is there an easy one-liner I can use?

like image 574
Grant Avatar asked Nov 12 '09 03:11

Grant


2 Answers

try this:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        AddMouseMoveHandler(this);
    }

    private void AddMouseMoveHandler(Control c)
    {
        c.MouseMove += MouseMoveHandler;
        if(c.Controls.Count>0)
        {
            foreach (Control ct in c.Controls)
                AddMouseMoveHandler(ct);
        }
    }

    private void MouseMoveHandler(object sender, MouseEventArgs e)
    {
        lblXY.Text = string.Format("X: {0}, Y:{1}", e.X, e.Y);
    }
}
like image 161
TheVillageIdiot Avatar answered Nov 06 '22 04:11

TheVillageIdiot


I know this post is quite old, but it seems to me that the simplest method would be for the form to implement IMessageFilter. In the constructor (or in OnHandleCreated) you call

Application.AddMessageFilter(this);

and then you can catch the messages of all windows in your implementation of IMessageFilter.PreFilterMessage.

You'd likely need to use P/Invoke for the WIN32 IsChild method

[DllImport("user32.dll")]
public static extern bool IsChild(IntPtr hWndParent, IntPtr hWnd);

along with the form's Handle property to ensure that you're handling the right messages.

like image 7
stritch000 Avatar answered Nov 06 '22 03:11

stritch000