Marc,
看来问题可能是当你移动鼠标的速度比 Windows 事件快时WM_INPUT
处理它。例如,假设鼠标在一帧中移动了 2 个像素。你会损失 1/5700 英寸(在你的情况下),因为对于one WM_INPUT
事件已处理,您将移动two pixels.
要解决此问题,您应该检查有多少像素每次向程序发送 WM_INPUT 消息时,鼠标都会移动。你要做的就是做一个RAWINPUTDEVICE
变量并设置结构,使其包含有关鼠标的信息。
以下代码注册了RAWINPUTDEVICE
所以它可以用在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]);
下面的代码实际上使用了Rid
变量二确定自上次以来鼠标移动了多少像素WM_INPUT
被发起。
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;
}
请注意,此代码与 msdn 上有关该主题的代码相同(链接如下)。
您现在可以拥有某种类型的全局变量,其中包含鼠标的 x 位置和 y 位置(以像素为单位)。然后,您只需将这些变量除以 DPI,就可以得到与将全局变量设置为 0 时的英寸偏移量。
总共一个easier方法是处理WM_MOUSEMOVE
事件代替。它可以轻松获得鼠标的准确位置(当然以像素为单位)。使用它,您可以从起始位置的像素值中减去它。
Example:
分辨率 = 5700。
初始位置 = (100px, 300px)。
3 秒后的位置 = (500px, 400px)。
这 3 秒内移动的英寸数 = ( (500px - 100px)/5700 英寸, (400px - 300px)/5700 英寸 )
一般规则:S 秒后移动的英寸数 = (inital_pixels_x - Final_pixels_x)/DPI 英寸
水平方向,(initial_pixels_y - Final_pixels_y)/DPI 英寸,垂直方向
这里,final_pixels_x 是 s 秒后鼠标的 x 位置,final_pixels y 是 s 秒后的 y 位置。
总结一下你做错了什么,你错误地假设每个WM_INPUT
事件意味着鼠标移动了 1 个像素。
如果我出于某种原因误解了这个问题,并且您知道您已经移动了正确数量的像素,请发表评论,我将尽力尝试修复我的答案。不过,我仍然建议使用WM_MOUSEMOVE
代替WM_INPUT
因为它是专门针对鼠标的,并且它应用“指针加速”,您可以在最底部的链接上阅读有关内容。
感谢您提出问题,tcs08
WM_INPUT鼠标输入的msdn代码和解释
WM_MOUSEMOVE鼠标输入的msdn代码和解释