模拟鼠标点击而不移动光标

J. *_*ann 3 c++ windows winapi function button

我编写了一个应用程序来检测所有活动的 Windows 并将它们放入一个列表中。

有没有办法在不实际移动光标的情况下模拟屏幕上相对于 Windows 位置的某个点的鼠标点击?

我无权访问应该单击的按钮句柄,只能访问窗口的句柄

Rem*_*eau 6

有没有办法在不实际移动光标的情况下模拟屏幕上相对于 Windows 位置的某个点的鼠标点击?

回答您的具体问题 - 否。鼠标单击只能指向单击时鼠标光标实际所在的位置。模拟鼠标输入的正确方法是使用SendInput()(或mouse_event()在旧系统上)。但是这些函数将模拟事件注入到实际鼠标驱动程序发送到的相同输入队列中,因此它们将对鼠标光标产生物理影响 - 即在屏幕上移动它等。

如何在没有 SendInput 的情况下模拟输入?

SendInput 在输入堆栈的底层运行。它只是键盘和鼠标驱动程序用来告诉窗口管理器用户生成输入的相同输入机制的后门。SendInput 函数不知道输入会发生什么。这是由更高级别的窗口管理器处理的,例如点击测试鼠标输入以查看消息最初应该传递到哪个窗口的组件。

当某些东西被添加到队列中时,它需要时间才能从队列的前面出来

当您调用 SendInput 时,您将输入数据包放入系统硬件输入队列。(注意:不是官方术语。这正是我今天所说的。)这与物理设备报告事件时硬件设备驱动程序堆栈使用的输入队列相同。

消息进入硬件输入队列,原始输入线程在那里接收它们。原始输入线程以高优先级运行,因此它可能会非常快地接收它,但是在多核机器上,您的代码可以在第二个核心运行原始输入线程时继续运行。并且原始输入线程在事件出列后需要做一些事情。如果有低级输入钩子,它必须调用这些钩子中的每一个来查看是否有任何一个想要拒绝输入。(而那些钩子可能需要谁知道多长时间才能决定。)只有在所有低级钩子在输入上签字后,原始输入线程才允许修改输入状态并导致 GetAsyncKeyState 报告密钥为下。

执行您所要求的唯一真正方法是找到HWND位于所需屏幕坐标处的 UI 控件的 。然后你可以:

  1. 直接向它发送WM_LBUTTONDOWNWM_LBUTTONUP消息。或者,在标准 Win32 按钮控件的情况下,BM_CLICK改为发送单个消息。

  2. 使用UI 自动化API的AccessibleObjectFromWindow()功能访问控件的界面,然后调用其方法,对于按钮将单击它。IAccessibleaccDoDefaultAction()

话虽如此, ...

我无权访问应该单击的按钮句柄。

您可以访问任何带有HWND. 看看WindowFromPoint(),例如。您可以使用它来查找HWND占据所需屏幕坐标的按钮(当然有警告:WindowFromPoint、ChildWindowFromPoint、RealChildWindowFromPoint,什么时候会全部结束?)。

  • @ColdZer0:如果有支持按钮控件的本机窗口,那就很容易了。通常情况并非如此。Web 浏览器通常不使用本机控件。Qt 应用程序也不行。不过,这两者都支持 UI 自动化。 (2认同)