0

我想在后台窗口中使用键盘和鼠标(窗口是 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”,鼠标点击成功。但我移动鼠标失败。

4

2 回答 2

2

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

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

于 2013-09-21T07:51:42.067 回答
0

WM_MOUSEMOVE不管它是否是前台窗口,都会为鼠标光标下方的窗口生成消息。WM_MOUSEMOVE(likeWM_TIMERWM_PAINT)消息不会发布到线程的消息队列中。当线程的消息队列为空并且线程调用GetMessage. 如果一个窗口似乎没有接收到WM_MOUSEMOVE消息,那可能是因为消息队列从未完全耗尽。

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

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

重定向键盘输入涉及使用SetWindowsHookEx安装键盘钩子低级键盘钩子来拦截输入。必须记录输入并随后将其发送到所需的目标。这不受操作系统支持,并且会以或多或少的微妙方式失败(例如,请参阅Replaying input is not the same as reprocessing it)。系统控制的内部状态也将不同步,并且类似的函数GetAsyncKeyState将返回不匹配的结果。

于 2013-09-21T09:55:54.947 回答