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

2023-12-15

我有一个 Logitech G500 游戏鼠标,其全 DPI 为 5700。

我正在尝试用 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 英寸物理运动的假设是否正确?

有谁对我如何使其准确有任何想法吗?谢谢!


Marc,

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

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


总共一个easier方法是处理WM_MOUSEMOVE事件代替。它可以轻松获得鼠标的准确位置(当然以像素为单位)。使用它,您可以从起始位置的像素值中减去它。

Example:

分辨率 = 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

WM_INPUT鼠标输入的msdn代码和解释

WM_MOUSEMOVE鼠标输入的msdn代码和解释

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何准确测量具有已知 DPI 的鼠标的鼠标移动(以英寸或厘米为单位) 的相关文章

  • 用于代数简化和求解的 C# 库 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 网络上有很多代数求解器和简化器 例如 algebra com 上不错的代数求解器和简化器 然而 我正在
  • 每个托管线程是否都有自己对应的本机线程?

    我想知道是否在 Net 中创建托管线程 通过调用Thread Start 导致在后台创建一个本机线程 那么托管线程是否有对应的本机线程呢 如果是 当托管线程等待或睡眠时 是否意味着相应的本机线程也在等待或睡眠 是的 NET 线程映射到所有当
  • 使用 std::packaged_task/std::exception_ptr 时,线程清理程序报告数据争用

    我遇到了线程清理程序 TSan 的一些问题 抱怨某些生产代码中的数据争用 其中 std packaged task 通过将它们包装在 std function 中而移交给调度程序线程 对于这个问题 我简化了它在生产中的作用 同时触发 TSa
  • 如何在 .NET Framework 2.0 中模拟“Func<(Of <(TResult>)>) 委托”?

    我尝试使用这个类代码项目文章 http www codeproject com KB threads AsyncVar aspx在 VB NET 和 NET Framework 2 0 中 除了这一行之外 所有内容似乎都可以编译Privat
  • 如何将非静态类成员“std::bind”绑定到 Win32 回调函数“WNDPROC”?

    我正在尝试将非静态类成员绑定到标准WNDPROC http msdn microsoft com en us library ms633573 aspx功能 我知道我可以通过将类成员设为静态来简单地做到这一点 但是 作为一名 C 11 ST
  • 提交后禁用按钮

    当用户提交付款表单并且发布表单的代码导致 Firefox 中出现重复发布时 我试图禁用按钮 去掉代码就不会出现这个问题 在firefox以外的任何浏览器中也不会出现这个问题 知道如何防止双重帖子吗 System Text StringBui
  • 在 DataView 的 RowFilter 中选择 DISTINCT

    我试图根据与另一个表的关系缩小 DataView 中的行范围 我使用的 RowFilter 如下 dv new DataView myDS myTable id IN SELECT DISTINCT parentID FROM myOthe
  • 使用 Newtonsoft 和 C# 反序列化嵌套 JSON

    我正在尝试解析来自 Rest API 的 Json 响应 我可以获得很好的响应并创建了一些类模型 我正在使用 Newtonsoft 的 Json Net 我的响应中不断收到空值 并且不确定我的模型设置是否正确或缺少某些内容 例如 我想要获取
  • 如何区分用户点击链接和页面自动重定向?

    拥有 C WebBrowser control http msdn microsoft com en us library system windows forms webbrowser aspx在我的 WinForms 应用程序中 并意识
  • 获取两个工作日之间的天数差异

    这听起来很简单 但我不明白其中的意义 那么获取两次之间的天数的最简单方法是什么DayOfWeeks当第一个是起点时 如果下一个工作日较早 则应考虑在下周 The DayOfWeek 枚举 http 20 20 5B1 5D 3a 20htt
  • 具有交替类型的可变参数模板参数包

    我想知道是否可以使用参数包捕获交替参数模式 例如 template
  • 如何检测表单的任何控件的变化?

    如何检测 C 中表单的任何控件的更改 由于我在一个表单上有许多控件 并且如果表单中的任何控件值发生更改 我需要禁用按钮 我正在寻找一些内置函数 事件处理程序 属性 并且不想为此创建自定义函数 不 我不知道任何时候都会触发任何事件any控制表
  • Qt - ubuntu中的串口名称

    我在 Ubuntu 上查找串行端口名称时遇到问题 如您所知 为了在 Windows 上读取串口 我们可以使用以下代码 serial gt setPortName com3 但是当我在 Ubuntu 上编译这段代码时 我无法使用这段代码 se
  • 等待进程释放文件

    我如何等待文件空闲以便ss Save 可以用新的覆盖它吗 如果我紧密地运行两次 左右 我会得到一个generic GDI error
  • AES 128 CBC 蒙特卡罗测试

    我正在 AES 128 CBC 上执行 MCT 如中所述http csrc nist gov groups STM cavp documents aes AESAVS pdf http csrc nist gov groups STM ca
  • 如何设置 log4net 每天将我的文件记录到不同的文件夹中?

    我想将每天的所有日志保存在名为 YYYYMMdd 的文件夹中 log4net 应该根据系统日期时间处理创建新文件夹 我如何设置它 我想将一天中的所有日志保存到 n 个 1MB 的文件中 我不想重写旧文件 但想真正拥有一天中的所有日志 我该如
  • 如何在非控制台应用程序中查看 cout 输出?

    输出到调试窗口似乎相当繁琐 我在哪里可以找到cout如果我正在编写非控制台信息 则输出 Like double i a b cout lt lt b lt lt endl I want to check out whether b is z
  • 不同类型指针之间的减法[重复]

    这个问题在这里已经有答案了 我试图找到两个变量之间的内存距离 具体来说 我需要找到 char 数组和 int 之间的距离 char data 5 int a 0 printf p n p n data 5 a long int distan
  • 如果没有抽象成员,基类是否应该标记为抽象?

    如果一个类没有抽象成员 可以将其标记为抽象吗 即使没有实际理由直接实例化它 除了单元测试 是的 将不应该实例化的基类显式标记为抽象是合理且有益的 即使在没有抽象方法的情况下也是如此 它强制执行通用准则来使非叶类抽象 它阻止其他程序员创建该类
  • C++ 条件编译

    我有以下代码片段 ifdef DO LOG define log p record p else define log p endif void record char data 现在如果我打电话log hello world 在我的代码中

随机推荐

  • C# 等待用户在文本框中输入完毕

    C 中是否有一种方法可以等到用户在文本框中完成输入后再获取他们输入的值而不按 Enter 键 稍微修改一下这个问题 好吧 我有一个简单的乘以 2 的计算器 这是我想要它做的事情 用户在文本框中输入一个值 例如 1000 它会自动显示 200
  • R脚本从谷歌分析导入数据

    我正在尝试通过 R studio 服务器上运行的脚本连接到 google analytic s API 我已按照本教程中的步骤操作 http www r bloggers com how to extract google analytic
  • 将 && \ 添加到文本文件中除最后一行之外的每一行

    我正在尝试添加 在文本文件中除最后一行之外的每一行的末尾 输入示例 ps mkdir repo cd repo touch file1 txt 预期输出 ps mkdir repo cd repo touch file1 txt 第一次尝试
  • 如何在使用 QnA 机器人时对其进行训练?

    我使用 bot framework SDK3 和 QnAmaker 服务制作了一个 QnA 机器人 据我所知 我们可以训练我们的知识库 但我不知道如何在团队等其他渠道中使用我的 QnA 机器人时对其进行训练 我想我可以让用户判断机器人的回答
  • subprocess.call() 和 os.system() 之间的速度差异

    执行速度是否有任何差异subprocess call and os system 命令 假设命令本身完全相同 我知道有很多帖子谈论子流程的好处及其原因os system 应该被抛弃 但没有人提到它们的速度 据我了解 子流程远不及包装器os
  • JSON 序列化以元组为键的字典

    Python 有没有办法序列化使用元组作为键的字典 e g a 1 2 a 简单地使用json dumps a 引发此错误 Traceback most recent call last File
  • 将 firestore“integer_value”转换为整数

    使用 Golang Firestore 1 8 库 我尝试使用 Google 去年秋天推出的 Firestore 的新 count 函数 这些文档似乎还没有示例 不是我发现的 但我拼凑了一些有点可行的代码 这些代码几乎让我完成了所有工作 只
  • WPF 拖放

    如何为 WPF 应用程序实现拖放 我可以打开 2 个相同的应用程序并将一个对象从一个应用程序拖动到另一个应用程序 这是我要拖动的内容
  • 按行重塑数据框[重复]

    这个问题在这里已经有答案了 我有一个类似于以下示例的数据框 gt df lt data frame imp c Johny Johny Lisa Max item c 5025 1101 2057 1619 gt df imp item 1
  • 仅最初需要 git 子模块更新?

    我正在掌握 git 子模块 一厢情愿的想法 并且我提出了更具体的问题 这是一个好兆头 我试图找到超级项目引用的子模块的哪个版本 在 gitmodules and git config 但那里没有提到任何内容 这种情况是 我正在更改根位置的子
  • 与 HoloEverywhere 的相对 Gradle 项目依赖性

    我有这个目录结构 Project contrib holo everywhere library addons slider preferences app library app one app two settings gradle 我
  • 保留选定的打印机设置

    我有一个应用程序 它运行一系列预订 并以行程的形式依次打印每个预订并发送给客户 每次运行可能有 30 个左右的预订 因此需要自动化 我们已经交付了它 所有这些都可以与我们的报告软件 DELPHI 的 Report Builder 配合使用
  • 使用 / 分割 C++ 字符串

    我有一个 C 字符串 如下所示 dirname filename ini 我需要在之后得到一切 我怎样才能做到这一点 Using find and substr方法来自std string std string fullpath dirna
  • 模块构建失败(来自 ./node_modules/postcss-loader/src/index.js)

    当我运行命令时 我正在使用角度和节点npm start我收到这个错误 src styles scss 中的错误 node modules css loader dist cjs js ref 13 1 node modules postcs
  • 运算符重载,运算符+与运算符+=

    我正在阅读一些 C 源代码 并且了解了一些语法 path path operator string postPath 我想知道这是否是实际的语法以及为什么 c 不使用已经存在的运算符 而是将值应用于有问题的对象 就像您想确保对象被正确删除一
  • 按对象键过滤对象数组

    我有一个 Javascript 对象数组 var List employee Joe type holiday employee Jerry type seminar employee Joe type shore leave 我想获得两个
  • Rails 的地理定位 API [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 我试图从我的 Rails 应用程序中显示某个位置的地图 我尝试检查 YM4R GM 和 GeoKit 组合 但不确定是否有更好的 Rails 3 的
  • 转换为 64 位 int

    因此 我正在使用 PHP 来转换 Steam Id 这可能是你们很多人都熟悉的 我有以下 Steam ID STEAM 0 1 1514332 现在 我需要将其转换为 64 位版本 这也是社区 ID 浏览 Steams 官方发布后 http
  • 如何在 WPF 中过滤 ListView?

    我有一个绑定到项目集合的 ListView 我不想显示属性 IsDeleted 1 的项目 我怎样才能做到这一点 我将使用 CollectionView 并将 Filter 属性设置为表达式 var view CollectionViewS
  • 如何准确测量具有已知 DPI 的鼠标的鼠标移动(以英寸或厘米为单位)

    我有一个 Logitech G500 游戏鼠标 其全 DPI 为 5700 我正在尝试用 C 编写一个程序 以物理单位准确测量鼠标的水平移动 即 厘米或英寸 我通过 WM INPUT 消息使用 Windows API 和 Windows 原