トップ回答者
GetWindowで取得したポップアップメニューなどが所属するアプリケーションウィンドウを判定するには?

質問
-
与えられたアプリケーションウィンドウについて、それにかぶさっているウィンドウを列挙しようとしています。そこでGetWindow(hwnd, GW_HWNDFIRST)を使うのですが、IEについてそれを行っていると
- ボタンバーをクリックしたときに出てくるポップアップメニュー
- ボタンにマウスを乗せたときに出てくるツールチップ
- アドレスバーから下にせり出すサジェスト
などが「かぶさっている」ものとして出てきてしまいます。もちろん、これらは「関係者」ですから除外したいのですが、どのようにそのことを判定可能でしょうか?
GetWindow( item, GW_OWNER), GetParent( item ), GetAncestor( item, * ), IsChild() のいずれでも、関係者だと判定できませんでした。
ウィンドウ構造を調べてみようにも、どれも他のアプリに切り換えた途端に消えてしまう表示物なのでSpy++で引っかけることもできず…- 編集済み miuras_net 2015年11月10日 5:53 Spy++が使えない理由
回答
-
GetWindowThreadProcessIdでHWNDからプロセスIDとスレッドIDが取れるので、EnumWindowsでトップレベルウィンドウを列挙して同じプロセスIDなら同じアプリケーションであると判定はできます。
ポップアップウィンドウはトップレベルウィンドウになるのでEnumWindowsだけでいいはず。
あとは、スレッドIDも同じウィンドウは関係があるとみなす位までなら判定可能かも。(親子関係があっても別スレッドの可能性はあるので)
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク miuras_net 2015年11月11日 0:39
-
追加情報:
IEは一般的なWin32アプリに比べてウィンドウ構造が特殊なことがわかってきました。
- ツールチップおよびメニュー(メニューバーのものも、コンテキストメニューも)が、メインウィンドウと別のプロセスで動いています。これはどうやら32ビット版と64ビット版の協調動作のためのようです。
これらのウィンドウが出現するのはメインウィンドウがフォアグラウンドのときに限られるので、
・IEメインウィンドウがフォアグラウンド
・ウィンドウの所有プロセスの実行ファイル名がiexplore.exe
なら所有があろうと判定できました。 - スクリプトからalert()やconfirm()で出したダイアログが、一見モーダルダイアログのように見えて、これも別プロセスで動作しています。モーダルダイアログのように偽装(メインウィンドウが触れなく)するために、メインウィンドウの上には同じサイズの透明なウィンドウがかぶせられます(まるでWebデザインにおける疑似モーダルダイアログを作っているようです)。この透明ウィンドウのクラス名は"Alternate Modal Top Most"です。モーダルダイアログはこのAlternate
Modal Top Most に所有されています。
ウィンドウクラス名・位置・サイズから所有関係を推測しました。
- 回答としてマーク miuras_net 2015年11月11日 8:25
- ツールチップおよびメニュー(メニューバーのものも、コンテキストメニューも)が、メインウィンドウと別のプロセスで動いています。これはどうやら32ビット版と64ビット版の協調動作のためのようです。
すべての返信
-
GetWindowThreadProcessIdでHWNDからプロセスIDとスレッドIDが取れるので、EnumWindowsでトップレベルウィンドウを列挙して同じプロセスIDなら同じアプリケーションであると判定はできます。
ポップアップウィンドウはトップレベルウィンドウになるのでEnumWindowsだけでいいはず。
あとは、スレッドIDも同じウィンドウは関係があるとみなす位までなら判定可能かも。(親子関係があっても別スレッドの可能性はあるので)
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク miuras_net 2015年11月11日 0:39
-
追加情報:
IEは一般的なWin32アプリに比べてウィンドウ構造が特殊なことがわかってきました。
- ツールチップおよびメニュー(メニューバーのものも、コンテキストメニューも)が、メインウィンドウと別のプロセスで動いています。これはどうやら32ビット版と64ビット版の協調動作のためのようです。
これらのウィンドウが出現するのはメインウィンドウがフォアグラウンドのときに限られるので、
・IEメインウィンドウがフォアグラウンド
・ウィンドウの所有プロセスの実行ファイル名がiexplore.exe
なら所有があろうと判定できました。 - スクリプトからalert()やconfirm()で出したダイアログが、一見モーダルダイアログのように見えて、これも別プロセスで動作しています。モーダルダイアログのように偽装(メインウィンドウが触れなく)するために、メインウィンドウの上には同じサイズの透明なウィンドウがかぶせられます(まるでWebデザインにおける疑似モーダルダイアログを作っているようです)。この透明ウィンドウのクラス名は"Alternate Modal Top Most"です。モーダルダイアログはこのAlternate
Modal Top Most に所有されています。
ウィンドウクラス名・位置・サイズから所有関係を推測しました。
- 回答としてマーク miuras_net 2015年11月11日 8:25
- ツールチップおよびメニュー(メニューバーのものも、コンテキストメニューも)が、メインウィンドウと別のプロセスで動いています。これはどうやら32ビット版と64ビット版の協調動作のためのようです。