[英]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 的情况下(假设后面描述的速度缩放是相同的):
应用加速度后,系统会按所需的鼠标速度缩放结果值。 鼠标速度的范围可以从 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.