Capturing mouse events from every component

Gustavo Cardoso picture Gustavo Cardoso · Apr 29, 2009 · Viewed 31.5k times · Source

I have a problem with MouseEvents on my WinForm C# application.

I want to get all mouse clicks on my application, but I don't want to put a listener in every child component neither use Windows mouse hook.

On Flash I could put a listener on Stage to get all the MouseEvents on the movie.

Is there such thing on C#? A global MouseListener?


Edit:

I create this class from IMessageFilter ans used Application.AddMessageFilter.

public class GlobalMouseHandler : IMessageFilter{

    private const int WM_LBUTTONDOWN = 0x201;

    public bool PreFilterMessage(ref Message m){
        if (m.Msg == WM_LBUTTONDOWN) {
            // Do stuffs
        }
        return false;
    }
}

And put this code on the Controls that need listen global clicks:

GlobalMouseHandler globalClick = new GlobalMouseHandler();
Application.AddMessageFilter(globalClick);

Answer

Tim Robinson picture Tim Robinson · Apr 29, 2009

One straightforward way to do this is to add a message loop filter by calling Application.AddMessageFilter and writing a class that implements the IMessageFilter interface.

Via IMessageFilter.PreFilterMessage, your class gets to see any inputs messages that pass through your application's message loop. PreFilterMessage also gets to decide whether to pass these messages on to the specific control to which they're destined.

One piece of complexity that this approach introduces is having to deal with Windows messages, via the Message struct passed to your PreFilterMessage method. This means referring to the Win32 documention on WM\_LBUTTONDOWN, WM\_MOUSEMOVE, WM\_LBUTTONUP etc, instead of the conventional MouseDown, MouseMove and MouseUp events.