Winforms: first intercept the mouse event on the main form, not on the controls

Of course, there is a convenient way to do this:

I applied "Window Movement" when moving the mouse on my main form, and I would like the MouseClick / Move event to be intercepted by the form, and not by the controls that are in it.

I would like to find an equivalent / copy KeyPreview property for mouse events

In addition, I want to avoid redirecting the mouse event to the main form method 12 times in 12 mouse control events individually (which is the ugly workaround I have found so far)

Any ideas?

+7
source share
5 answers

Subscribe to all MouseMove event controls (note that they are recursive for nested controls)

foreach (Control control in Controls) control.MouseMove += RedirectMouseMove; 

And raise MouseMove inside this event handler

 private void RedirectMouseMove(object sender, MouseEventArgs e) { Control control = (Control)sender; Point screenPoint = control.PointToScreen(new Point(eX, eY)); Point formPoint = PointToClient(screenPoint); MouseEventArgs args = new MouseEventArgs(e.Button, e.Clicks, formPoint.X, formPoint.Y, e.Delta); OnMouseMove(args); } 

Keep in mind that controls receive MouseEvents with local control coordinates. Therefore, you need to convert it to a coordinate form. There may be flaws with the nested controls, but I leave them to you (e.g. calling Parent.PointToClient)

UPDATE: you can still handle management events - just subscribe to the event again.

+4
source

You can use the global Mouse Hook to intercept mouse events, there is a sample on MSDN

+2
source

Based on your comments,

Implement the Mouse event forwarding function in the base class, and then make all the controls from this base class.

Thus, you only implement this functionality once, and then all your controls will "reconstruct" the mouse event, which will be detected by the main form.

Hope this helps.

+1
source

Override the Control.PreProcessMessage method:

http://msdn.microsoft.com/en-us/library/system.windows.forms.control.preprocessmessage.aspx

Edit:

It seems PreProcessMessage might not work for mouse events. Instead, try overriding WndPrc. It can accurately intercept mouse messages, but you need to make sure that it intercepts them in the order you want:

http://bytes.com/topic/c-sharp/answers/752144-preprocessmessage

+1
source

You can use the GlobalMouseKeyHook library to easily intercept the system with the width of the mouse .

When you click, you should check to see if the mouse point intersects with your form, or if your windows under the mouse are your form.

To execute the last WindowFromPoint API function:

  [DllImport( "user32.dll", SetLastError = true )] public static extern IntPtr WindowFromPoint( [In] POINTAPI Point ); private void _mouseListener_MouseClick( object sender, MouseEventArgs e ) { var localPoint = this.PointToClient( e.Location ); bool containsPoint = this.ClientRectangle.Contains( localPoint ); var windowHandle = WindowFromPoint( e.Location ); var ctl = (Form)Form.FromHandle( windowHandle ); bool mainFormClicked = ctl != null && ctl.Handle == this.Handle; if( containsPoint && mainFormClicked ) { //form click is intercepted! } } 

I actually use this when I want to capture a click outside my form (there is no other way). In your case, I would snap to each MouseClick control for performance (the global hook is heavy).

0
source

All Articles