Marc,
It seems that the problem may be when you move the mouse faster than Windows event WM_INPUT
processes it. For instance, suppose the mouse moved 2 pixels in one frame. You would have a loss of 1/5700th of an inch (in your case) because for the one WM_INPUT
event processed, you would move two pixels.
To fix this, you should check how many pixels the mouse moves every time the WM_INPUT message is sent to the program. What you have to do is make a RAWINPUTDEVICE
variable and set the struct so it has the information about the mouse.
The following code registers the RAWINPUTDEVICE
so it can be used in WM_INPUT
.
RAWINPUTDEVICE Rid[1];
Rid[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
Rid[0].usUsage = HID_USAGE_GENERIC_MOUSE;
Rid[0].dwFlags = RIDEV_INPUTSINK;
Rid[0].hwndTarget = hWnd;
RegisterRawInputDevices(Rid, 1, sizeof(Rid[0]);
The following code acutally uses the Rid
variable two determine how many pixels the mouse has moved since the last time WM_INPUT
was initiated.
case WM_INPUT:
{
UINT dwSize = 40;
static BYTE lpb[40];
GetRawInputData((HRAWINPUT)lParam, RID_INPUT,
lpb, &dwSize, sizeof(RAWINPUTHEADER));
RAWINPUT* raw = (RAWINPUT*)lpb;
if (raw->header.dwType == RIM_TYPEMOUSE)
{
int xPosRelative = raw->data.mouse.lLastX; // Could be 1, or could be more than 1
int yPosRelative = raw->data.mouse.lLastY; // Could be 1, or could be more than 1!
}
break;
}
Note that this code is the same code presented on msdn on this very topic (link below).
You could now have some type of global variable that has the x-position and y-position (in pixels) of the mouse. Then, you simply divide those variables by the DPI, and you have the amount of inches offset from whenever you set the global variables to 0.
An altogether easier method would be to process the WM_MOUSEMOVE
event instead. It makes it easy to get the exact position of the mouse (in pixels, of course). Using this, you can subtract this from the pixel values of the starting location.
Example:
DPI = 5700.
Initial position = (100px, 300px).
Position after 3 seconds = (500px, 400px).
The amount of inches moved in those 3 seconds = ( (500px - 100px)/5700 inches, (400px - 300px)/5700 inches )
General rule: Amount of inches moved after S seconds = (inital_pixels_x - final_pixels_x)/DPI inches
horizontally, (initial_pixels_y - final_pixels_y)/DPI inches vertically
Here, final_pixels_x is the x-position of the mouse after s seconds, and final_pixels y is the y-position after s seconds.
To summarize what you did wrong, you incorrectly assumed that each WM_INPUT
event means that 1 pixel was travelled by the mouse.
If I for some reason misunderstood the question and you know that you are already getting the correct amount of pixels moved, please leave a comment and I will do my best to try and fix my answer. However, I would still recommend using WM_MOUSEMOVE
instead of WM_INPUT
as it is specifically for the mouse and it applies "pointer acceleration" which you can read about on the link at the very bottom.
Thank you for asking your question, tcs08
Msdn code and explanation for mouse input with WM_INPUT
Msdn code and explanation for mouse input with WM_MOUSEMOVE