如何为具有已知DPI的鼠标准确测量英寸或厘米的鼠标移动 [英] How to accurately measure mouse movement in inches or centimetres for a mouse with a known DPI

查看:209
本文介绍了如何为具有已知DPI的鼠标准确测量英寸或厘米的鼠标移动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Logitech G500游戏鼠标,它以5700的完整DPI运行。

I have a Logitech G500 gaming mouse that is running at its full DPI of 5700.

我正在尝试用C ++编写一个程序,该程序可以准确地测量水平运动鼠标的物理单位,即

I'm trying to write a program in C++ that accurately measures horizontal movement of the mouse in physical units, ie. centimetres or inches.

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

I'm using the windows API and windows raw input via the WM_INPUT message to get raw movement changes from the mouse.

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

I'm then assuming 1 unit of movement reported through WM_INPUT is 1/5700th of an inch, and as I'm tracking the net movement of the mouse, I thought I could perform a simple calculation to yield the net physical movement:

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

distance(inches) = total_movement_from_wminput / dpi; // dpi = 5700 in this case

不幸的是,该计算似乎并不准确。从仅在我的鼠标垫上进行的物理测量,我可以知道,经过大约6英寸的鼠标移动,计算得出的值约为5个半英寸(损失约1/2英寸)。

Unfortunately, the calculation doesn't seem to be accurate. I can tell from physical measuring just on my mouse pad, that over about 6inches of mouse movement, the calculation yields a value of about 5 and a half inches (a loss of a bout 1/2 an inch).

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

Where am I going wrong? I have set my mouse to 5700DPI in its control panel, could its actual DPI be less than that? Is my assumption about 1 unit of change via WM_INPUT being 1/dpi inches of physical movement incorrect?

有人对我如何使它变得准确有任何想法吗?谢谢!

Does anyone have any ideas on how I could get this to be accurate? Thanks!

推荐答案

马克,

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

It seems that the problem may be when you move the mouse faster than Windows event WM_INPUT processes it. For instance, suppose the mouse moved 2 pixels in one frame. You would have a loss of 1/5700th of an inch (in your case) because for the one WM_INPUT event processed, you would move two pixels.

要解决此问题,您应该每次将WM_INPUT消息发送到程序时检查鼠标移动了多少像素。您要做的是制作一个 RAWINPUTDEVICE 变量并设置该结构,使其具有有关鼠标的信息。

To fix this, you should check how many pixels the mouse moves every time the WM_INPUT message is sent to the program. What you have to do is make a RAWINPUTDEVICE variable and set the struct so it has the information about the mouse.

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

The following code registers the RAWINPUTDEVICE so it can be used in 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 以来鼠标移动了多少像素。

The following code acutally uses the Rid variable two determine how many pixels the mouse has moved since the last time WM_INPUT was initiated.

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上有关此主题的代码相同(下面的链接)。

Note that this code is the same code presented on msdn on this very topic (link below).

您现在可以使用某种类型的全局变量具有鼠标的x位置和y位置(以像素为单位)的ariable。然后,您只需将这些变量除以DPI,就可以将偏移量设置为0时的英寸偏移量。

You could now have some type of global variable that has the x-position and y-position (in pixels) of the mouse. Then, you simply divide those variables by the DPI, and you have the amount of inches offset from whenever you set the global variables to 0.

easier 方法将代替处理 WM_MOUSEMOVE 事件。它很容易获得鼠标的精确位置(当然,以像素为单位)。使用此功能,您可以从起始位置的像素值中减去此值。

An altogether easier method would be to process the WM_MOUSEMOVE event instead. It makes it easy to get the exact position of the mouse (in pixels, of course). Using this, you can subtract this from the pixel values of the starting location.

示例:


DPI = 5700

DPI = 5700.

初始位置=(100px,300px)。

Initial position = (100px, 300px).

3秒后的位置=(500px,400px)。

Position after 3 seconds = (500px, 400px).

这3秒钟内移动的英寸数=((500px-100px)/ 5700英寸,(400px-300px)/ 5700英寸)

The amount of inches moved in those 3 seconds = ( (500px - 100px)/5700 inches, (400px - 300px)/5700 inches )

一般规则:S秒后移动的英寸数=(inital_pixels_x-final_pixels_x)/ DPI英寸

General rule: Amount of inches moved after S seconds = (inital_pixels_x - final_pixels_x)/DPI inches

水平,(initial_pixels_y-final_pixels_y)/垂直DPI英寸

horizontally, (initial_pixels_y - final_pixels_y)/DPI inches vertically

在这里,final_pixels_x是s秒后鼠标的x位置,而final_pixels y是s秒后的y位置。

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个像素。


To summarize what you did wrong, you incorrectly assumed that each WM_INPUT event means that 1 pixel was travelled by the mouse.

如果由于某种原因我误解了这个问题,而您知道您已经迷失了方向正确移动像素数量,请发表评论,我会尽力尝试解决问题。但是,我仍然建议使用 WM_MOUSEMOVE 代替 WM_INPUT ,因为它专门用于鼠标,并且适用于指针加速

If I for some reason misunderstood the question and you know that you are already getting the correct amount of pixels moved, please leave a comment and I will do my best to try and fix my answer. However, I would still recommend using WM_MOUSEMOVE instead of WM_INPUT as it is specifically for the mouse and it applies "pointer acceleration" which you can read about on the link at the very bottom.

感谢您提出问题,tcs08

Thank you for asking your question, tcs08

使用WM_INPUT输入鼠标的Msdn代码和说明

使用WM_MOUSEMOVE输入鼠标的Msdn代码和解释

这篇关于如何为具有已知DPI的鼠标准确测量英寸或厘米的鼠标移动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆