2

私はPythonの経験が非常に浅いと言ってこれを前置きします。それが私の問題の解決策が簡単であることを意味することを願っています.

私のプログラムは別のウィンドウで単純なアクションを実行するので、理想的には、残りのコマンドに進む前に、スクリプトでこの別のウィンドウが最大化されてアクティブになっていることを確認したいと思います。これは、私が予想していたよりもはるかに困難であることが判明しました。

find_window を使用してフォアグラウンドに設定する win32gui でこれを達成できると確信しています。この前の質問に出くわしたとき、私は自分の解決策を見つけたと思いました: Python Window Activation

残念ながら、いくつかの理由により、ソリューション コードを使用したり、それを操作して問題を解決したりすることができませんでした。

-ユーザーがfind_windowを定義した方法では、ウィンドウのクラス名でしか選択できません。これは、Javaで実行されているゲームであるため、わかりません。また、見つけることができませんでした。「デフォルトの引数」ではないため、その行を特定のウィンドウ名(私が知っている)で機能するように変更することはできなかったようです。

-どのように機能するかわからないため、ウィンドウを列挙して見つけたくありません。

-そのスクリプトに書かれているようにfind_window_wildcardを使用すると、ウィンドウを数回前面に表示することができましたが、ウィンドウがすでに開いている場合に限り、断続的にしか機能しません。

-set_foreground() は 1 つの入力ステートメントを必要とし、どのように設定しようとしても、要素の数が間違っているか、ウィンドウに無効なハンドルがあるというエラーが常に表示されます。

私は自分が愚かであることを知っています。しかし、この問題に対する明確で簡潔な解決策、または少なくとも find_window/getwindow 構文の適切な説明は、私自身とこの問題を抱えている他の人にとって天の恵みです。

4

2 に答える 2

4

Swapypywinautoのページをご覧になることを強くお勧めします。UI オートメーションに関しては、いくつかの素晴らしいことを行うのに役立ちます。

于 2013-03-15T00:17:35.047 に答える
1

ユーザーが find_window を定義した方法では、ウィンドウのクラス名でのみ選択できます

ユーザーが定義した方法は、2 つのパラメーターclass_namewindow_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…ウィンドウごとに 1 回、関数を呼び出します。ウィンドウは (たとえば、などの関数にhwnd渡すことができます)、渡した値と同じです。(何も渡す必要がない場合は、コールバック関数の値で何もしないでください。ただし、他の回答者がそれを使用して正規表現を渡す方法を見ることができます。)win32guiGetWindowTextcookiesome_cookieNone

その間:

そのスクリプトに書かれているように使用find_window_wildcardすると、ウィンドウを数回前面に表示することができましたが、ウィンドウが既に開いている場合に限り、断続的にしか機能しません。

まず、ウィンドウが存在しない場合、そのウィンドウを最前面に表示することはできません。それがどのように機能すると思いますか?

断続的に動作する限り、私の推測では、ワイルドカードに一致するウィンドウがたくさんあり、プログラムはそのうちの 1 つを恣意的に選択します。それはあなたが望むものではないかもしれません。(非表示のウィンドウか何かである可能性もあるため、何も起こらないことがわかります。)

とにかく、使用する必要はありませんfind_window_wildcard; 正確な名前がわかっている場合は、それを使用してください。もちろん、それはまだ一意ではないかもしれません (ゲームの名前が何であれ、同じタイトルの電子メール メッセージやメモ帳ウィンドウを開くことを妨げるものは何もありません...ちなみに、最初にクラス名を試してみたいのはそのためです)。ただし、少なくとも指定されていないワイルドカードよりも一意である可能性が高くなります。

では、クラス名が一意ではなく (さらに悪いことに、一般的なダイアログ ウィンドウの #32770 のような特別な「番号」クラスの 1 つ)、かつウィンドウ名も一意でない場合はどうなるでしょうか? たとえば、所有しているプロセスまたはモジュール (exe/dll)、または親ウィンドウなどを調べることで、物事をもう少し絞り込むことができる場合があります。win32guiウィンドウを一意に指定する方法が見つかるまで、および/または MSDN のドキュメント (上記のリンク) を調べて、試行錯誤を繰り返して試行錯誤する必要があります (Spy ツールも思い出してください)。次に、それをコーディングします。

于 2013-03-15T00:04:59.157 に答える