I'm currently writing a c++ console application that grabs the mouse position at regular intervals and sends it to another visual application where it is used to drive some 3d graphics in real time. The visual app is closed source and cannot be altered outside it's limited plug-in functionality.
Currently I'm using the GetCursorPos() function which is easy and fast enough, but I'm running into the issue that all of the data is clipped based on the current screen resolution of 1920x1600 so that all x values are between 0 and 1920 and all y values are between 0 and 1600 no matter how far the mouse is physically moved.
I need to get the mouse position before it's clipped at the edge of the screen, or possibly the deltas which I could use to calculate the current position.
I've seen some references to the windows MouseMove event but I would really not want to implement a window to make it work or especially have it as the active to receive those events.
I'm working in a windows environment and a language change is not feasible.
I might be wrong, but in Win32 land you don't get mouse move messages when the mouse is at the edge of the screen because, well, the mouse isn't moving. The usual way to get an infinite mouse area is to do the following:
Hide the mouse, get exclusive access and record position
Centre mouse to window
When mouse moves, get delta from centre of screen to current position
Centre mouse to window again
The next mouse move should have a delta of (0,0), so ignore it
Go to 3 until end of mouse move operation
Reset position, show the mouse and release exclusive access
If you didn't hide the mouse, then you'd see the mouse moving a small distance and then snapping back to the centre position, which looks nasty.
This method does require a message pump for the mouse move messages so the console application idea probably won't work with this. Can you create a full screen invisible window for grabbing the mouse?
Just get the position, and move it to the center and return the delta yourself
This is how FPS games do it
I don't have any direct experience with raw input, which is probably what you need to tap into. According to MSDN, you have to register the device, then setup your winproc to accept the WM_INPUT messages and then do your calculations based on the raw data.
Here's another relevant link.
Related
I want to have my code read the movement of the mouse and act accordingly, for example, if you are moving your mouse up, you print the mouse is moving up in the console and sort of like that. (I am using Windows 10.)
The problem is, I could find a lot of articles that take the coordinates of the mouse cursor, but couldn't find one that deals with the real raw mouse input. The reason I want to do it this way is that when your cursor hits the border and cannot go further, the cursor position wouldn't change and the program won't recognize the mouse movement even though the mouse is "physically" moving. Another problem is that certain programs can "lock" your cursor to stay in a fixed position. For example, most FPS games do that.
Therefore, I wanted to get the raw input that the sensor of the mouse gives to the computer and utilize them instead of cursor position.
Therefore, I wanted to get the raw input that the sensor of the mouse gives to the computer and utilize them instead of cursor position.
Use the Raw Input API for that. Call RegisterRawInputDevices() to register the target mouse device(s) you want to monitor (there could be multiple connected to the PC), and then handle WM_INPUT messages containing the raw input data from the mouse(s).
I am trying to record my in-game mouse movement so I can play it back. The game is Call of Duty 4, although that isn't relevant to this question. What is relevant is that most First Person Shooter games re-center the mouse cursor when you move it, so that you never hit any borders. I can't find anything about this online after searching for a while. I am currently using a mouse hook (WH_MOUSE) in order to keep track of the mouse movements (WM_MOUSEMOVE). When I list these messages, I can see that the cursor is pulled back to screenResolutionX / 2, screenResolutionY / 2 (the center of the screen).
My first attempt at figuring this out was to ignore the messages if they are equal to the center of the screen, so that when I play back these mouse movements, the re-centering is ignored. I assumed this would solve the problem, but now when I play back the mouse movements the mouse goes too far (way off from what I recorded). When I do the same recording/playing back in the main menu of the game (where the cursor isn't re-centered), the playback is incredibly accurate. My question is: what can I do to record mouse movements in the game accurately, given that the game re-centers my cursor?
Thanks in advance.
Edit: let me clarify what I'm asking. I want to only record actual user mouse input, not the game re-centering the mouse cursor.
In order to intercept those mouse messages you'd have to make a filter driver or a hook. Here's a nice article (with code) on the subject:
http://www.oblita.com/interception.html
That article is based on this Windows API: SetWindowsHookEx and shold be a good starting point for you.
Have you considered Low Level Mouse Hook? It intercepts mouse messages earlier than just mouse hook.
I am developing a brush just like the brush in mspaint, but I cannot get all the pixels from
WM_MOUSEMOVE when the mouse move over the pixels.only can get a set of desultory points.
You can use GetMouseMovePointsEx to get a history of the last 64 mouse points, which may include points that were never delivered to your app via WM_MOUSEMOVE.
But you can often improve the performance in this sort of application by ignoring the actual mouse position that WM_MOUSEMOVE sends you and instead query the pointer position directly with GetCursorPos.
Either way, you'll never get enough resolution from the mouse to draw a smooth joined-up line - the best you can do is draw straight lines (or even interpolate splines) between the coordinates.
At the moment I simply use the WM_MOUSEMOVE message, but it limits the mouse movement to the maximum resolution. So what's the best way of capturing the mouse with Win32 (on a OpenGl window)? I don't want to use freeglut or any extra library.
For games and realtime DirectInput is very suitable, it's moderately hard to use.
That is not core win32 api, the winapi way of getting the input is either GetCursorPos/SetCursorPos driven by your own update loop, so you query and reset with your own frequency.
Or SetCapture and then upon WM_MOUSEMOVE you call SetCursorPos.
The point of setting the cursor pos is to give room for movement so you can get the delta, the amount the cursor moved since the last update and then put it back the cursor into the center of your window.
If you want to be able to capture mouse events after the mouse has existed the window, then you might want to look into the SetCapture function
If your problem is that you want to make a FPS game and you want your character to be able to spin in a continuous motion, then you want to set the mouse position to the center of the window after each mouse move event and handle input based on the difference between the position of the cursor when the mouse move event is fired and the center of the screen. To set the position of the mouse you can use the SetCursorPos function.
Your best bets are to either use DirectInput (which can be a bit of a pain to set up) or RawInput.
There is a fairly comprehensive example available in the Using RawInput page (See example 2).
Reading this article "Taking Advantage of High-Definition Mouse Movement" - http://msdn.microsoft.com/en-us/library/windows/desktop/ee418864(v=vs.100).aspx, I surmise that one should use raw input for more precise readings from input devices.
The article states that WM_MOUSEMOVE's primary disadvantage is that it is limited to the screen resolution.
Upon close inspection of the RAWMOUSE structure I see that lLastX and lLastY are long values and you get the delta via them.
To me it looks like WM_MOUSEMOVE and WM_INPUT is the same except with WM_INPUT you do not get acceleration (pointer ballistics) applied.
Are both WM_MOUSEMOVE and WM_INPUT limited to the screen resolution?
If so, what is the benefit of using WM_INPUT?
RAWMOUSE gives you logical coordinates for the mouse based on the mouse's native resolution.
That is, you see the actual movement of the mouse.
Windows will use the mouse speed and acceleration (ballistics) settings to update the cursor position. Because of course the two are not linked - the apparent movement of the mouse must be interpreted to generate a cursor movement else how can more than one mouse be supported?
If you wish to control a pointer, as far as I can tell there is no reason to duplicate the Windows mouse ballistics calculations. Just let windows do it. Therefore for controlling the pointer, you should just use WM_MOUSEMOVE. That is, unless you wish to disable the mouse acceleration settings in your application.
However, if you want to control the player's POV (point of view), or use the mouse to control an in-game object such as a spaceship flight yoke, then the RAWMOUSE data gives you the best possible access to the movement of the mouse, and you can implement your own algorithm to convert that into flight yoke/POV movement.
The main benefit and reason to use it is that that with rawInput you can use two mouses or more. Presently I write small game prototype which is designed to be played by two players with two mouses/mices - It is more complicated but It works and it is not bad because I do nod need to link external libs.