Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capturing mouse events from every component

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); 
like image 358
Gustavo Cardoso Avatar asked Apr 29 '09 21:04

Gustavo Cardoso


People also ask

Do all components generate the MouseEvent?

'Yes' all components generate mouse event in java.

How do you handle mouse events?

If you depress the mouse button on an element and move your mouse off the element, and then release the mouse button. The only mousedown event fires on the element. Likewise, if you depress the mouse button, move the mouse over the element, and release the mouse button, the only mouseup event fires on the element.


2 Answers

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.

like image 74
Tim Robinson Avatar answered Sep 21 '22 15:09

Tim Robinson


Sample Class

class CaptureEvents : IMessageFilter {     #region IMessageFilter Members     public delegate void Callback(int message);     public event Callback MessageReceived;      IntPtr ownerWindow;     Hashtable interestedMessages = null;     CaptureEvents(IntPtr handle, int[] messages)     {         ownerWindow = handle;         for(int c = 0; c < messages.Length ; c++)         {             interestedMessages[messages[c]] = 0;         }     }     public bool PreFilterMessage(ref Message m)     {         if (m.HWnd == ownerWindow && interestedMessages.ContainsKey(m.Msg))         {             MessageReceived(m.Msg);         }         return true;     }      #endregion } 
like image 26
Renjith V Avatar answered Sep 19 '22 15:09

Renjith V