What I am going to do is very simple, I want to hide the mouse cursor after 1 second if the move does not move or click.
I searched and saw someone recommends using WM_MOUSEMOVE. In my app, however, WM_MOUSEMOVE is simply a dectection of whether the mouse is in the client area. If it is, the app receives WM_MOUSEMOVE continually. I've read the MSDN page but I am still confused.
Use WM_SETCURSOR.
Use WM_SETCURSOR for cursor related works. This message is made for that purpose. Your mentioning of client area suggest you probably need to use SetCapture API also.
Another way (or more modern way of doing) is using TrackMouseEvent. It provides WM_MOUSEHOVER.
The recommendation is correct. What you need to do is define a timer (for example, one that triggers the WM_TIMER message).
You activate it in the first mouse movement (WM_MOUSEMOVE). If a mouse movement won't occur within the interval you defined for the timer, the WM_TIMER event will fire and you can then hide the mouse.
Each time the WM_MOUSEMOVE event fires, you simply restart the timer (using its dedicated API). So that WM_MOUSEMONVE events prevent the timer from expiring. If WM_MOUSEMOVE stop arriving (because you don't move the mouse anymore), the timer will tick without interrupts until it elapses and fires.
Related
at the moment I have to code some mouse-events in C++. I know that there are mouse events for press, release, move, double click.
What I wonder about is how to distinguish between events when they are used in a different order. Lets say I do:
Mouse move -> Mouse click -> Mouse move -> Mouse release
How can I distinguish between the first an the second Mouse-move event?
I solved that by using a flag "Mouse-click-flag" that is set true while running the Mouse-click-event. In the mouse-move routine, I have an if-Statement checking (Mouse-click-flag== true), that decides weather or not to run the Mouse-click-event-routine. This works but it seemes very complicated.
How would one solve this?
Thank you
itelly
What you're doing is correct. You would also want to set Mouse-click-flag to false on your mouse release event, but you've probably figured that out and just didn't say it. You mention running a mouse-click-event routine on the first move. Is there a reason you don't run that in the mousePressEvent routine? There are good reasons sometimes...just confirming that's what you need.
If you only care about mouse move events while the user has the mouse down, then as thuga said, turn off mouse tracking by calling "setMouseTracking" on the widget and set it to false. Then you will only ever get click-move-release patterns.
I'd like to understand how callback functions in a windowing application (like FreeGLUT, GLFW) work.
How many times they check for keyboard/mouse/resize events per second?
Does it depend on the frame rate, is it constant or maybe operation system specific?
Speaking generally, without getting into specifics for Unix or Windows implementations, callbacks are invoked from a main event loop which looks roughly like this:
Loop forever {
Get a message from the event queue.
Process the message
}
The stage of "Get a message" will have a very small sleep if it waits for a message to appear in the queue, probably less than a millisecond. The event queue will contain every message relevant to the application, including things like mouse button presses, mouse motion events, keyboard events, and window events like resize and expose.
The "Process the message" step will take an event and dispatch it to whatever is relevant for the event. So for example, a mouse click might result in the callback for a Button widget being called. Or if your OpenGL drawing area has an input handler callback set up, the mouse click would result in that function being called.
Here are a couple of resources to learn more about the process:
For Windows: http://en.wikipedia.org/wiki/Message_loop_in_Microsoft_Windows
For X/Motif: http://www.unix.com/man-page/all/3x/XtAppMainLoop/
If you want to see the specific steps along the way (there are many), you might try setting a breakpoint in a function you're interested in, such as your main OpenGL draw routine or an input callback function. Then the call stack will show you how you got there.
I'm writing a Win32 OpenGL application for painting where it is critical that all mouse movement is handled. As it happens, sometimes the painting operation in my program is not able to perform in real time -- which is fine for me, as long as all mouse events are queued and can be handled later. Now I would have thought that this would simply be a matter of calling PeekMessage making sure to process all events, but when I do this, it is apparent that the mouse movements my application receives are not of the same fidelity that as those being displayed by Windows.
Is this a feature of Windows? Are mouse event dropped when the application is labor intensive? Or am I missing something? In either case, what can I do to remedy this situation? I would like to avoid multi-threading, part of the reason being that, as I understand, Win32 requires the message callback to be in the main thread and I'm not sure about separating the OpenGL-stuff to a different context.
And as for code example, I am essentially using the template code in the link below. The message I'm checking for is WM_MOUSEMOVE.
http://nehe.gamedev.net/tutorial/creating_an_opengl_window_(win32)/13001/
Is this a feature of Windows? Are mouse event dropped when the application is labor intensive?
Yes, this is a feature. WM_MOUSEMOVE messages are not dropped, they are synthesized. In other words, they are not actually posted to the message queue. That wouldn't work very well in practice, a user could generate a great many mouse moves in a second and rapidly fill the message queue to capacity when your program is busy.
You get a WM_MOUSEMOVE message when the mouse was moved since the last time you called GetMessage(). And you get the last known position. So the rate at which you get them, and the number of pixels between them, depend directly on how often you call GetMessage().
An alternative is to use raw input.
WM_MOUSEMOVE is special in that it isn't queued; it's automatically generated as needed when the message queue is empty. (WM_PAINT and WM_TIMER behave the same way.)
Raymond Chen suggests using GetMouseMovePointsEx if you need additional mouse input data.
Additional reading:
Why do I get spurious WM_MOUSEMOVE messages?
Paint messages will come in as fast as you let them
I am using below code in my application's view on particular event to simulate a left mouse click.
SendMessage(WM_LBUTTONDOWN);
SendMessage(WM_LBUTTONUP);
Once this code executed a mouse drag view appears. How to avoid this drag view after simulating the mouse click?
When I monitored via SPY++ I got the both messages are sent like below,
WM_LBUTTONDOWN fwKeys: MK_LBUTTON xPos : 752 yPos:85
WM_BUTTONUP fwKeys:0000 xPos:752 yPos 85
I suspect the WM_LBUTTONUP message not sent properly.
What is the fwKeys : 0000 indicates?
Is there any think wrong in sendMessage of WM_LBUTTON up in the above code?
First of all, if that is your real code, you are "simulating" the mouse click improperly. There's more to a WM_LBUTTONDOWN or WM_LBUTTONUP than the message itself: there's data packed in the wParam and lParam values of the message.
You could easily see that if you had taken a second to look at the MSDN pages for WM_LBUTTONDOWN and WM_LBUTTONUP. They describe exactly what the wParam and lParam values mean in this context. And, by the way, this would also answer your question about the meaning of "fwKeys" in Spy++.
But really, if you need to simulate mouse events, then do it the right way: call the mouse_event function. It's whole purpose in life is to synthesize mouse events.
On to your other question: how to disable the drag view: it depends on what kind of control you're dealing with. For example, if you had a tree view control, then you could set the TVS_DISABLEDRAGDROP style on the control, as stated on MSDN. If you want to disable drag & drop for that control permanently, then set the flag when you create the control. If you only want to disable it temporarily, during your synthesized input operations, then that's a bit trickier - you can use CWnd::ModifyStyle to temporarily remove the TVS_DISABLEDRAGDROP but you will also need to add code to enable it again, after you finish sending your synthesized mouse movements and the control has finished processing them.
With all that said, what exactly are you trying to achieve? There may be an easier way to solve the problem that you are trying to address.
Thanks for all your answers and support.
I am working on a already developed application which requires this solution. Finally I found that the WM_LBUTTONDOWN handler was already defined in my view. This takes time to execute. Since I used SendMessage which posts message to a thread's message queue and return immediately, before the WM_LBUTTONDOWN finished, the next message WM_LBUTTONUP is called. So the WM_LBUTTONUP was failing.
I used PostMessage as below,
PostMessage(WM_LBUTTONDOWN);
PostMessage(WM_LBUTTONUP);
This resolves my problem.
I have a hook setup for getting mouse events in a plugin I develop. I need to get the WM_LBUTTONDBLCLK, and I expect the message flow to be:
WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDBLCLK
If I call the next hook when dealing with the first WM_LBUTTONDOWN, then the flow is as expected. However, if I return my own result, then the expected double click comes as a mouse down message. Any idea why this is happening? I need the message to stop after I handle it, and not have it passed to the next hook.
After having done a little reading over at the MSDN, I think the explanation of this behaviour lies in this remark on the WM_LBUTTONDBLCLK page:
Only windows that have the CS_DBLCLKS
style can receive WM_LBUTTONDBLCLK
messages, which the system generates
whenever the user presses, releases,
and again presses the left mouse
button within the system's
double-click time limit.
If your program is returning a nonzero value when it handles WM_LBUTTONDOWN or WM_LBUTTONUP, then those messages aren't sent to the target window -- as expected. However, my inference, based on the above quote, is that since no window with the CS_DBLCLKS style is therefore receiving the messages (since the hook prevents any window from receiving the messages), the system therefore doesn't feel like it needs to generate a WM_LBUTTONDBLCLK.
To put it another way, the system only generates a WM_LBUTTONDBLCLK if and only if (a) a window receives the previous WM_LBUTTONDOWN/WM_LBUTTONUP messages and (b) that window has the CS_DBLCLKS style. Since your hook prevents condition (a) from being satisfied, WM_LBUTTONDBLCLK is never generated and so a WM_LBUTTONDOWN message is sent instead.
As to a workaround, I doubt there's a perfect solution. I assume the reason why you want to receive the WM_LBUTTONDBLCLK message is so your hook knows whether or not a regular WM_LBUTTONDOWN message represents the second click of a double-click, right? In that case, what you could do is read the double-click time from the registry as Faisal suggests and have your hook measure the time between WM_LBUTTONDOWN messages, however there's a large chance that you will get inaccurate results (due to the lag time between the messages being sent). Alternatively if there's some way you could instead redirect the WM_LBUTTONDOWN/WM_LBUTTONUP messages to maybe a hidden window that your hook owns (which has the CS_DBLCLKS style), the system may end up generating a WM_LBUTTONDBLCLK message and sending it to your hidden window, which you can then process in that window's WndProc (though I don't have a lot of experience with hooking so I don't know if this is possible).
Are you calling CallNextHookEx() before returning your own result - according to MSDN's documentation MouseProc it is highly recommended that you call it since when you return your own result you prevent other hooks from being called.
Have you considered using a low level mouse hook? It doesn't require your DLL to be injected into the process being hooked and I find it to be a more consistent and powerful hook (albeit more resource intensive if not coded appropriately) - especially when listening for clicks in some legacy applications (there was one that was coded in ancient delphi) and clicks in applications served via terminal servers (citrix).
The only issue with low level mouse hooks is that they don't receive double clicks per se - which means you have to query the registry for the 'DoubleClickSpeed' and then check for two mouse down events within that interval before triggering a double click.