2

我首先要说我对 python 非常缺乏经验,我希望这意味着我的问题的解决方案会很简单。

我的程序将在另一个窗口中执行简单的操作,因此理想情况下,我希望我的脚本在继续执行其余命令之前确保该另一个窗口已最大化并处于活动状态。事实证明,这比我预想的要困难得多。

我相当确定我可以通过 win32gui 使用 find_window 并将其设置为前台来实现这一点。当我遇到上一个问题时,我以为我已经找到了解决方案: Python Window Activation

不幸的是,由于以下几个原因,我无法使用解决方案代码或操纵它来解决我的问题:

- 用户定义 find_window 的方式只允许您通过窗口的类名进行选择,我不知道也无法找到,因为它只是一个在 Java 中运行的游戏。我似乎无法更改该行以适用于特定的窗口名称(我知道),因为它不是“默认参数”。

- 我不想枚举窗口来找到它,因为我不确定它是如何工作的。

- 使用在该脚本中编写的 find_window_wildcard 已经成功地将窗口带到前台几次,但前提是窗口已经打开,并且它只能间歇性地工作。

-set_foreground() 需要一个输入语句,无论我如何尝试设置它,我总是会收到一个错误,即我的元素数量错误或窗口上的句柄无效。

我知道我很愚蠢;但是对这个问题的一个清晰简洁的解决方案,或者至少对 find_window/getwindow 语法的一个很好的解释,对于我自己和遇到这个问题的任何人来说都是天赐之物。

4

2 回答 2

4

强烈建议您查看Swapypywinauto的页面。当涉及到 UI 自动化时,它们可以帮助您做一些很棒的事情。

于 2013-03-15T00:17:35.047 回答
1

用户定义 find_window 的方式只允许您通过窗口的类名进行选择

用户定义它的方式是传递两个参数class_name,并且window_name不加改动地传递给win32gui.FindWindow(它反过来只是调用 Win32 API 函数FindWindow)。所以,只需这样做:

windowmgr.find_window(None, 'My Window Name')

但即使那不是真的,你也不需要使用他的find_window功能;如何称呼win32gui.FindWindow自己应该很明显:

hwnd = win32gui.FindWindow(None, 'My Window Name')

如果你想对FindWindow/ EnumWindows/etc 有一个很好的解释。语法,您是否尝试查看他们的文档?那里有什么你不明白的吗?

同时:

…窗口的类名,我不知道也找不到,因为它只是一个用Java运行的游戏

它在 Java 中运行有什么不同?您可以枚举窗口并打印出它们的类名,无论它们是用 C++、Java、.NET、Python 还是其他任何语言编写的。或者使用 Visual Studio/VS Express 附带的工具之一,或者您可以在网上找到的任何免费改进版本,例如MS Spy++,它可以让您指向一个窗口并为您提供标题和类名.

我不想枚举窗口来找到它,因为我不确定它是如何工作的。

只需windowmgr.find_window_wildcard(wildcard)使用正则表达式调用,它就会枚举窗口并将它们的标题与该正则表达式进行比较。

如果您想编写自己的代码来执行此操作,只需编写如下函数:

def my_callback(hwnd, cookie):

现在,当你这样做时:

win32gui.EnumWindows(my_callback, some_cookie)

…它会在my_callback每个窗口调用一次你的函数,hwnd作为窗口(你可以传递给win32gui函数,例如,GetWindowText),并且cookie是你传入的相同some_cookie值。(如果你不需要传入任何东西,只需传递None,并且不要对回调函数中的值做任何事情。但是您可以看到其他应答器如何使用它来传递正则表达式。)

同时:

使用find_window_wildcard该脚本中编写的方法已成功将窗口置于前台几次,但前提是窗口已经打开,并且只能间歇性地工作。

首先,如果窗口不存在,则不能将其置于前台。你希望它如何工作?

就间歇性工作而言,我的猜测是有很多窗口与您的通配符匹配,程序将任意选择其中一个。它可能不是你想要的。(它甚至可能是一个隐藏的窗口或其他东西,所以你根本看不到任何事情发生。)

无论如何,您不需要使用find_window_wildcard; 如果您知道确切的名称,请使用它。当然,它仍然可能不是唯一的(无论游戏的名称是什么,都没有什么能阻止您打开具有相同标题的电子邮件或记事本窗口……顺便说一句,这就是您想先尝试类名的原因),但至少它比一些未指定的通配符更可能是唯一的。

那么,如果类名不是唯一的(或者,更糟糕的是,它是特殊的“数字”类之一,例如通用对话框窗口的#32770),并且窗口名也不是唯一的怎么办?您可以通过查看拥有的进程或模块(exe/dll)或父窗口或其他任何东西来更好地缩小范围。您必须查看win32gui和/或 MSDN 文档(上面链接)以寻找可能要尝试的东西,并通过反复试验(也请记住 Spy 工具),直到找到某种方法来唯一地指定窗口。然后编码。

于 2013-03-15T00:04:59.157 回答