質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

3964閲覧

ウィンドウの列挙

BeatStar

総合スコア4958

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2017/01/13 03:34

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 をクリックして ソフトを表示する

のような感じでやるソフトです。

主に常駐するようなソフトです。

これも列挙対象に入れたいのですが、どう判断すればいいのでしょうか?

一応やりたいことは、

  1. 常駐ソフト ( 音声プレイヤー etc. ) を C/C++のソフトから起動
  2. そのままでは表示されないので tt に格納されている 1 のソフト用ボタンを押した状態にする
  3. 2 で出てくるメニューから "表示" ( ソフトによって 文字列が変わると思いますが... ) を押した状態にする ( メッセージを送る )
  4. 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

宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

具体的な回答は置いといて…

この手の要求を満たそうと思うとSPY++を使わないと
デバッグが辛いと思うので
もし、存在を知らない or 使ったことが無い
であれば是非どうぞ

投稿2017/01/14 07:40

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

現在表示されているウィンドウ

今のままでよいと思います。

tt に格納されているウィンドウ

Shell Tray Info - Arrange your system tray icons - CodeProject あたりが参考になりそうです。
トレイアイコン押下時に表示されるウィンドウは必ずしも表示状態にあるわけではないはず。
アイコン押下時にそのイベントを取得して表示状態にするなどの処理になるため、トレイアイコンに紐づく情報を取得することで、ウィンドウにたどり着くことができるかどうかを調べてください。

これって出来ているのでしょうか?

「数字が大きいからできていない」という判断がわかりません。
取れている = できている ですよね!?
Window ID は確か int 型なので、その範囲内だったら仕様として正しいかと思います。

投稿2017/01/13 03:53

編集2017/01/13 03:54
qt6hy

総合スコア149

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問