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

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

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

C++Builderは、C/C++を用いてアプリ開発できる統合開発環境 (IDE) 。DelphiのC++版です。コンポーネントによるビジュアル開発、高機能なコードエディターなどで生産性の高い開発ができます。

Win32 API

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

Q&A

解決済

自アプリで起動したアプリやファイルのWindowのハンドルを正しく取得できません

yun.nishi
yun

総合スコア5

C++Builder

C++Builderは、C/C++を用いてアプリ開発できる統合開発環境 (IDE) 。DelphiのC++版です。コンポーネントによるビジュアル開発、高機能なコードエディターなどで生産性の高い開発ができます。

Win32 API

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

2回答

0グッド

0クリップ

961閲覧

投稿2022/01/23 14:47

編集2022/01/26 00:53

前提・実現したいこと

初めて投稿します。
WindowsAPIを使用して、起動したアプリやファイルのWindowを正しく探すテストプログラムを作って評価しています。目的のWindowを探せますが、下記の結果のように、それ以外のWindowもヒットしてしまいます。異なるWindow同士でProsessIdが同じ値を持つことはないと認識していました。このような現象は正常な動作なのでしょうか。ネット上のサンプルも参考にさせていただいて特に違いはないように思いますが、なぜか日本語入力フロントエンドがヒットするのか不明です。

発生している問題・エラーメッセージ

エラーメッセージ

該当のソースコード

【SampleU.cpp】 //--------------------------------------------------------------------------- #include <vcl.h> #include <Windows.h> #pragma hdrstop #include "SampleU.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam); //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { wchar_t lpResult; wchar_t Result[1024]; wchar_t _str[1024]; String str, str1; ZeroMemory(&si, sizeof(STARTUPINFOW)); ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); si.cb = sizeof(STARTUPINFOW); si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_SHOWNORMAL; str = L"C:\\Windows\\System32\\notepad.exe D:\\Mydesktop\\memo.txt"; CreateProcessW( NULL, str.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ); WaitForSingleObject(pi.hProcess, 1000); EnumWindows(EnumWindowsProc, (LPARAM)&pi); CloseHandle(pi.hThread); CloseHandle(pi.hProcess); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject Sender) { Memo1->Lines->Clear(); } //--------------------------------------------------------------------------- //■hWnd:トップウィンドウのハンドル、 LPARAM lParam ← (LPARAM)pi.hProcess //------------------------------------------------------------ BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) { PROCESS_INFORMATION p = (PROCESS_INFORMATION*)lParam; DWORD pid = 0; GetWindowThreadProcessId(hWnd, &pid); wchar_t _Title[1024]; String Title; GetWindowTextW(hWnd, _Title, 1024); Title = _Title; if (pid == p->dwProcessId) { Form1->Memo1->Lines->Add(L"-----"); Form1->Memo1->Lines->Add(L"Title = " + Title); Form1->Memo1->Lines->Add(L"pid = " + IntToStr((int)pid)); Form1->Memo1->Lines->Add(L"p->dwProcessId = " + IntToStr((int)p->dwProcessId)); Form1->Memo1->Lines->Add(L"hWnd = " + IntToStr((int)hWnd)); } return true; } //--------------------------------------------------------------------------- 【SampleU.h】 //--------------------------------------------------------------------------- #ifndef SampleUH #define SampleUH //--------------------------------------------------------------------------- #include <System.Classes.hpp> #include <Vcl.Controls.hpp> #include <Vcl.StdCtrls.hpp> #include <Vcl.Forms.hpp> #include <Vcl.ExtCtrls.hpp> #include <Vcl.Dialogs.hpp> //--------------------------------------------------------------------------- class TForm1 : public TForm { __published: // IDE で管理されるコンポーネント TPanel *Panel1; TMemo *Memo1; TButton *Button1; TButton *Button2; void __fastcall Button1Click(TObject *Sender); void __fastcall Button2Click(TObject Sender); private: // ユーザー宣言 STARTUPINFOW si; PROCESS_INFORMATION pi; public: // ユーザー宣言 __fastcall TForm1(TComponent Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TForm1 *Form1; //--------------------------------------------------------------------------- #endif

試したこと

ソースコードをコンパイルして実行したところ、同一のプロセスIdのWindowを下記のように4個ヒットしました。

補足情報

-----
Title = ATOK30TIP UI Window Name
pid = 3076
p->dwProcessId = 3076
hWnd = 3869068
-----
Title = memo.txt - メモ帳
pid = 3076
p->dwProcessId = 3076
hWnd = 330382
-----
Title = MSCTFIME UI
pid = 3076
p->dwProcessId = 3076
hWnd = 6949362
-----
Title = Default IME
pid = 3076
p->dwProcessId = 3076
hWnd = 1247030

以上、ご教授ください。

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

y_waiwai

2022/01/23 23:35

このままではコードが読みづらいので、質問を編集し、<code>ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください
yun.nishi

2022/01/24 12:09

このteratailに慣れていないので見にくい投稿となってしまい失礼いたしました。ご提案のやり方がわからず、今後理解した上で何か投稿したいと思います。アドバイスありがとうございました。
yun.nishi

2022/01/26 05:54

y_waiwaiさんのご指摘をもとにソースコードの表記を修正しました。コメントありがとうございました!おかげでteratailの使い方を少し理解できるようになりました。

回答2

1

ベストアンサー

なぜか日本語入力フロントエンドがヒットするのか不明です。

なぜって、ウインドウがあるからです。(^_^;)

.NET Framework のソースですが
ProcessManager.IsMainWindow
https://referencesource.microsoft.com/#System/services/monitoring/system/diagnosticts/ProcessManager.cs,53d47c883d8b918a

・オーナーがいない
・Visible である

のをメインウインドウとしています。
FEP のウインドウはこれで除外できますが、条件を満たすウインドウは複数作れるので、どれがメインウインドウなのかは判別できそうにないですね。

投稿2022/01/23 23:39

編集2022/01/23 23:50
KOZ6.0

総合スコア2252

yun👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

yun.nishi

2022/01/24 12:06

・オーナーがいない ・Visible である 確かにそうなんですね。FEP関係のヒットを回避するよう検討してみます。助言くださりありがとうございます。
yun.nishi

2022/01/24 12:25

ご指摘ありがとうございます。 IMEという表現は知っていますが、MSの日本語入力専用と思っていました。勉強になりました。感謝!
yun.nishi

2022/01/26 05:51

KOZ6.0さんのコメントを参考にさせていただき、 IsWindowVisible() がtrue、 GetWindow(hWnd, GW_OWNER) == NULL(オーナーがいない) 2つの条件にあうWindowを選んで、無事に目的のWindowを取得することができました。ありがとうございました!大変勉強になりました。

0

おかげさまで、以下のように修正して目的のWindowのみをキャッチすることができました!

//【SampleU.cpp】 //--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "SampleU.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; // オーナー・ウインドウの判別 #define IsWindowOwner(h) (GetWindow(h,GW_OWNER) == NULL) BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam); BOOL IsWindowType(HWND hWnd); //BOOL IsEnumCheck(HWND hWnd, LPCTSTR lpTitle, LPCTSTR lpClass); //BOOL IsWindowType(HWND hWnd, LPCWSTR lpTitle); //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- //■実行 //------------------------------------------------------------ void __fastcall TForm1::Button1Click(TObject *Sender) { wchar_t lpResult; wchar_t Result[1024]; wchar_t _str[1024]; String str; ZeroMemory(&si, sizeof(STARTUPINFOW)); ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); si.cb = sizeof(STARTUPINFOW); si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_SHOWNORMAL; str = L"C:\\Windows\\System32\\notepad.exe D:\\Mydesktop\\memo.txt"; CreateProcessW( NULL, str.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ); WaitForSingleObject(pi.hProcess, 1000); EnumWindows(EnumWindowsProc, (LPARAM)&pi); CloseHandle(pi.hThread); CloseHandle(pi.hProcess); } //--------------------------------------------------------------------------- //■画面消去 //------------------------------------------------------------ void __fastcall TForm1::Button2Click(TObject *Sender) { Memo1->Lines->Clear(); } //--------------------------------------------------------------------------- //■hWnd:トップウィンドウのハンドル、 LPARAM lParam ← (LPARAM)pi.hProcess //------------------------------------------------------------ BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) { PROCESS_INFORMATION* p = (PROCESS_INFORMATION*)lParam; DWORD pid = 0; GetWindowThreadProcessId(hWnd, &pid); wchar_t _Title[1024]; String Title; //列挙ウインドウの表示 if (pid == p->dwProcessId) { GetWindowTextW(hWnd, _Title, sizeof(_Title)); Title = _Title; if (IsWindowType(hWnd)) { SetWindowPos(hWnd, HWND_TOP, 500, 100, 500, 1000, (SWP_NOSIZE|SWP_NOZORDER|SWP_NOOWNERZORDER)); Form1->Memo1->Lines->Add(L"-----"); Form1->Memo1->Lines->Add(L"Title = " + Title); Form1->Memo1->Lines->Add(L"pid = " + IntToStr((int)pid)); Form1->Memo1->Lines->Add(L"p->dwProcessId = " + IntToStr((int)p->dwProcessId)); Form1->Memo1->Lines->Add(L"hWnd = " + IntToStr((int)hWnd)); } return true; } return true; } //--------------------------------------------------------------------------- //■表示するウインドウをチェック //------------------------------------------------------------ BOOL IsWindowType(HWND hWnd) { if (IsWindowVisible(hWnd)){ if (IsWindowOwner(hWnd)){ return true; } } return false; } //--------------------------------------------------------------------------- 【SampleU.h】 //--------------------------------------------------------------------------- #ifndef SampleUH #define SampleUH //--------------------------------------------------------------------------- #include <System.Classes.hpp> #include <Vcl.Controls.hpp> #include <Vcl.StdCtrls.hpp> #include <Vcl.Forms.hpp> #include <Vcl.ExtCtrls.hpp> //--------------------------------------------------------------------------- class TForm1 : public TForm { __published: // IDE で管理されるコンポーネント TPanel *Panel1; TMemo *Memo1; TButton *Button1; TButton *Button2; void __fastcall Button1Click(TObject *Sender); void __fastcall Button2Click(TObject *Sender); private: // ユーザー宣言 STARTUPINFOW si; PROCESS_INFORMATION pi; public: // ユーザー宣言 __fastcall TForm1(TComponent* Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TForm1 *Form1; //--------------------------------------------------------------------------- #endif

投稿2022/01/26 06:12

編集2022/01/26 07:05
yun.nishi

総合スコア5

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

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

ただいまの回答率
86.02%

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

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

質問する

関連した質問

同じタグがついた質問を見る

C++Builder

C++Builderは、C/C++を用いてアプリ開発できる統合開発環境 (IDE) 。DelphiのC++版です。コンポーネントによるビジュアル開発、高機能なコードエディターなどで生産性の高い開発ができます。

Win32 API

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