C/C++ ( Windows API 実装あり ) でやっています。
ウィンドウを列挙して 指定ソフトへメッセージを送りたいのですが、
それに関しての質問があります。 ( 2つくらい。 )
質問1:
「C言語・WIN32API・C++・C#・.NET Framework」( http://www11.ocn.ne.jp/~ikalu/ )
-> 「現在表示されているウインドウを列挙する」
-> 「multimapコンテナとstringコンテナを使用したバージョン」
にあるソースコードを拝借して、multimap -> vector 等のように微妙に変えてやってみました。
ここまではいいのですが、タスクトレイっていうのですか? 「隠れているインジケーターを表示します」とある部分
に格納されている場合がありますよね? ( 以降 tt とします )
ファイルを起動 -> tt に格納 -> ユーザが tt をクリックして ソフトを表示する
のような感じでやるソフトです。
主に常駐するようなソフトです。
これも列挙対象に入れたいのですが、どう判断すればいいのでしょうか?
一応やりたいことは、
- 常駐ソフト ( 音声プレイヤー etc. ) を C/C++のソフトから起動
- そのままでは表示されないので tt に格納されている 1 のソフト用ボタンを押した状態にする
- 2 で出てくるメニューから "表示" ( ソフトによって 文字列が変わると思いますが... ) を押した状態にする ( メッセージを送る )
- 1 のソフトが 表示される
のような感じです。
これをやるために 最低でも
- ソフトの ウィンドウハンドル
- tt に格納されているボタン の ID
- tt に格納されているボタンを押したときに出てくるメニューの ID群 ( 最低でも対象は必ず )
は必要だと推測できます。
[ 上記サイトにあるソースコードを流用して作成したコード ]
C++
1// 必要なヘッダファイルはインクルード済みだとします。 2 3// 必要なライブラリもリンク済みだとします。 4 5 6//---------------------------------------------- 7// 構造体定義 8//---------------------------------------------- 9 10struct ENUMWINDOW{ 11 std::string classname; // クラス名 12 std::string title; // タイトルバーの文字列 13 HWND hWnd; 14}; 15 16 17 18 19 20/************************************************************** 21* 22* クラス名: --- 23* 24* 関 数 名: EnumWindowsProc 25* 26* 目 的: ウィンドウの列挙をするためのコールバック関数 27* 28* 引 数: 29* HWND hWnd := ウィンドウハンドル 30* LPARAM lp := 引数 31* 32* 戻 り 値: 33* BOOL 34* 35* 使 用 例: 36* --- 37* 38* 参 ・ 引: 39* 「C言語・WIN32API・C++・C#・.NET Framework」( http://www11.ocn.ne.jp/~ikalu/ ) 40* ->「現在表示されているウインドウを列挙する」 41* ->「multimapコンテナとstringコンテナを使用したバージョン」 42* 43* 備 考: 44* ウィンドウの列挙をするEnumWindowsEx関数用。 45* 46**************************************************************/ 47 48BOOL CALLBACK EnumWindowsProc( HWND hWnd, LPARAM lp ){ 49 vector<ENUMWINDOW> *VisibleWindow = (vector<ENUMWINDOW>*)lp; 50 51 WINDOWPLACEMENT wpm; 52 53 wpm.length = sizeof(WINDOWPLACEMENT); 54 55 GetWindowPlacement( hWnd, &wpm ); 56 57 if( IsWindowVisible( hWnd ) ){ 58 TCHAR windowText[0x2ff]; 59 ENUMWINDOW ew; 60 61 // クラス名 62 GetClassName( hWnd, windowText, sizeof(windowText) ); 63 ew.classname = windowText; 64 65 windowText[0] = '\0'; 66 67 // ウィンドウ 68 GetWindowText( hWnd, windowText, sizeof(windowText) ); 69 ew.title = windowText; 70 71 // ウィンドウハンドル 72 ew.hWnd = hWnd; 73 74 VisibleWindow->push_back( ew ); 75 } 76return true; 77} 78 79 80 81/************************************************************** 82* 83* クラス名: --- 84* 85* 関 数 名: EnumWindowsEx 86* 87* 目 的: 現在 起動&表示されているウィンドウの列挙 88* 89* 引 数: 90* std::vector<ENUMWINDOW> &result := 結果用vector 91* 92* 戻 り 値: 93* int : ウィンドウの数 94* 95* 使 用 例: 96* int n = EnumWindowsEx( 結果用vector ); 97* 98* 参 ・ 引: 99* 「C言語・WIN32API・C++・C#・.NET Framework」( http://www11.ocn.ne.jp/~ikalu/ ) 100* ->「現在表示されているウインドウを列挙する」 101* ->「multimapコンテナとstringコンテナを使用したバージョン」 102* 103* 備 考: 104* 105* 106**************************************************************/ 107 108int EnumWindowsEx( vector<ENUMWINDOW> &result ){ 109 EnumWindows( (WNDENUMPROC)EnumWindowsProc, (LPARAM)&result ); 110return result.size(); 111} 112 113
[ main関数内 ]
C++
1 vector<ENUMWINDOW> Window; 2 3 cout << "Window: " << EnumWindowsEx( Window ) << endl; 4 5 for( int i = 0; i < Window.size(); i++ ){ 6 cout << i << ":" << Window[i].classname << ", " << Window[i].title << " = " << Window[i].hWnd << endl; 7 }
コールバック関数 EnumWindowsProc 内の IsWindowVisible関数 のブロック ( 処理自体は残して ) を排除した状態にしたところ、
列挙対象に含めない範囲まで列挙してしまいます。
私が列挙対象に含めたいのは
- 現在表示されているウィンドウ
- tt に格納されているウィンドウ
です。
質問2:
質問1 にあるソースコードから ウィンドウを列挙できるなら 子ウィンドウ ( コントロール ) も列挙できるのでは?
と思い、ヘルプファイルで "EnumWindows" と検索したところ、
"参照" の部分に EnumChildWindows とあったので、
Firefox を起動した状態で
[ 追加コード ]
C++
1struct ENUMCHILDWINDOW{ 2 HWND parent; // 親ウィンドウハンドル 3 HWND hWnd; // コントロールのウィンドウハンドル 4 int ControlID; // コントロールID 5}; 6 7 8BOOL CALLBACK EnumWindowsProc( HWND hWnd, LPARAM lp ){ 9 vector<ENUMCHILDWINDOW> *v = (vector<ENUMCHILDWINDOW>*)lp; 10 11 ENUMCHILDWINDOW ew; 12 13 ew.hWnd = hWnd; 14 15 ew.ControlID = GetWindowLong( hWnd, GWL_ID ); 16 17 v->push_back( ew ); 18return true; 19} 20 21 22int EnumChildWindowsEx( HWND hWnd, vector<ENUMCHILDWINDOW> &result ){ 23 EnumChildProc( hWnd, (WNDENUMPROC)EnumWindowsProc, (LPARAM)&result ); 24return result.size(); 25} 26
と書いて、
C++
1vector<ENUMCHILDWINDOW> firefox; 2 3for( int i = 0; i < Window.size(); i++ ){ 4 if( Window[i].title.find( "Firefox" ) != string::npos ){ 5 EnumChildWindowsEx( Window[i].hWnd, firefox ); 6 } 7} 8 9for( int i = 0; i < firefox.size(); i++ ){ 10 cout << "HWND: " << firefox[i].hWnd << " ID: " << firefox[i].ControlID << endl; 11} 12
を追加して、チェックしてみたところ、
何も表示されませんでした。
ウィンドウの指定を適当にして ( i = 3 とか ) チェックしたところ、
ContorlID の桁が かなり多い感じのものがありました。
これって出来ているのでしょうか?
私がやるときは 基本的に IDは コントロールの場合 102から開始しますが、コントロール数が少ないせいもあり、
110かそこらまでしか使いません。
ですが、ウィンドウの指定を適当... の部分で表示したものは 231341 みたいに 桁がかなり多くて...
[環境等]
言語: C/C++ ( Windows API あり )
コンパイラ: MinGW
宜しくお願い致します。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。