ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2019-10-11 10:10:02  阅读:386  来源: 互联网

标签:raw-input c winapi distance 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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有