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

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

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

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

Win32 API

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

Q&A

解決済

2回答

2316閲覧

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

yun.nishi

総合スコア5

C++Builder

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

Win32 API

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

0グッド

0クリップ

投稿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

以上、ご教授ください。

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

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

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

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

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

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の使い方を少し理解できるようになりました。
guest

回答2

0

ベストアンサー

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

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

.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

総合スコア2626

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

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

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を取得することができました。ありがとうございました!大変勉強になりました。
guest

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

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問