我们需要使用 InjectTouchInput 函数
contacts 应该是“触摸点”的意思,官网翻译成了“联系人”,所以下面给出正确的翻译。
InjectTouchInput 函数 (winuser.h)
模拟触摸输入。
- 注:
InitializeTouchInjection
必须在InjectTouchInput
的任何调用之前。
语法
1 | BOOL InjectTouchInput( |
参数
[in] count
触摸点数组的大小。
count 的最大值由 InitializeTouchInjection 函数的 maxCount 参数指定。
[in] contacts
表示桌面上所有触摸点的 POINTER_TOUCH_INFO 结构的数组。 每个触摸点的屏幕坐标必须在桌面的边界内。
返回值
如果函数成功,则返回值不为零。
如果函数失败,则返回值为零。要获得更多的错误信息,请调用 GetLastError。
注解
注入的输入将发送到运行注入进程的会话的桌面。
触摸输入注入有两种输入状态(交互和悬停)由触点中的以下 pointerFlags 组合指示:
pointerFlags (POINTER_FLAG_*) | 状态 |
---|---|
INRANGE | UPDATE | 悬停开始或移动 |
INRANGE | INCONTACT | DOWN | 触摸状态开始 |
INRANGE | INCONTACT | UPDATE | 触摸点移动 |
INRANGE | UP | 将触摸转换为悬停 |
UPDATE | 悬停结束 |
UP | 触摸结束 |
- 注:互动状态代表屏幕上的触摸点可以与任何支持触摸功能的应用程序进行交互。悬停状态表示触摸输入未与屏幕接触,不能与应用程序交互。触摸注入可以在悬停或交互状态下开始,但状态转换只能使用
INRANGE | INCONTACT | DOWN
(悬停状态转换为交互状态)或INRANGE | UP
(交互状态转换为悬停状态)。
所有触摸注入序列都以 UPDATE 或 UP 结尾。
下图演示了一个以悬停状态开始、过渡到交互状态并以悬停状态结束的触摸注入序列。
对于长按手势,必须发送多个帧以确保输入不会被取消。对于在点(x,y)处的长按,在点(x,y)处发送 WM_POINTERDOWN,然后在点(x,y)处发送 WM_POINTERUPDATE 信息。
监听 WM_DISPLAYCHANGE,以处理显示分辨率和方向的变化,并管理屏幕坐标更新。收到 WM_DISPLAYCHANGE 消息时,所有活动触摸点都会被取消。
通过设置 POINTER_FLAG_UP 或 POINTER_FLAG_UPDATE 取消单个触摸点。在没有 POINTER_FLAG_UP 或 POINTER_FLAG_UPDATE 的情况下取消触摸注入会使注入无效。
当设置 POINTER_FLAG_UP 时,POINTER_INFO 的 ptPixelLocation 应与上一触摸注入帧的 POINTER_FLAG_UPDATE 值相同。否则,注入失败,显示 ERROR_INVALID_PARAMETER,并取消所有激活的注入触摸点。系统在取消注入时会修改 WM_POINTERUP 事件的 ptPixelLocation。
输入时间戳可在 POINTER_INFO 的 dwTime 或 PerformanceCount 字段中指定。该值不能比注入线程当前的 tick 计数或 QueryPerformanceCounter 值更近。一旦帧注入了时间戳,所有后续帧都必须包含时间戳,直到帧中的所有触摸点进入 UP 状态。必须为触摸点数组中的第一个元素提供自定义时间戳值。第一个元素之后的时间戳值将被忽略。自定义时间戳值必须在每个注入帧中递增。
如果指定了 PerformanceCount 字段,在实际注入时,时间戳会以 0.1 毫秒的分辨率转换为当前时间。如果自定义 PerformanceCount 的结果与上次注入的 0.1 毫秒窗口相同,API 将返回错误 (ERROR_NOT_READY),并且不会注入数据。虽然错误不会立即导致注入无效,但下次成功注入的 PerformanceCount 值必须与上次成功注入的 PerformanceCount 值至少相差 0.1 毫秒。同样,如果使用了自定义的 dwTime 值,该值必须至少间隔 1 毫秒。
如果在注入参数中同时指定了 dwTime 和 PerformanceCount,InjectTouchInput 将失败并显示错误代码 (ERROR_INVALID_PARAMETER)。一旦注入应用程序使用 dwTime 或 PerformanceCount 参数启动,时间戳字段必须正确填写。注入序列开始后,注入不能将自定义时间戳字段从一个切换到另一个。
如果没有指定 dwTime 或 PerformanceCount 值,InjectTouchInput 将根据 API 调用的时间分配时间戳。如果调用时间间隔小于 0.1 毫秒,API 可能会返回错误 (ERROR_NOT_READY)。该错误不会立即导致输入无效,但注入应用程序需要再次重试同一帧,以确保注入成功。