みなさん、はじめまして。
早速ですが、質問させて下さい。
タイトルにあることをVC++ 2008で行いたいのですが、妥当な方法がわかりません。
現在、
----------------------------------------
1)CreateProcess をコール
2)EnumWindows でウィンドウを列挙
3)列挙したウィンドウのハンドルからプロセスIDを取得して、1で得たプロセスIDと同じか比較
4)3で同じだったら、SetWindowsPos で中央に配置
----------------------------------------
としてますが、これだと3で該当するウィンドウが列挙されません。
1と2の間で WaitoForSingleObject や WaitForInputIdle をコールして1秒くらい止めると成功します。
ただし、「1秒」は根拠の無い数値なので、例えば表示状態を見るなどした方が良いと思うのですが、その方法がわかりません。
そして何より、上記の方法は妥当なやり方なのでしょうか?
ご意見頂けないでしょうか?
よろしくお願いします。
> これだと3で該当するウィンドウが列挙されません
恐らく、起動されたプロセスで”ウィンドウ”が作成完了される前に EnumWindows() が実行されている。
EnumWindows() が実行された段階ではウィンドウはまだ存在していなかった為に列挙されなかったかと。
> 1と2の間で WaitoForSingleObject や WaitForInputIdle をコールして1秒くらい止めると成功します。
CreateProcess() はプロセスを起動した段階で制御を返す。
起動されたプロセスはウィンドウを作成したり等の初期化処理を行うだろうが、CreateProcess() は初期化の完了を待ったりはしない。
1秒待った時に成功しているのは、その1秒の間に対象プロセスの初期化処理でウィンドウが作成された為だと思われる。
> ただし、「1秒」は根拠の無い数値なので、例えば表示状態を見るなどした方が良いと思うのですが、その方法がわかりません。
WaitForInputIdle() でキッチリ待ってやれば良い。
WaitForInputIdle() は指定プロセスのメインスレッドのメッセージキューが空っぽになるまで待ってくれる類の処理なので、
WaitForInputIdle() が正常終了 == 指定プロセスの初期化処理(ウィンドウ作成を含めた諸々の処理)が完了、と看做せる。
> 上記の方法は妥当なやり方なのでしょうか?
特に問題無いかと。ただ、2)、3) は EnumThreadWindows() を使った方が妥当かもしれない。
CreateProcess() で対象プロセスのメインスレッドidが得られるから、こっちの方が無駄が無い。
gak 様、早速のレスありがとうございます。
おかげさまで、思った通りの動きになりました。
ありがとうございました。
ツイート | ![]() |