gpt4 book ai didi

c++ - 如何准确测量具有已知 DPI 的鼠标的鼠标移动(以英寸或厘米为单位)

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:51:36 25 4
gpt4 key购买 nike

我有一个罗技 G500 游戏鼠标,它以 5700 的全 DPI 运行。

我正在尝试用 C++ 编写一个程序,以物理单位准确测量鼠标的水平移动,即。厘米或英寸。

我正在使用 Windows API 和通过 WM_INPUT 消息的 Windows 原始输入来获取鼠标的原始移动变化。

然后我假设通过 WM_INPUT 报告的 1 个移动单位是 1/5700 英寸,并且当我跟踪鼠标的净移动时,我想我可以执行一个简单的计算来产生净物理移动:

距离(英寸)= total_movement_from_wminput/dpi;//在这种情况下 dpi = 5700

不幸的是,计算似乎并不准确。我可以通过鼠标垫上的物理测量得知,鼠标移动大约 6 英寸后,计算得出的值大约为 5.5 英寸(损失大约 1/2 英寸)。

我哪里错了?我在鼠标的控制面板里设置了5700DPI,它的实际DPI会不会低于这个?我关于通过 WM_INPUT 的 1 个变化单位是 1/dpi 英寸物理运动的假设是否不正确?

有没有人对我如何使它准确无误有任何想法?谢谢!

最佳答案

马克,

看来问题可能出在您移动鼠标的速度快于 Windows 事件 WM_INPUT 处理它的速度时。例如,假设鼠标在一帧中移动了 2 个像素。您将损失 1/5700 英寸(在您的情况下),因为对于处理的 one WM_INPUT 事件,您将移动 two像素。

要解决此问题,您应该检查每次向程序发送 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 时的英寸偏移量。


一个完全更简单的方法是改为处理 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

关于c++ - 如何准确测量具有已知 DPI 的鼠标的鼠标移动(以英寸或厘米为单位),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15455888/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com