繁体   English   中英

SendInput() 鼠标移动计算?

[英]SendInput() mouse movement calculation?

我正在使用SendInput()来移动鼠标,它需要INPUT结构。 我正在使用相对运动,在关于这个结构的文档中,在备注中它说:

相对鼠标运动受鼠标速度和两鼠标阈值的影响。

所以我的问题是,这是什么以及如何计算的(公式是什么)? 未指定。

我尝试搜索它,但没有运气。 希望有人知道。

我需要这些信息,因为我试图使鼠标移动独立于实际的 Windows 光标速度。 在文档中,它清楚地表明这受这些值的影响。

  • 相对价值

相对鼠标运动受鼠标速度和两鼠标阈值的影响。 所以我的问题是,这是什么以及如何计算的(公式是什么)? 未指定。

如何计算在MOUSEINPUT结构文件的备注中说明如下:

系统对指定的相对鼠标移动应用两个测试。 如果沿 x 或 y 轴的指定距离大于第一个鼠标阈值,并且鼠标速度不为零,则系统将距离加倍。 如果沿 x 或 y 轴的指定距离大于第二个鼠标阈值,并且鼠标速度等于 2,则系统将应用第一个阈值测试产生的距离加倍。 因此,系统可以将指定的沿 x 或 y 轴的相对鼠标移动最多乘以四倍。

为防止系统将距离加倍或将指定的鼠标沿 x 或 y 轴的相对移动最多乘以四倍,例如,您可以保持指定的鼠标相对移动小于或等于第一个鼠标阈值,并设置鼠标速度归零。 请测试看看这是否符合您的要求。

至于 UIPI 限制,由于您的应用程序已经以管理员权限运行,因此它具有较高的强制级别,因此除非您的目标应用程序以系统完整性级别运行,否则这不会成为问题。

  • 绝对值

并且不受 UIPI 限制,也可以使用不受鼠标速度和两鼠标阈值影响的绝对值

mouse_event函数的文档中:

鼠标相对运动受鼠标速度和加速度级别的设置影响。 最终用户使用控制面板中的鼠标应用程序设置这些值。 应用程序使用SystemParametersInfo函数获取和设置这些值。

我相信这些是指以下两个查询:

  • SPI_GETMOUSE ( = 0x0003 ),

    检索两个鼠标阈值和鼠标加速度。 pvParam参数必须指向接收这些值的三个整数的数组。

    这三个值是第一阈值、第二阈值和加速度。

  • SPI_GETMOUSESPEED ( = 0x0070 ),

    检索当前鼠标速度。 鼠标速度根据鼠标移动的距离确定指针移动的距离。 pvParam参数必须指向一个整数,该整数接收一个介于 1(最慢)和 20(最快)之间的值。 默认值为 10。

    这似乎遵循一个有点奇怪的公式来缩放运动。

系统在应用加速度时对指定的相对鼠标运动应用两个测试。 如果沿 x 或 y 轴的指定距离大于第一个鼠标阈值,并且鼠标加速级别不为零,则操作系统将距离加倍。 如果沿 x 轴或 y 轴的指定距离大于第二个鼠标阈值,并且鼠标加速度级别等于 2,则操作系统将应用第一个阈值测试产生的距离加倍。 因此,操作系统可以将沿 x 轴或 y 轴的相对指定的鼠标移动最多乘以四倍。

不幸的是,我无法破解这个问题(它适用于在“鼠标属性”中启用“增强指针精度”时)。 它绝对不似乎只是使价值翻倍。

对于三倍于阈值的值,缩放似乎是准确的(它会使您的输入加倍),但除此之外,因子 2 会不断增长。 这些是用 10 的鼠标速度测试的:

  • 对于您的输入 20,最终行驶距离为 40。
  • 对于 40,最终距离是 93 而不是 80(约高 1.16)。
  • 对于 80,最终距离是 201 而不是 160(约高 1.25)。
  • 对于 160,最终距离是 416 而不是 320(约高 1.30)。
  • 对于 320,最终距离是 846 而不是 640(约高 1.32)。
  • 对于更高的值,实际/预期的比率几乎不会增长。

更糟糕的是,在速度为 20 的情况下(假设后面描述的速度缩放是相同的):

  • 对于您输入的 20,最终行驶距离为 66。
  • 对于 40,最终距离是 173 而不是 280(约低 0.62)。
  • 对于 80,最终距离是 388 而不是 560(约低 0.69)。
  • 对于 160,最终距离是 416 而不是 320(约低 0.73)。
  • 对于 320,最终距离是 1677 而不是 2240(约高 0.75)。
  • 对于更高的值,我的显示器不够大。

应用加速度后,系统会按所需的鼠标速度缩放结果值。 鼠标速度的范围可以从 1(最慢)到 20(最快),并表示指针根据鼠标移动的距离移动了多少。 默认值为 10,不会对鼠标移动进行额外修改。

从我的测试来看,10 表示没有缩放(比例为 1)。 每个高于 10 的值似乎都会将比例因子增加 1/4,而低于 10 的每个值都会将比例因子减少 1/8(除了值 2 会达到 0,因此比例为 1/16,并且以 1 个单位缩放似乎是 0/32)。 如果禁用“增强指针精度”,以下算法 (Python) 会预测鼠标的结束位置:

import ctypes

speed = ctypes.c_int()
ctypes.windll.user32.SystemParametersInfoA(0x0070, 0, ctypes.byref(speed), 0)  # SPI_GETMOUSESPEED
speed = out.value

# x is how much you want to move the mouse in the x axis (the same is true for the y axis)

if speed == 1:
    predict_x = x // 32
elif speed == 2:
    predict_x = x // 16
elif speed <= 10:
    predict_x = (x * (speed - 2)) // 8
else:
    predict_x = (x * (speed - 6)) // 4

如果您想精确移动鼠标x ,则需要反向代码:

if speed == 1:
    used_x = x * 32
elif speed == 2:
    used_x = x * 16
elif speed <= 10:
    used_x = int(round((x * 8) / (speed - 2)))
else:
    used_x = int(round((x * 4) / (speed - 6)))

我的结论是使用相对移动来进行精确的鼠标移动是不值得的。 您最好查询当前位置,添加增量并设置绝对位置。 否则,您必须查询可以随时更改的鼠标配置,并且旨在让您感觉良好,而不是在单个动作中精确。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM