c++ - 在不移动光标的情况下模拟鼠标点击

标签 c++ windows function winapi button

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

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

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

最佳答案

Is there a way to simulate a mouseclick on a spot on the screen relative to the Windows location without actually moving the cursor?

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

How do I simulate input without SendInput?

SendInput operates at the bottom level of the input stack. It is just a backdoor into the same input mechanism that the keyboard and mouse drivers use to tell the window manager that the user has generated input. The SendInput function doesn't know what will happen to the input. That is handled by much higher levels of the window manager, like the components which hit-test mouse input to see which window the message should initially be delivered to.

When something gets added to a queue, it takes time for it to come out the front of the queue

When you call Send­Input, you're putting input packets into the system hardware input queue. (Note: Not the official term. That's just what I'm calling it today.) This is the same input queue that the hardware device driver stack uses when physical devices report events.

The message goes into the hardware input queue, where the Raw Input Thread picks them up. The Raw Input Thread runs at high priority, so it's probably going to pick it up really quickly, but on a multi-core machine, your code can keep running while the second core runs the Raw Input Thread. And the Raw Input thread has some stuff it needs to do once it dequeues the event. If there are low-level input hooks, it has to call each of those hooks to see if any of them want to reject the input. (And those hooks can take who-knows-how-long to decide.) Only after all the low-level hooks sign off on the input is the Raw Input Thread allowed to modify the input state and cause Get­Async­Key­State to report that the key is down.

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

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

  2. 使用AccessibleObjectFromWindow() API的UI Automation函数访问控件的IAccessible接口(interface),然后调用它的accDoDefaultAction()方法,对于一个按钮会点击它。

也就是说,...

I don't have access to the buttons handle that is supposed to be clicked.

您可以访问任何具有HWND 的内容。例如,看看 WindowFromPoint() 。您可以使用它来查找占据所需屏幕坐标的按钮的 HWND(当然要注意:WindowFromPoint, ChildWindowFromPoint, RealChildWindowFromPoint, when will it all end?)。

关于c++ - 在不移动光标的情况下模拟鼠标点击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34846165/

相关文章:

c - 在 Windows/mingw 上,什么是 `fcntl(fd, F_GETFL) | O_ACCMODE` 的等价物?

python - 如何在pygame中创建冷却功能?

c++ - 不使用 cv::imdecode() 从多个 JPEG 编码图像创建 MJEPG 视频

c++ - Visual Studio 2015 Update 2 RC 中的 regex_token_iterator 问题

c++ - 如何编写 bison 文件以自动使用 C 头文件中定义的 token 枚举列表?

python - 在带有 Python 的 Windows 上使用符号链接(symbolic link)模块

c++ - 为什么 TrimRight 从字符串的开头搜索?

c++ - 不要在发布时显示控制台窗口但在调试时显示

c++ - 函数指针在带参数的对象中使用函数

javascript - 如何使用对象组织 JS 函数