将击键发送到特定窗口(在后台),但与此同时进行其他操作[重复]


问题内容

这个问题已经在这里有了答案

使用python将一些键发送到非活动窗口 (2个答案)

去年关闭。

这段代码(启发自哪一种是在Python上模拟键盘和鼠标的最简单方法?)打开记事本并每秒发送键A,B,C,D,…,Z:

import win32com.client, time
shell = win32com.client.Dispatch("WScript.Shell")
shell.Run('Notepad')
time.sleep(1)
shell.AppActivate("Notepad")
for i in range(65,91):
    shell.SendKeys(chr(i))
    time.sleep(1)

我想让此操作在后台继续,在计算机上继续我的工作, 并将击键发送到记事本(在后台)

问题:如果同时打开另一个应用程序(例如浏览器),则击键会发送到当前不活动的窗口中!

问题: 即使此应用程序不在前台,如何让Python 将击键发送到notepad.exe ?

上下文:我正在自动化一些繁琐的任务,要求我的Python脚本app.exe在大约15分钟内将击键发送到(后台),但与此同时,我想对计算机执行其他操作。

注意:更一般而言,我感兴趣的用例是流程app.exe可能会打开对话框,关闭对话框,打开其他窗口的情况,因此解决方案应该能够将击键发送到 流程
活动窗口 。因此,像此处这样的具有固定hWnd的解决方案无法直接使用。


问题答案:

为了将击键发送到任何应用程序窗口,而无需激活应用程序以获取输入焦点。我们必须先获取Windows处理程序。这需要Windows
APIFindWindowFindWindowsEx。首先,通过获得顶级窗口的句柄FindWindow。然后使用FindWindowsEx获取子窗口的句柄或控件以接收键。因为应用程序的顶部窗口并不总是接受按键的窗口(例如notepad.exe,实际上接受按键的窗口是记事本主窗口下的Edit控件),所以可以通过ClassID或Caption找到它。

假设已获取目标窗口的句柄(hwnd),则将使用将该关键消息发送到窗口PostMessage

对于普通的字符键,直接使用WM_CHAR消息是最简单的,如下所示:

PostMessage(hwnd, WM_CHAR, 'a', 0);

对于未正常字符键,诸如功能键,方向键等,WM_KEYDOWN并且WM_KEYUP消息应使用如下:

VirtualKey = MapVirtualKeyA(VK_RIGHT, 0);
PostMessage(hwnd, WM_KEYDOWN, VK_RIGHT, 0x0001|VirtualKey>>16);
PostMessage(hwnd, WM_KEYUP, VK_RIGHT, 0x0001|VirtualKey>>16|0xC0>>24);

lParam您可以参考msdn的最后一个参数()的详细信息。

对于键“ Shift / Ctrl”,示例:

keybd_event(VK_SHIFT, 0, 0, 0);
PostMessage(hwnd, WM_KEYDOWN, 0x41, 0x001E0001);
PostMessage(hwnd, WM_KEYUP, 0x41, 0xC01E0001);
keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);

对于按键“ Alt”,使用WM_SYSKEYDOWN/WM_SYSKEYUP消息属于系统按钮。样品:

PostMessage(hwnd, WM_SYSKEYDOWN, VK_F4, 0x003E0001 |0x20000000);
PostMessage(hwnd, WM_SYSKEYUP, VK_F4, 0xC03E0001 | 0x20000000);

0x20000000 表示上下文代码,如果按下“ Alt”键,则值为1。