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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Visual Studio 2010

Microsoft Visual Studio 2010はMicrosoftが提供している統合開発環境(IDE)です。

Win32 API

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

Q&A

解決済

1回答

14355閲覧

起動中のウィンドウのハンドルとタイトル名の取得方法(タスクマネージャーに表示されるものと一致させる)

mery

総合スコア27

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Visual Studio 2010

Microsoft Visual Studio 2010はMicrosoftが提供している統合開発環境(IDE)です。

Win32 API

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

1グッド

1クリップ

投稿2019/04/19 10:46

前提・実現したいこと

windows7のタスクマネージャーを起動し、アプリケーションのタブを選択した時にタスクの欄に表示されているウィンドウ名と同じウィンドウのハンドルとタイトル名を取得したいのですがうまくできません。

EnumWindows関数を使ってウィンドウを列挙する方法を試してみたのですがタスクマネージャーに表示されていないものまで表示されてしまいました。

私の環境ではタスクマネージャーに3つ表示されている時に、私のプログラムでは6つ表示されました(program Manager,NECWSET_TB_WINDOW,Windows タスクマネージャー,スタートの4つが表示されていて、自分自身のプログラムは表示されません)

余分に表示されるものをif(lstrcmp(szText,TEXT("スタート"))==0){ return TRUE;} という感じで判定すれば表示しないようにはできますが、これだと自分の作った他のプログラムのタイトルがこれらのタイトル名と同じだった場合にそのプログラムのハンドルまで表示されなくなってしまいます。
どうすればタスクマネージャーに表示されているものと同じものだけを表示させることができますか?

該当のソースコード 表示する項目の判定部分

c

1BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam){ 2LVITEM item; 3TCHAR szText[256];//ウィンドウのキャプションの保存用 4TCHAR szhwnd[256];//ウィンドウハンドル表示用 5TCHAR szClassName[256];//取得したクラス名保存用 6 7wsprintf(szhwnd,TEXT("%X"),hwnd); 8if(!IsWindowVisible(hwnd)) return TRUE; 9GetWindowText(hwnd,szText,256); 10if (szText[0] == 0) return TRUE; 11 GetClassName(hwnd, 12 szClassName, 13 sizeof(szClassName) / sizeof(TCHAR)); 14 15 item.mask = LVIF_TEXT; 16 item.pszText = szhwnd; 17 item.iItem = 0; 18 item.iSubItem = 0; 19 20 ListView_InsertItem((HWND)lParam, &item); 21 22 item.pszText = szClassName; 23 item.iItem = 0; 24 item.iSubItem = 1; 25 ListView_SetItem((HWND)lParam, &item); 26 27 item.pszText = szText; 28 item.iItem = 0; 29 item.iSubItem = 2; 30 ListView_SetItem((HWND)lParam, &item); 31 32 return TRUE; 33}

補足情報(FW/ツールのバージョンなど)

Microsoft Visual C++ 2010 Express C言語
WIN32 ユニコードビルド Windows7

atata0319👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

Visual Studio に付属のウィンドウ解析用ツール Spy++ を使って軽く確認した限りですが、タスクマネージャーでは

  • EnumWindowsAPIで列挙できるトップレベルウィンドウの内、
  • 現在Visibleのもので、
  • ウィンドウスタイルが WS_POPUP ではないもの

を表示しているようです。例としてEnumWindowProcの以下のコードで、タスクマネージャーでの表示に一致しました。(Windows 7 Ultimate 64ビット、Windows 10 Professional 64ビット で確認)

C++

1static BOOL CALLBACK EnumWindowsProc( 2 _In_ HWND hwnd, 3 _In_ LPARAM lParam 4) 5{ 6 if (IsWindowVisible(hwnd)) { 7 8 LONG_PTR style = GetWindowLongPtr(hwnd, GWL_STYLE); 9 if ((style & WS_POPUP) == 0) { 10 // 確認の為デバッグ端末へ出力 11 TCHAR sz[256 + 2]; 12 GetWindowText(hwnd, sz, 256); 13 lstrcat(sz, _T("\n")); 14 OutputDebugString(sz); 15 } 16 } 17 18 return TRUE; 19}

以下の件ですが、

これだと自分の作った他のプログラムのタイトルがこれらのタイトル名と同じだった場合にそのプログラムのハンドルまで表示されなくなってしまいます。

ウィンドウのタイトルバーに表示されているタイトル文字列は、SetWindowTextを使って動的に変えることもでき、それで考えるとタイトルだけで判断するのは不十分とも言えます。厳密にするのであれば、タイトルだけでなく、ウィンドウクラス名や必要に応じてウィンドウの付帯情報(ウィンドウスタイルや親子関係)まで対象にすれば判別は可能だと思います。(質問者さんのコードでは、GetClassNameでクラス名を取得していますね)

なお、ウィンドウの解析に便利なツール Spy++は Visual Studio 2010 Professional版には付属していますが、質問者さんご利用のExpress版に付属しているかは分かりません。


追記しました:(2019/04/20 14:28)

ReactOSと言うWindows互換を目指しクローンOSがあります。
Wikipedia - ReactOS

そのタスクマネージャーのソースが参考になるかもしれません。
github - reactos / taskmgr

このソース中のEnumWindowsProc関数の中で、
/* Check and see if this is a top-level app window */と言うコメント部分があり、ここでタスクマネージャーに表示しないものを選り分けています。Windows 7やWindows 10と同じ挙動とは限りませんが、先の私のコード例より、親ウィンドウやオーナーウィンドウ、拡張ウィンドウスタイルを意識するなど、選別条件が増えています。こちらのコードを参考にすること、お望みの挙動になるかもしれません。

投稿2019/04/20 01:20

編集2019/04/20 05:31
dodox86

総合スコア9183

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

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

mery

2019/04/20 04:12

回答ありがとうございます。 教えて頂いたコードを参考に試してみましたがタスクマネージャーの結果とは一致しなかったです。 余分に表示されていた4つのうち3つの表示は消えたのですがNECWSET_TB_WINDOWというものだけが消えませんでした。また、ファイルのプロパティ画面を表示しているとそのウィンドウの情報も表示されませんでした。タスクマネージャーではそれも表示されるので「ウィンドウスタイルが WS_POPUP ではないもの 」とういう条件は違うような気がするのですが・・・。 私のプログラムで余分に表示されていた「スタート」というウィンドウと同じタイトルとウインドウクラス名を持つプログラムを作成し、実行してみるとタスクマネージャーにはそれが表示されたのでタイトル名やクラス名で判別されているわけでもなさそうです。 他に考えられる判別方法は無いでしょうか?
dodox86

2019/04/20 04:52 編集

"NECWSET_TB_WINDOW"の件は書かなかったのですが、NEC製のバンドルソフトではありませんか?(NEC製PCであったりしませんか?)「NECWSET_TB_WINDOW」で検索してみてください。ワイヤレスの設定用ツールのようです。特別なウィンドウスタイルであったり、また、別の条件もあるかもしれません。当方で同じ環境にないので、すみませんが確認できません。 > タイトル名やクラス名で判別されているわけでもなさそうです。 回答には書かせていただきましたが、ウィンドウスタイルも関係していると思われます。(あくまで私の推測です)"スタート"と言うのはWindowsの「スタート」ボタンだと思います。タスクマネージャーはWindows標準のものなので、他の(Windows標準としての)"Program Manager (ウィンドウクラス名は"Progman")やタスクマネージャーのウィンドウは、あえて表示から外して表示していることも考えられます。この辺は公式な情報があるわけではないので、これも推測です。
atata0319

2019/04/20 05:41

Windows7 が手元に無いので確認できていませんが、EnumWindows で取得した一覧から GetAltTabInfo で情報が取れるものを選別した後、同一プロセスをまとめて表示しているとかじゃないですかね?
dodox86

2019/04/20 06:15

atata0319さん、フォローありがとうございます。取り急ぎ手持ちのWindows 7 のtaskmgr.exe を"dumpbin /imports"してインポートしている一連のWindows APIを眺めてみたところ、 GetAltTabInfo はありませんでしたが、(<もちろん、直接インポートしているとは限りませんけど)  代わりに、EnumDesktopWindows OpenDesktopその他がありました。EnumWindows は使っていませんでした。EnumWindowsは現デスクトップ用のラッパー関数な気もするので、EnumWindowsの使用をEnumDesktopWindowsに変えても挙動は同じな気もしますが。タスクマネージャーと言うことで、ご指摘のように同一プロセスを意識するなど複雑な選別をしていることはありそうです。
mery

2019/04/20 08:02

atata0319さん、dodox86さん回答ありがとうございました。 dodox86さんに教えて頂いたReactOSのソースを参考にしてプログラムしたら解決できました。 ウィンドウスタイルが WS_POPUP ではないものを調べるところを削除して、代わりに拡張ウィンドウスタイルのWS_EX_TOOLWINDOWの有無で判断するようにしたら「NECWSET_TB_WINDOW」の表示も消えました。これだけだとメディアプレイヤーを起動している時に「Windows Media Player 」というタイトルが4回表示されてしまうのでGetParent(hWnd)で判別することも必要のようです。
atata0319

2019/04/21 13:43

解決したようでよかったです。 ReactOS のソースも読みましたが、意外と単純な仕組みなっているんですね。EnumDesktopWindows と EnumWindows の差についてはちょっと調べて、以下のスタックオーバーフローの記事を見つけました。Windows 10 ではクラシックアプリやストアアプリ等の列挙のされ方に差があるような感じですかね。 https://stackoverflow.com/questions/38205375/enumwindows-function-in-win10-enumerates-only-desktop-apps
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問