![](/img/trans.png)
[英]JNA / WinAPI. Simulate mouse click without moving the cursor doesn't work correctly
[英]Simulate mouse click without moving the cursor
我编写了一个应用程序来检测所有活动的 Windows 并将它们放入一个列表中。
有没有办法在不实际移动光标的情况下模拟屏幕上相对于 Windows 位置的某个点的鼠标点击?
我无权访问应该单击的按钮句柄,只能访问窗口的句柄
有没有办法在不实际移动光标的情况下模拟屏幕上相对于 Windows 位置的某个点的鼠标点击?
回答您的具体问题 - 否。 鼠标单击只能指向单击时鼠标光标实际所在的位置。 模拟鼠标输入的正确方法是使用SendInput()
(或旧系统上的mouse_event()
)。 但是这些函数将模拟事件注入到实际鼠标驱动程序发送到的相同输入队列中,因此它们将对鼠标光标产生物理影响 - 即在屏幕上移动它等。
SendInput 在输入堆栈的底层运行。 它只是键盘和鼠标驱动程序用来告诉窗口管理器用户生成输入的相同输入机制的后门。 SendInput 函数不知道输入会发生什么。 这是由更高级别的窗口管理器处理的,例如点击测试鼠标输入以查看消息最初应该传递到哪个窗口的组件。
当您调用 SendInput 时,您将输入数据包放入系统硬件输入队列。 (注意:不是官方术语。这正是我今天所说的。)这与物理设备报告事件时硬件设备驱动程序堆栈使用的输入队列相同。
消息进入硬件输入队列,原始输入线程在那里接收它们。 原始输入线程以高优先级运行,因此它可能会非常快地接收它,但是在多核机器上,您的代码可以在第二个核心运行原始输入线程时继续运行。 并且原始输入线程在事件出列后需要做一些事情。 如果有低级输入钩子,它必须调用这些钩子中的每一个来查看是否有任何一个想要拒绝输入。 (而那些钩子可能需要不知道多长时间才能决定。)只有在所有低级钩子在输入上签字后,原始输入线程才允许修改输入状态并导致 GetAsyncKeyState 报告密钥为下。
做你所要求的唯一真正的方法是找到位于所需屏幕坐标的 UI 控件的HWND
。 然后你可以:
直接向它发送WM_LBUTTONDOWN
和WM_LBUTTONUP
消息。 或者,在标准 Win32 按钮控件的情况下,改为发送单个BM_CLICK
消息。
使用UI 自动化API 的AccessibleObjectFromWindow()
函数访问控件的IAccessible
接口,然后调用其accDoDefaultAction()
方法,对于按钮将单击它。
话虽如此, ...
我无权访问应该单击的按钮句柄。
您可以访问任何具有HWND
。 例如,看看WindowFromPoint()
。 您可以使用它来查找占据所需屏幕坐标的按钮的HWND
(当然有警告: WindowFromPoint、ChildWindowFromPoint、RealChildWindowFromPoint,什么时候会全部结束? )。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.