Is there any way to get mouse state (position, buttons states) using winapi in C++?
I don't want to use windows messages (WM_MOUSEMOVE, WM_LBUTTONDOWN, etc).
Thank you!
It sounds like you are looking for GetCursorInfo and GetKeyState. The latter you call with virtual key codes that specify the mouse button of interest.
If you only need cursor position, you can just use GetCursorPos(). Remember that both GetCursorInfo() and GetCursorPos() return screen coordinates. Use ScreenToClient() to convert to client area offsets.
Although the OP didn't want to use Windows Messages, I just wanted to mention something as a sidenote.
Something I found was that getting the cursor position as part of a message handler (for instance WM_SETCURSOR), most of the literature recommends using GetMessagePos() to retrieve the cursor's position at the time the message was sent. However, its the position before the mouse moved, not after. So the position returned 'lags' behind a pixel when trying to do mouseover detection over an area.
Related
I'm using WM_MOUSEMOVE to get changes in mouse position. When simulating "knobs" for example it's desired to let the user go up/down with mouse without any limits. In this cases I hide cursor and use SetCursorPos to change its position every time user moves with it and detect just the difference from the original position.
Unfortunately it doesn't seem to work - if I set the mouse position, it sometimes works, but sometimes is one or more pixels away, which is just wrong. And even bigger trouble is that after the call another WM_MOUSEMOVE seems to be delivered, which unfortunately does the same thing as it wants to move the cursor back to the original position again. So it ends up in an infinite cycle or settings mouse position and receiving messages until the user releases the mouse button.
What's the correct approach or what's the problem?
The raw input system can do this - it lets you register for raw mouse input that isn't clipped or confined to the screen boundaries.
Broadly speaking, you register for raw input using RegisterRawInputDevices(). Your window will then receive WM_INPUT messages, which you process using the GetRawInputData() function.
See Using Raw Input for an example.
I hide cursor and use SetCursorPos to change its position every time user moves with it and detect just the difference from the original position.
This is just plain wrong. Instead, use SetCapture() to capture the mouse. All movements will be reported as WM_MOUSEMOVE messages with coordinates that are relative to the specified window, even if the mouse is outside of that window, until you release the capture.
Asking the user to move the mouse continuously, even after the cursor hit the screen limit is a very bad idea in terms of User Interface, IMHO.
Some games have another approach: when the mouse hit the "limit", the game enter a special mode: things appears to function exactly as if the mouse was moving, even if the user don't move it. When the user wants to exit that mode, he just has to move the mouse of the limit.
Doing so requires a timer, armed when the mouse hit some limit, executing code periodically as if the mouse was moving. The timer is stopped when a real mouse movement makes it leaves the limit.
Ok folks, so I found a solution simple enough:
The main problem is that SetCursorPos may not set the coordinates accurately, I guess it's because of some high resolution processing, nevertheless it's probably a bug. Anyway if SetCursorPos doesn't set the coordinates correctly (but +-1 in x and/or y) it also sends WM_MOUSEMOVE to the target window. As a result the window performs the exact same operation as before and this goes on and on.
So the solution is to remove all WM_MOUSEMOVE messages right after SetCursorPos:
MSG msg;
while (::PeekMessage(&msg, NULL, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)) { };
Then retrieving the current mouse cursor pos using ::GetCursorPos .
It's ugly but seems to fix the problem. It basically seems that in some position of the mouse, the system always adds or subtracts 1 in either coordinate, so this way you let system do the weird stuff and use the new coordinates without trying to persuade system that your coordinates are the correct ones :).
I'm creating an FPS demo using an Engine called: Gameplay. I'm currently trying to define a captureMouse() function into the engine so the player can look around the map. I've already been able to pin the cursor to the center of the window and turn it invisible, but as I move the mouse the screen (camera) seems to "vibrate" as it moves around. After a lot of tinkering with X11 functions I figured that the XWarpPointer() function I'm using to warp the cursor back to the center of the window is adding a "mouse moved" event to the event queue.
X11 Question: How can I identify and remove an event from the event queue before it is captured by the event cycle?
Question: Has anyone been a similar problem and solved in a different manner? If so, what did you do?
I'm sorry if I'm not being clear. I have no extensive knowledge of X11, but I really need to add this to the engine so I can, in turn, add it to my game.
I guess you're using XtAppMainLoop to handle your events.
This is actually a call to XtAppNextEvent followed by XtDispatchEvent.
If you replace the XtAppMainLoop with a loop calling XtAppNextEvent to get the next event and check its type (the type field of the XEvent structure).
If you want to handle the event call XtDispatchEvent, do nothing to ignore it.
The loop needs to exit when XtAppGetExitFlag returns true (or add your own exit flag).
How to find out blink cursor position in windows, from c++? In many cases I need send button click on the position of the blinking cursor, but I didn't find any important function which will take care of that.
OS win 7(64), c++
It is called "caret", cursor is the mouse pointer. You use GetCaretPos() to get its position. But the returned position is relative to the client area of the window that owns the caret. Which probably means that you need to find that window first, use GetForegroundWindow() for that. And don't send button click messages, they are posted so use PostMessage().
Avoid all of this by just using SendInput().
Note that UIPI (the user interface component of UAC) prevents you from poking stuff into a window owned by an elevated process.
GetGUIThreadInfo() is probably your best bet; pass it with idThread = 0 to get the info from the currently active thread, and then check the rcCaret member of the returned GUITHREADINFO structure. You'll then need to use ClientToScreen() with the hwndCaret value to convert client-relative coordinates to screen coordinates.
Note that this only works for apps that use the Win32 caret functions - specifically SetCaretPos(). If an app draws its own caret without using these, you may not get anything meaningful back. (Some apps, like Word, draw their own caret, but still call SetCaretPos so that accessibility aids that need to track the caret can use this technique.)
The rectangle you get back can sometimes be wider than the actual caret. When a bitmap is used for the caret, as is the case for Right-To-Left or Left-To-Right carets that have a little 'flag' attached to the top, you'll get back a rectangle that's a bit wider than the actual caret area, and may need to adjust or otherwise figure out where within this area the actual caret bar is - it may or may not be in the exact middle. Looks like for Notepad++ you should be fine, though.
I want to separate the stylus position from the mouse position in a win32 application. I'm using the wintab sdk and I've seen articles about distinguishing between mousebuttondown/up events coming from the pen/eraser or mouse. But I haven't been able to find anything that lets you use the stylus as a second device. I want to respond to WT_PACKET events to determine the position of the pen for painting, and use the mouse cursor for other operations.
I figured it out.
LOGCONTEXT lc;
lc.lcOptions |= CXO_SYSTEM // this flag links it to the system cursor.
return WTOpen(hWnd, &lc, TRUE;
.....
I'm working on a Win32 control. There could be hundreds of "items" on this control. Those are not windows, but internal objects (eg: rectangles). Depending on the mouse position I want to change the mouse cursor. That is fine, I can use WM_SETCURSOR.
At the same time based on mouse move I want to display a status bar which shows details about the object currently under the mouse. For that I can use WM_MOUSEMOVE.
Because there could be hundreds of items, traveling all of them to find one under the mouse, well it's not efficient, especially two times (one for set cursor, one for mouse move).
To make it short, do you know if WM_SETCURSOR and WM_MOUSEMOVE are ALWAYS in pair? In that case I can calculate what I want during WM_SETCURSOR. The other option would be to set the mouse cursor during WM_MOUSEMOVE, but as far as I know that it's not a good solution (will flicker).
Thanks
While they might currently always come as a matched pair, you probably can't rely on this behaviour.
You can set the cursor during WM_MOUSEMOVE (using SetCursor), and it won't flicker, as long as (IIRC), you return TRUE from WM_SETCURSOR without doing anything (i.e. you eat the message), and your window doesn't have a class cursor assigned to it.
You might also try GetMessagePos() (gives cursor screen coordinates), then MapWindowPoints() and see if it's in hot rectangle, or something similar.
Most important of all is that your window message handlers shouldn't worry about holding or calculating anything. You should simply signal your application's logic that the mouse is potentially over new area and make it find the object(s). Once you find the hot area (or more than one), cache its (their) boundaries and check the following mouse moves against those. Once the mouse moves out from one of them, you can rebuild your hot-object-list.
You don't have to be hunting for the hot area all over the control on every mouse move.
In case when there can be many objects sharing the same area, there's the question of z-order. Think about it when you're creating those objects and handle their movement.
Also you should think about an efficient data structure holding the object coordinates so you don't have to check every single object every time you're looking for the hot one.
Just my two euros. ;)
Is there any way to cache the last item that was found, and shortcut the lookup if the cursor is in the same place? That would be the most robust solution.