c-如何准确测量具有已知DPI的鼠标的英寸或厘米为单位的鼠标移动
作者:互联网
我有一个Logitech G500游戏鼠标,它以5700的完整DPI运行.
我正在尝试用C语言编写一个程序,该程序可以精确地测量鼠标在物理单位上的水平移动.厘米或英寸.
我正在通过WM_INPUT消息使用Windows API和Windows原始输入,以从鼠标获取原始运动更改.
然后,我假设通过WM_INPUT报告的1个运动单位是1/5700英寸,当我跟踪鼠标的净运动时,我认为我可以执行一个简单的计算来产生净物理运动:
距离(英寸)= total_movement_from_wminput / dpi; //在这种情况下dpi = 5700
不幸的是,该计算似乎并不准确.从仅在我的鼠标垫上进行的物理测量,我可以知道,在大约6英寸的鼠标移动范围内,计算得出的值约为5个半英寸(损失约1/2英寸).
我要去哪里错了?我已经在其控制面板中将鼠标设置为5700DPI,它的实际DPI会小于吗?我对通过WM_INPUT进行的1单位变化的假设是否是1 / dpi英寸的物理运动是错误的?
有人对我如何使它变得准确有任何想法吗?谢谢!
解决方法:
渣,
看来问题可能出在您以比Windows事件WM_INPUT处理鼠标更快的速度移动鼠标.例如,假设鼠标在一帧中移动了2个像素.您将损失1/5700英寸(在您的情况下),因为对于处理的一个WM_INPUT事件,您将移动两个像素.
要解决此问题,您应该检查每次将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变量2确定自上一次启动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时的英寸偏移量.
完全简单的方法是处理WM_MOUSEMOVE事件.这样可以轻松获得鼠标的确切位置(当然,以像素为单位).使用此功能,可以从起始位置的像素值中减去此值.
例:
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.
总结一下,您做错了什么,您错误地认为每个WM_INPUT事件都意味着鼠标移动了1个像素.
如果由于某种原因我误解了该问题,并且您知道已经移动了正确数量的像素,请发表评论,我会尽力尝试解决问题.但是,我仍然建议使用WM_MOUSEMOVE而不是WM_INPUT,因为它专门用于鼠标,并且会应用“指针加速”,您可以在最底部的链接上阅读该信息.
感谢您提出问题,tcs08
Msdn code and explanation for mouse input with WM_INPUT
Msdn code and explanation for mouse input with WM_MOUSEMOVE
标签:raw-input,c,winapi,distance,dpi 来源: https://codeday.me/bug/20191011/1891606.html