如何在后台窗口中移动鼠标

How to move mouse in background window?

本文关键字:移动 鼠标 窗口 后台      更新时间:2023-10-16

我想在后台窗口中使用键盘和鼠标(窗口是dx窗口)。

HWND myhwnd = GetForegroundWindow();
PostMessage(myhwnd, WM_KEYDOWN, 0x33, 0); //press "3"
PostMessage(myhwnd, WM_KEYUP, 0x33, 0);
LPARAM lParam = MAKELPARAM(300,100);
PostMessage(myhwnd, WM_MOUSEMOVE, 0,lParam); // mouse move
PostMessage(myhwnd, WM_RBUTTONDOWN, 0,lParam); // mouse click
PostMessage(myhwnd, WM_RBUTTONUP, 0, lParam);

按"3",鼠标点击成功。但是我移动鼠标失败了。

移动鼠标会导致窗口将消息发布到拥有鼠标光标正下方窗口的线程的输入队列(除非使用 SetCapture 捕获鼠标)。但是发布消息不会导致鼠标移动。您可能必须使用 SendInput Windows API 来实现硬件输入的模拟。由于鼠标输入与鼠标光标正下方的窗口相关联的方式,您可能必须将窗口置于前面,然后调用 SendInput。键盘输入模拟只会转到前台的窗口。键盘输入也可以使用SendInput进行模拟。

但通常由于像 EDIT 和其他窗口控件处理键盘消息的方式 - 例如在它们WM_KEYDOWN时将闪烁的光标向下移动一个字符 - 您通常可以通过手动发布消息来短路它们。这种短路通常不适用于鼠标消息,因为窗口在接收 10,20 的WM_MOUSEMOVE时不会将鼠标移动到位置 10,20,而是期望鼠标处于该位置。还有许多其他这样的原因使帖子消息方法不适用于鼠标输入。

WM_MOUSEMOVE都会

为鼠标光标下方的窗口生成消息,无论它是否是前台窗口。 WM_MOUSEMOVE(如 WM_TIMERWM_PAINT )消息不会发布到线程的消息队列中。当线程的消息队列为空并且线程调用 GetMessage 时,它们会动态生成。如果窗口似乎没有接收WM_MOUSEMOVE消息,则可能是因为消息队列从未完全耗尽。

重定向键盘输入是一个非常奇怪的概念。用户希望键盘输入转到前台窗口。实际上,前台窗口定义为:

用户当前正在使用的窗口。

重定向键盘输入涉及使用 SetWindowsHookEx 拦截输入以安装键盘挂钩或低级键盘挂钩。必须记录输入,然后发送到所需的目标。操作系统不支持此功能,并且会以或多或少微妙的方式失败(例如,请参阅重播输入与重新处理输入不同)。系统控制的内部状态也将不同步,GetAsyncKeyState等函数将返回不匹配的结果。