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 eve
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.
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
}
Take a look at this article. It recursively hoooks all the control events and broadcasts them. You could also override WndProc in your form.
If you don't want to handle the messages by overriding Form.PreProcessMessage or Form.WndProc then you could subclass Form to hook an event handler to all the MouseClick events from the various controls on the form.
EDIT: forgot to recurse through child controls of controls on the form.
public class MousePreviewForm : Form
{
protected override void OnClosed(EventArgs e)
{
UnhookControl(this as Control);
base.OnClosed(e);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
HookControl(this as Control);
}
private void HookControl(Control controlToHook)
{
controlToHook.MouseClick += AllControlsMouseClick;
foreach (Control ctl in controlToHook.Controls)
{
HookControl(ctl);
}
}
private void UnhookControl(Control controlToUnhook)
{
controlToUnhook.MouseClick -= AllControlsMouseClick;
foreach (Control ctl in controlToUnhook.Controls)
{
UnhookControl(ctl);
}
}
void AllControlsMouseClick(object sender, MouseEventArgs e)
{
//do clever stuff here...
throw new NotImplementedException();
}
}
Your forms would then need to derive from MousePreviewForm not System.Windows.Forms.Form.