首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用已知的DPI精确测量鼠标的移动(英寸或厘米)

如何使用已知的DPI精确测量鼠标的移动(英寸或厘米)
EN

Stack Overflow用户
提问于 2013-03-17 07:21:39
回答 1查看 3.3K关注 0票数 2

我有一个罗技G500游戏鼠标,它是运行在其完整的DPI5700。

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

我通过WM_INPUT消息使用windows API和windows raw input来获取鼠标的原始移动更改。

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

距离(英寸)= total_movement_from_wminput / dpi;// dpi = 5700

不幸的是,计算似乎并不准确。我可以从我的鼠标垫上的物理测量中看出,在鼠标移动大约6英寸的情况下,计算得到的值大约是5.5英寸(每英寸损失大约1/2英寸)。

我哪里错了?我已经在控制面板中将鼠标设置为5700DPI,它的实际DPI是否会小于5700DPI?我假设通过WM_INPUT的1个单位的变化是1/dpi英寸的物理移动是不正确的吗?

有没有人知道我怎么才能让这个更准确呢?谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-07-04 07:45:36

马克

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

要解决此问题,应检查每次将WM_INPUT消息发送到程序时鼠标移动的像素数。您需要做的是创建一个RAWINPUTDEVICE变量并设置结构,以便它包含有关鼠标的信息。

下面的代码注册RAWINPUTDEVICE,以便可以在WM_INPUT中使用它。

代码语言:javascript
运行
复制
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变量two来确定自上次启动WM_INPUT以来鼠标移动了多少像素。

代码语言:javascript
运行
复制
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。

初始位置= (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

Msdn code and explanation for mouse input with WM_INPUT

Msdn code and explanation for mouse input with WM_MOUSEMOVE

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15455888

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档