如何将键盘事件发送到 Pywin32 中的不同窗口?
Posted
技术标签:
【中文标题】如何将键盘事件发送到 Pywin32 中的不同窗口?【英文标题】:How to send a keyboard event to a different Window in Pywin32? 【发布时间】:2013-01-28 08:31:35 【问题描述】:我必须编写一个脚本来在后台的不同程序中模拟一些键盘事件。这是我的代码:
pwin = win32ui.FindWindow(None,r'someprograme')
pwin.SendMessage(win32con.WM_KEYDOWN,18)
pwin.SendMessage(win32con.WM_KEYDOWN,68)
pwin.SendMessage(win32con.WM_KEYUP,18)
pwin.SendMessage(win32con.WM_KEYUP,68)
pwin.SendMessage(win32con.WM_KEYDOWN,13)
pwin.SendMessage(win32con.WM_KEYUP,13)
但似乎什么也没发生。那我该怎么办?我试过 PostMessage func 似乎仍然无法做到。
【问题讨论】:
首先,您确定pwin
是正确的窗口吗?其次,它有键盘焦点吗?第三,你为什么不通过两个参数? (我还没有检查文档;也许 0 总是适合 lparam?)最后,那些键是什么? (你知道WM_KEYDOWN
不能用于ALT
的大多数用途,对吧?)
另外,您要驱动什么应用程序?
看来我没有找到正确的窗口。我想向程序发送 ALT+D 以打开某事。那么如果 WM_KEYDOWN 不能使用,我怎么发送呢?
对于您的第一点:如果您没有合适的窗口,其他的东西都不重要;你显然必须先找到正确的窗口,否则你甚至无法测试。
第二个:为什么要向程序发送Alt+D?你想打开什么?通常这会弹出菜单栏中的第一个菜单,名称中带有下划线“D”。那是你想要做的吗?如果是这样,请参阅我的回答,其中我解释了为什么它在许多应用程序中不起作用,以及该怎么做。
【参考方案1】:
快速浏览一下WM_KEYDOWN docs:
当按下非系统键时,以键盘焦点发布到窗口。非系统键是在未按下 ALT 键时按下的键。
但是查找your keycodes,您正在尝试发送 ALT-D(后跟 ENTER,这很好)。听起来您正在尝试驱动菜单;如果这就是你想要做的,WM_KEYDOWN
不是这样做的方法。
问题在于键盘菜单导航是由 Windows 驱动的,而不是由应用程序驱动的(少数应用程序会覆盖正常的菜单处理,例如某些版本的 Visual Studio)。当您查看记事本并按 ALT-F 打开“文件”菜单时,记事本代码会收到一堆与菜单相关的消息(WM_INITMENU
等),而不是按键。
如果您使用 WM spy 程序(我认为免费的 Visual Studio Express 仍然带有 Spy++ 和 ManagedSpy,但如果没有,请搜索等效程序),您可以在使用键盘,然后你可以弄清楚如何从你的 Python 脚本中模拟它。
除此之外,根据程序的编写方式,它可能在没有焦点时不接受击键。
顺便说一句,如果您刚刚开始使用 Windows GUI 自动化,您可能希望查看更高级别的内容,例如 pywinauto
。这样,您不必计算要发送哪些与菜单相关的消息来打开“数据”菜单;您只需执行app.Foo.MenuSelect('Data')
之类的操作即可。
【讨论】:
谢谢,我已经使用 pywinauto 完成了任务。当使用 sendkeys 而不是 keyevent 时,它可以工作以上是关于如何将键盘事件发送到 Pywin32 中的不同窗口?的主要内容,如果未能解决你的问题,请参考以下文章
如何自动化 UI 键盘输入? pywin32 PostMessage vs Powershell SendKeys
如何使用 pywin32 在 Python 中获取特定应用程序窗口的句柄?
Pywinauto常用02--pywin32(Python调用win api)