将击键发送到特定窗口(在后台),但同时执行其他操作 [英] Send keystrokes to a specific window (in background), but do something else in the meantime

查看:20
本文介绍了将击键发送到特定窗口(在后台),但同时执行其他操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此代码(灵感来自 在 Python 上模拟键盘和鼠标的最简单方法是什么?)打开记事本并每秒发送 A、B、C、D、...、Z 键:

This code (inspired from Which is the easiest way to simulate keyboard and mouse on Python?) opens a Notepad and send the keys A, B, C, D, ..., Z every second:

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)

我想让这个操作在后台继续,继续我在电脑上的工作,并将按键发送到记事本(在后台).

I would like to let this operation continue in background, continue my work on the computer, and have the keystrokes sent to Notepad (in background).

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

Problem: if I open another application (example: browser) in the meantime, the keystrokes are sent ... to the currently active window, which I dont't want!

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

Question: how to have Python send the keystrokes to notepad.exe only, even if this application is not in foreground?

上下文:我正在自动化一些需要我的 Python 脚本在大约 15 分钟内将击键发送到 app.exe(在后台)的长任务,但我想用同时使用电脑.

Context: I'm automating some long task requiring that my Python script sends keystrokes to app.exe (in background) during maybe 15 minutes, but I'd like to do something else with the computer in the meantime.

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

Note: More generally, the use case I'm interested in is the case where the process app.exe might open dialogs, close dialogs, open other windows, so the solution should be able to send the keystrokes to the active window of the process. Thus a solution with a fixed hWnd like here doesn't work directly.

推荐答案

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

In order to send Keystroke to any application window, without activating the application to get input focus. We must get the windows handler first. This requires Windows API FindWindow and FindWindowsEx. First, the handle of Top Level window of application is obtained by FindWindow. Then use FindWindowsEx to get the handle of the child window or control to receive keys. Because the top window of the application is not always the window that accepts Keystroke (such as notepad.exe, the window that actually accepts Keystroke is the Edit control under the main window of Notepad), it can be found by ClassID or Caption.

假设已经得到了目标窗口的句柄(hwnd),关键消息将通过PostMessage发送给窗口.

Assuming that the handle of the target window has been got(hwnd), the key message will be sent to the window with PostMessage.

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

For normal character keys, it is simplest to use WM_CHAR message directly, as follows:

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

对于非正常字符键,如功能键、方向键等,WM_KEYDOWNWM_KEYUP消息应按如下方式使用:

For un-normal character keys, such as function keys, direction keys, etc., WM_KEYDOWN and WM_KEYUP messages should be used as follows:

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.

The details for last parameter (lParam) you can reference to msdn.

对于Shift/Ctrl"键,示例:

For the keys "Shift/Ctrl", sample:

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 消息.示例:

For the keys "Alt", It belongs to the system button, using WM_SYSKEYDOWN/WM_SYSKEYUP message. sample:

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

0x20000000 表示上下文代码,如果Alt"不存在,则值为 1.键已按下.

0x20000000 means context code, the value is 1 if the "Alt" key is down.

这篇关于将击键发送到特定窗口(在后台),但同时执行其他操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆