指定画面のハンドルを取得するには?

解決


さえ  2006-06-15 20:55:38  No: 95771

こんにちは。いつもお世話になっております。

ハンドルの取得で分からない点があるので
お力をお借りしたく書き込みさせて頂きます。

開発環境は、WIN2000、VB6.0 SP5です。

A.exeからB.exeを制御する為、
APIのFindWindowsを使用し、A.exeの中で、
B.exeのCaption名を指定してハンドルを取得しています。
B.exeのCaptionは画面により変わります。
しかし、Captionの内容は数種類しかないので、
その数種類全て試し、ハンドルが取得出来なければ
他のCaptionで試す。という方法でプログラミングしました。

ここでわからない事があったのですが、
B.exeのメイン画面のCaptionが「プログラム-メイン」で、
他の画面のCaptionが「プログラム」であった時に、
今開いているメイン画面ではないハンドルを取得したいのに、
メイン画面のハンドルが取れてしまいます。

lngHNDL = FindWindow(vbNullString, "プログラム-メイン")  '①
If lngHNDL = 0 Then
    lngHNDL = FindWindow(vbNullString, "プログラム")       '②
End If

私の予想では、①ではハンドルが取得出来ず、②でハンドルが取れると
思っていたのですが、①で取れてしまうので、正しいハンドルが取得出来ず
制御ができません。

私の知らない何かが不足しているのでしょうか。
ご存知の方、ご教授よろしくお願いします。


我龍院忠太  2006-06-16 05:28:02  No: 95772

多分言葉が今ひとつ不明確な為レスがつかないのでしょう。
>今開いているメイン画面ではないハンドルを取得したいのに、
「メイン画面」の画面とはどのような画面でしょう、親のWindowとは
違うのですよね。
それと開いているとはどのような状態でしょうか?
開いていないWindowのハンドルは取得出来ませんが、当然
ご存知ですよね。


さえ  2006-06-16 18:53:31  No: 95773

おはようございます。

我龍院忠太様、ご指摘ありがとうございます。
言葉が足りないか、レベルが低すぎるのかと思っていました。
出来うる限りで補足致します。

先に我龍院忠太様のご指摘に回答いたします。

>「メイン画面」の画面とはどのような画面でしょう
B.exeを起動して最初に表示される画面の事です。
画面は一つです。

>それと開いているとはどのような状態でしょうか?
その画面を表示しているという事です。
確かに、開いていると表示しているでは意味が違いますね。
申し訳ありません。

>開いていないWindowのハンドルは取得出来ませんが、当然
>ご存知ですよね。

はい。現在表示している画面のハンドルをCaption指定で
取得したいが、うまく行かないので質問させていただきました。
ただ、書きそびれた事がひとつあり、B.exeは最小化して
タスクバーに入り、その状態でA.exeはB.exeのハンドルを
取得しようとします。最小化に問題があるのでしょうか…。

以下、最初の書き込みを補足する形で書き直します。

Caption内容が変わるB.exeですが、具体的には、
B.exe起動時最初に表示される画面をメイン画面と考え、
このメイン画面のCaption=「プログラム-メイン」です。
メイン画面にはボタンがたくさんあり、ボタン毎に画面が変わり、
その画面のCaption=「プログラム」です。

メイン画面のボタンを押下すると、ボタンに応じた画面に変わり、
さらにその画面にもボタンがあり、押下すると次の画面に変わる仕組みで、
Caption内容は、メイン画面以外全て「プログラム」になっています。
モーダル画面はありません。
つまり、Captionのパターンは二種類しかありません。
メイン画面のCaption=「プログラム-メイン」
その他の画面のCaption=「プログラム」です。

あれから、if文の順番を変えたら、うまく制御出来たかのように
動いたのですが、最初の画面(1)→次の画面(2)→次の画面(3)  の、
(3)の画面で制御出来なくなりました。
※Captionは、メイン画面ではないので「プログラム」
※ハンドル値はCaption=「プログラム」で取得出来ていました。

以上できうる限りで補足させて頂きましたが、
これでもわからないようでしたらもう少し日本語と用語を学んで
出直します。お手数おかけ致しますが、分かる方がおられましたら
ご教授を、意味がわからなければその旨お叱りくださいますようお願い致します。

よろしくお願い致します。


魔界の仮面弁士  2006-06-16 20:37:58  No: 95774

1) 正しく取得できないとのことでしたが、指定したキャプション名は、
  間違いないのでしょうか? (空白の有無/全角空白の違いなど)
 
2) 異なるウィンドウハンドルが取得されてしまっていたようですが、
  そのハンドルのウィンドウのキャプションは、何だったのでしょうか?

3) SPYXX.EXE などを用いて、対象のウィンドウの
    「ウィンドウハンドル」
    「キャプション」
    「クラス名」
    「トップレベルかどうか」
  について、調べてみてください。


我龍院忠太  2006-06-17 04:46:59  No: 95775

その症状はFindWindowでは無くGetForegroundWindow
でハンドルを取得してる症状なんですが、どこかで
関数が入れ替わっていませんか。


通ってみた  2006-06-17 23:57:43  No: 95776

キャプションの後ろ3文字だけを調べて「メイン」かどうかで判断してみるとかどうでしょう


さえ  2006-06-19 18:37:19  No: 95777

おはようございます。
魔界の仮面弁士様への返事を書いてる途中(金曜)に
別の作業が割り込んでしまい、遅くなりました。すいません。

魔界の仮面弁士様、レスありがとうございます。

1)についてですが、間違いありません。
Captionの値は、全ての画面、関数から取得しているので
メイン画面以外は「プログラム」であり、空白等の違いが無い事を
確認しました。

2)についてですが、デバッグして調べてみます。
一つ前の分に書きましたが、
メイン画面(1)→次の画面(2)→次の画面(3)と画面遷移していき、
そのCaption値は、
(1)「プログラム-メイン」
(2)「プログラム」
(3)「プログラム」  です。
3つ目の画面を表示して最小化したB.exeに対して、
A.exeはCaption=「プログラム」でAPIはFindWindowを使用して
ハンドルを取得していますが、このハンドルがどの画面のハンドル値なのかは
デバッグをかけてみますが、判定出来るか断定できません。
が、とにかくデバッグかけて調べてみます。
A.exeが取得したハンドルとB.exeの現在のハンドルを調べます。
きっと一致していないのだと思いますが。

3)SPYXX.EXE がわからないので、調べます。すいません。

我龍院忠太様

使用APIはFindWindowです。GetForegroundWindow自体使用していないので、
関数が入れ替わっている事はありません。

通ってみた様

Captionが「プログラム」である画面のハンドルを取得しようとして、
デバッグではFindWindowでCaption=「プログラム」とした処理を通り、
ハンドルを戻しているので、「プログラム-メイン」と「プログラム」の
違いは判断出来てると思うのですが、もう少し調べる必要があるようです。

正しくCaption指定をしていて、ハンドル値も戻っているのに、
取得できたハンドル値が表示している画面のハンドルではないというのが
謎です。皆様のご指摘くださった事を元に調べてみます。


さえ  2006-06-20 02:05:02  No: 95778

こんにちは。

まず、先の書き込みで、我龍院忠太様、通ってみた様への
お礼が抜けていました。失礼しました。
レスありがとうございます。

空き時間を見つけて調べていて、気づいた事があるので書き込みます。
以下のようにプログラムを書いています。
何度も繰り返してしまいますが、Captionの値が2種類なので、
どちらかHITするように書いています。

A.exeのソース
------------------------------------------------------
lngHNDL = FindWindow(vbNullString, "プログラム-メイン")  '(1)
If lngHNDL = 0 Then
    lngHNDL = FindWindow(vbNullString, "プログラム")       '(2)
End If
------------------------------------------------------

B.exeの画面をメイン画面以外(つまりCaptionが「プログラム」)の状態で
上記のソースを走らせたら、(1)を通り、メイン画面のハンドルを取得しました。

(1)と(2)の順序を入れ替えて、
------------------------------------------------------
lngHNDL = FindWindow(vbNullString, "プログラム")  '(1)
If lngHNDL = 0 Then
    lngHNDL = FindWindow(vbNullString, "プログラム-メイン") '(2)
End If
------------------------------------------------------
メイン画面の次…
(メイン画面を1つ目の画面とし、メイン画面のボタンを押して次の画面に移ったら
それを2つ目の画面、2つ目の画面のボタンを押して次の画面に移ったら3つ目の
画面とします。)で上記ソースを走らせたら、
2つ目のハンドルが取得出来ました。これはOKです。
3つ目の画面で上記ソースを走らせたら、3つ目の画面を制御出来なかった事から、
おそらく2つ目のハンドルを取得したと思われます。

もし、B.exeの画面全てのCaptionが同じであり、
--------------------------------------------------------
lngHNDL = FindWindow(vbNullString, "プログラム")
--------------------------------------------------------
と記述したら、メイン画面のハンドルしか取れないのだと思います。

今から、魔界の仮面弁士様が3番目にあげてくださった事を調べてみます。


うげん  2006-06-28 21:38:19  No: 95779

かならず FindWindow '(1)でハンドルが取れるようですので
画面が遷移しても、後ろに隠れているか非表示Windowとして
他のプログラム画面なり、メイン画面が存在しているのでは
ないでしょうか?


さえ  2006-07-11 22:12:40  No: 95780

うげん様、回答ありがとうございます!

なるほど!!と思い、画面遷移する側のソースを見直したら、
次の画面を表示させる方法が「Load」で表示させており、
呼び出し元フォームは、「Hide」で非表示にしていました。

非表示にしていただけなので、同じCaption名の上位フォームの
ハンドルが取得されていたわけですね。

おそらくコレが原因だと思います。

SPYXX.EXEがわからない…という事で、
回答いただいていたのに確認が遅れて申し訳ありません。

皆様、ありがとうございました!

…SPYXX.EXEは宿題という事で調べ続けます。


さえ  2006-07-11 23:31:47  No: 95781

SPYXX.EXEについて

魔界の仮面弁士様、
使い方がわかりました!
こんな便利なツールがあったのですね!
また一つ勉強になりました!

ありがとうございます!
解決後失礼しました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加