次の状況でウィンドウ ハンドルを取得する最良の方法を探しています:
プロセスIDとプロセス ハンドルがあり、ウィンドウのタイトル名がわかっています。
では、どうすればよいでしょうか?FindWindow
? EnumWIndows
?
次の状況でウィンドウ ハンドルを取得する最良の方法を探しています:
プロセスIDとプロセス ハンドルがあり、ウィンドウのタイトル名がわかっています。
では、どうすればよいでしょうか?FindWindow
? EnumWIndows
?
を使用FindWindow
するには、ウィンドウ クラスまたはウィンドウ タイトルを知っている必要があります。これらの両方が必ずしも一意であるとは限りません。プロセス ハンドル (およびその ID) を既に取得しているため、 を使用して堅牢なソリューションを実装できますEnumWindows
。
まず、通信に使用する構造体を宣言します。プロセス ID を列挙プロシージャに渡し、ウィンドウ ハンドルを返します。
// Structure used to communicate data from and to enumeration procedure
struct EnumData {
DWORD dwProcessId;
HWND hWnd;
};
次に、特定のウィンドウのプロセス ID ( ) を取得し、GetWindowThreadProcessId
探しているものと比較するコールバック プロシージャが必要です。
// Application-defined callback for EnumWindows
BOOL CALLBACK EnumProc( HWND hWnd, LPARAM lParam ) {
// Retrieve storage location for communication data
EnumData& ed = *(EnumData*)lParam;
DWORD dwProcessId = 0x0;
// Query process ID for hWnd
GetWindowThreadProcessId( hWnd, &dwProcessId );
// Apply filter - if you want to implement additional restrictions,
// this is the place to do so.
if ( ed.dwProcessId == dwProcessId ) {
// Found a window matching the process ID
ed.hWnd = hWnd;
// Report success
SetLastError( ERROR_SUCCESS );
// Stop enumeration
return FALSE;
}
// Continue enumeration
return TRUE;
}
残っているのは公開インターフェースです。プロセス ID との通信に使用される構造体を設定し、最上位ウィンドウの列挙をトリガーし、ウィンドウ ハンドルを返します。この場合、エラーと成功の両方が返されるため、SetLastError
との呼び出しGetLastError
が必要です。EnumWindows
FALSE
// Main entry
HWND FindWindowFromProcessId( DWORD dwProcessId ) {
EnumData ed = { dwProcessId };
if ( !EnumWindows( EnumProc, (LPARAM)&ed ) &&
( GetLastError() == ERROR_SUCCESS ) ) {
return ed.hWnd;
}
return NULL;
}
// Helper method for convenience
HWND FindWindowFromProcess( HANDLE hProcess ) {
return FindWindowFromProcessId( GetProcessId( hProcess ) );
}
これにより、特定のプロセス ID に一致する最初のトップレベル ウィンドウが取得されます。要件では、特定のプロセスに対して 1 つのウィンドウしか存在しないと規定されているため、最初に一致したウィンドウが正しいウィンドウになります。
追加の制限が存在する場合EnumProc
は、それらを含めるように拡張できます。上記の実装で、追加のフィルターを適用できる場所をマークしました。