I have an application wich open a modal form with the ShowDialog method.
Once this form is displayed I want to capture the mouse movement even if the cursor is outside the form.
How can I capture the mouse movement? I saw something with the Capture property but I cannot manage to make it work.
[edit]
I want to be notified if the mouse move outside the form.
The Capture property is the correct way, but there are some limitations.
Only the foreground window can capture the mouse
Mouse capturing can be disabled by other parts of the system
The Win32 API function SetCapture gets reset everytime a "mouse up" event occours. I assume that also applies for .NET.
See the remarks section of Capture property.
When the mouse is captured, you'll receive the usual events but with a wider mouse coordinate range (for example a negative X position, if the mouse is left of the capturing control)
Mouse capturing is fragile, because of it's global nature. Check if there are other ways to handle certain events. Perhaps the MouseLeave or MouseEnter events are enough in your case.
You can just use the static property Control.MousePosition.
You can read the position of the cursor, using the Cursor.Position property, see Cursor.Position
Related
On System.Windows.UIElement there is a CaptureMouse() and a paired ReleaseMouseCapture() method. In this WPF DragDrop sample they call CaptureMouse on MouseDown and release it on MouseUp. The documentation in MSDN is about as useless as it comes - "CaptureMouse -> Captures the mouse."
In my head before trying it I assumed that it somehow locked the mouse inside the UIElement bounds, but that's clearly not the case when I try it. From experimenting, it seems to have something to do with responding to events when the mouse is outside of the UIElement, but not wanting to be a cargo cult programmer I don't want to just use it because the example does, I'd like an authoritative description of what it means.
From Capture and Uncapture the Mouse on MSDN:
When an object captures the mouse, all mouse related events are treated as if the object with mouse capture perform the event, even if the mouse pointer is over another object.
Only the capturing control receives the mouse events until released.
Capturing the mouse is useful for dragging because all the dragging code can exist in the one control, rather than being spread over multiple controls.
When it has captured the mouse, a control will receive mouse events even if the mouse pointer is no longer within its bounding area.
Typically, it's used for:
Drag and drop
Buttons (to handle Mouse Up when you put the mouse down on the button and move the mouse before you release the button)
The Silverlight 2 documentation for it has a more verbose description, I don't know why it isn't a part of the 3.5 documentation page too:
When an object has captured the mouse, that object receives mouse input whether or not the mouse pointer is within its bounding area. The mouse is typically only captured during simulated drag operations.
...
It works the same with WPF, and so the reason it is used with DragDrop, is that is how the
it knows to report back to the control being dragged from when the mouse may be outside of that control. If you comment out the MyCanvas.Capture() and the Capture(Null) (which clears it) then you can no longer drop.
I have a small video app that i would like to give vlc-like functionality. By that, I mean having a certain element disappear and appear on mouse move or mouse not moving. I have a rough concept of how to do this but I have no ideea how i coul detect if the mouse is moving or not. I thought about using the GetPosition function but that will just give me the mouse's position and won't let me know if the cursor is moving or not. I would like to use a timer to count down 2-3 seconds after the mouse has stopped moving and then either fade out the control or just make it collapse without further ado. I can't check the value of the position variable every milisecond. Is there some other way to do this ?
You can use a hook functionality so you will be notified when a mouse move, I use to use this free opensource library.
How to use it:
using Gma.UserActivityMonitor.GlobalEventProvider;
GlobalEventProvider _globalEventProvider1
= new Gma.UserActivityMonitor.GlobalEventProvider();
this.globalEventProvider1.MouseMove += HookMouseMove;//to listen to mouse move
Capture the mouse. Release the capture if the user actually clicks anywhere else. Then you can use the standard WPF mouse move event.
myElement.MouseMove += (my MouseMove handler)
Mouse.Capture(myElement);
Hallo,
I am trying to keep track of the mouse position and also its delta position. Is there any nicer way of doing this then implementing all the mouse events for all my forms in my window?
The problem with using the MouseMove event is that as soon as the mouse moves outside of the form it stops working properly. Implementing the mouseEnter, mouseLeave improves it somewhat, but it does still not feel perfect. Any ideas?
Regards,
You have to handle lower level windows events.
Check out this example: http://www.codeproject.com/KB/cs/globalhook.aspx
I have a large user drawn control that fills most of the screen area in an application.
I would like to simulate some "onMouseHover" behaviour, I cant really use the userControl event as the mouse is almost always on that control so it fires all of the time.
How can I detect the mouse "hovering" over part of my user drawn control?
(If it helps an image of the app can be found at : http://www.benbun.co.uk/st3/ayv the control is the large "year calendar")
You could handle MouseMove events instead of MouseHover. Then you could calculate based on the X,Y location of the mouse whether or not the cursor is in the part of your control you are interested in creating "hover" behavior for.
I have a custom Canvas control (inherited from Canvas) overlaid over a large area of User Controls. The idea is to draw paths between user controls (i.e. connector lines).
To capture mouse movement, I call Mouse.Capture(theCanvas) on MouseDown. This works beautifully, but the user controls under the canvas obviously no longer receive mouse events. Mouse.DirectlyOver always shows the canvas, so I can't really fake it by peeking at the current position and seeing which user control it's over.
So, I still need the Canvas for drawing paths, but how can I solve this one of the following ways:
Peek under the Canvas and see what the topmost control is right under it?
Get this MouseDown -> Track MouseMoves -> MouseUp workflow to work on the canvas without mouse captures?
Any other ideas welcome...
I'd agree that those are your two options. If you want to only forward some clicks to your usercontrols, then go with option 1, and hit test the controls under the canvas.
If you need your usercontrols to behave as though there is nothing covering them (textboxes, buttons etc), then i'd recommend using the PreviewMouseMove event on the user control's parent, as this can pick up and optionally "handle" events before the controls get at the event, but it won't block the event if you don't set handled to true