WPF,
MSDN:
UIElement.PreviewMouseMove Event
Occurs when the mouse pointer moves
while the mouse pointer is over this
element.
As I can see, this is not true... When I PreviewMouseDown, then PreviewMouseUp, an PreviewMouseMove event interferes. Is this a bug in Framework or MSDN documentation leak?
I just need to differentiate when a element really moves, and this "static" "Move" breaks my logic...
Function calls log:
Function: MyCanvas.OnPreviewMouseLeftButtonDown(System.Windows.Input.MouseButtonEventArgs), Thread: 0x6F4 Main Thread
Function: MyCanvas.OnPreviewMouseMove(System.Windows.Input.MouseEventArgs), Thread: 0x6F4 Main Thread
Function: MyCanvas.OnPreviewMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs), Thread: 0x6F4 Main Thread
Function: MyCanvas.OnPreviewMouseMove(System.Windows.Input.MouseEventArgs), Thread: 0x6F4 Main Thread
The previous log was obtained when obtaining also the DoubleClick event, so, I don't suppose I moved the mouse even by a micrometer...
Using simple handlers I was able to get PreviewMouseUp and PreviewMouseDown (and LeftButtonUp/Down) events to fire reliably without MouseMove interfering. I suspect that the behavior you're seeing is because, especially with modern high resolution mice, it's impossible to not move the mouse (even very slightly) while clicking it. Actually, it would be very foolish to assume your users won't do that. There's nothing preventing the user moving the mouse while keeping the mouse button pressed.
If you want to register the event sequence only if the mouse is stationary, record the position on mouse down and only do your actions on mouse up if the position changed significantly.
Related
TL;DR:
I need to use both sendmessage and sendinput in order to get into an old function/event in a program that I can't re-build. While in there, I can't release the virtual mouse click using any of the methods I used to get in there in the first place - they're ignored.
Any other way to trigger the mousedown event - one where I could also release the mouse click might work.
I am writing a program that has to interact with a black-boxed old piece of software written in VB6 long long ago.
My program has to be able to send mouse clicks, specifically mousedown and mouseup events to the old program.
Here's the tricky part...
The mousedown event in the old program uses:
While GetAsyncKeyState(1)
Wend
to wait for the user to release the mouse.
Currently, in order to get the event to trigger, I need to use:
SendMessage(control_handle, WM_LBUTTONDOWN, 0, 0);
Input.type = INPUT_MOUSE;
Input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
SendInput(1,&Input,sizeof(INPUT));
This does trigger the event (using just sendmessage does NOT trigger a necessary branch inside the event because that branch is entered with a GetAsyncKeyState(1) test as well), but issuing any combination of the following does NOT release the mouse click:
SendMessage(control_handle, WM_LBUTTONUP, 0, 0)
Input.type = INPUT_MOUSE;
Input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(1,&Input,sizeof(INPUT));
The code just keeps repeating in the while/wend part, it never gets out. The release code is being sent, but GetAsyncKeyState(1) isn't recognizing it as a mouse release. SUPER weird that GetAsyncKeyState(1) recognizes the function as a mouse down event, but GetAsyncKeyState(1) won't recognize as a mouse up.
What I've tested:
Clicking the real mouse elsewhere on the screen does release the
function.
Removing the sendmessage call, and using just the sendinput function
(and manually positioning the mouse over the object that needs
clicking) DOES work to release the loop.
I can't rely on the user not messing with the mouse while this is
doing its thing, so I'm hesitant to have the code virtually move the
mouse over the button to be clicked.
I've tried the deprecated mouse_event function as well, same exact
behavior.
Timing is critical. There can't be substantial delays between the trigger is issued and when it happens. Think keyboard-response speed.
I wrote a very simple VB6 program to simulate the while/GetAsyncKeyState(1)/wend loop to test this out on, and the behavior is the same - so I can be confident there isn't something weird in the old program that is causing this to happen.
Thank you very much for reading and helping!
In case this ever comes up for anyone else ever.... Using postmessage instead of sendmessage allows the program to continue on. Makes sense, really..
As I am trying to make my own custom "WinForms", I am left confused on when does each mouse event occurs. I have made my own custom classes, but now the events are something I have to rework, as they won't work right.
I have a custom class for controls. Objects from that class can contain other controls, which can contain other controls and so on. There is a main control, which gets input from a picture box. That input is what is where the mouse is and what even has been activated in the picture box.
So far I have figured, that MouseMove, MouseHover and MouseDown events are the simplest to write, as they occur in simple conditions. But the rest require additional data about the mouse's location, state and past. MouseDoubleClick seems to activate after a specific sequence of events (strictly down-up-down-up, down-up-down-move-up and down-up-down-move-leave-enter-move-up, with the movement events not activating). With that in mind, I am even more confused.
In what conditions and sequences does each mouse event occur?
EDIT
Further testing made things even more confusing. For one, now I want to know at what rate is the MouseMove being registered, and testing it shows that between each event there is a different time (or so does my use of a StopWatch say). This is important, because then that raises the question when is Hover being triggered.
Click is down-up, where moving is allowed between the two.
DoubleClick proved to be simple enough - down-up-down-up, where moving is allowed explicitly only between the second down-up.
Hover activates only once after each Enter, when the mouse remains stationary; if you want to trigger Hover again, the mouse has to leave and then re-enter.
So the question now is how the system tracks the mouse's activity - how does it detect the mouse moving, being held down and being released. Hopefully that would help me get the full answer.
How can I detect when the mouse cursor leaves a GtkTreeView row associated with a GtkListStore model?
Note that the signal "cursor-changed" is not what I am looking for, as it gets emitted as if it is a mouse enter (mouseover) event and I need it to be triggered when the mouse has just left the row instead. However within "cursor-changed" signal and a call of gtk_tree_view_get_cursor() I can obtain "the latest mouseovered row" to know which row the mouse cursor has previously entered. So I at least need a way to detect when the mouse cursor leaves some row.
Mouseout events normally require widgets to consume a window on the underlying implementation (the Xserver normally sends them when you abandon one window, Windows has another means of signalling them) so in environments where widgets don't use a window (this is quite normal on environments that don't have enough support from the implementation), they must be simulated. Normally you'll have to check the widget class hierarchy up to the root to see the place where those such events are being emulated, and how, to get an idea on how to deal with them. Probably you'll have some registering process in the superclasses to allow for a callback to be called on behalf of such events.
Question: Should we check at runtime for a touch device (using Modernizr.touch?) and then use the angular swipe service when it is a touch device and use mouse events when it isn't?
Objective: I am writing a Slider Directive and I want to move the slider button.
I want to handle mousedown, mousemove, and mouseup events on the desktop and I want similar behavior on a touch screen. I had this working well with mouse events on the desktop but I've modified the code to use angular's $swipe service instead. Now the touch screen functionality works well, but the mouseup event on the desktop browsers is lost if it occurs outside of the target element.
Here is a jsBin that demonstrates the $swipe utility:
http://jsbin.com/berome/1/edit?html,js,console,output
On a touch screen device, the demo functions correctly. The start event, move events, and end event fire respectively when dragging the finger across the target element.
On the desktop, the start and move events fire, but the end event will only fire if the mousedown is released whilst still within the target div. This is expected behavior because the mouseup is bound to the target element. However, if the cursor is taken outside of the div during a mousemove event and then the mouse button is released, no end event occurs. Moreover the mousemove event will continue to fire when the cursor returns within the target! (Try it on the demo. It gets stuck in the mousemove state until another mousedown-mouseup sequence within the target)
For the desktop implementation, mousedown would be bound to the target element, and mousemove and mouseup would be bound to the $window (or some parent element) from within the mousedown event. The mouseup would then always fire even when the mouse down is released - even if the cursor is outside the target element! The mousemove and mouseup would be unbound in the mouseup event.
There doesn't seem to be much documentation or examples for using $swipe yet. The ngBook has a paragraph or two but no working example. Any suggestions or comments? I'm leaning towards two implementations: one for touch and one for the desktop.
Thanks!
You are correct, there is very little documentation for ngTouch's $swipe. Just starting digging into this I am having a hard time finding anything. So thank you for your example.
The only solution to your problem that I can see from my limited understanding is that you treat it like a scroll on a touch device and cancel. These sentences are from the documentation:
If the vertical distance is greater, this is a scroll, and we let the
browser take over. A cancel event is sent.
cancel is called either on a touchcancel from the browser, or when we
begin scrolling as described above.
I haven't tried any of this, but I this thought occurred to me and I thought it might be useful to you and me (as I'm sure I will have to deal with it soon).
Is there a way in WPF to get active touch points? I need to determine if user is touching screen, similar to Mouse classes' Pressed -property?
I just need to know if any touch is present on the screen - don't mind what UIElement it's touching.
Here are two options, but they may not be the most correct way to do it:
1) You could subscribe to the MainWindow.PreviewTouchDown and MainWindow.PreviewTouchUp and maintain a list of all the current touch devices. It would be easy to implement but could make your code messy.
2) Subscribe to Touch.FrameReported which you can get a collection of touch points from the TouchFrameEventArgs.GetTouchPoints(null);. This will happen on every touch event firing, so it may be too often, but it would allow you to handle this event from any class.
You can subscribe to your main windows ManipulationStarting event (when the first finger makes contact with the screen), ManipulationInertiaStarting event (when the last finger lifts off the screen) and/or ManipulationDelta event (when any finger moves).
Within your event handlers you can get a list of all current touchpoints via ManipulationDeltaEventArgs.Manipulators
Don't forget to set your main window's IsManipulationEnabled to true.
This way you just have to remember whether a manipulation is currently in progress or not. You don't have to keep track of all the individual touch points yourself.