7

次の状況でウィンドウ ハンドルを取得する最良の方法を探しています:
プロセスIDプロセス ハンドルがあり、ウィンドウのタイトル名がわかっています

では、どうすればよいでしょうか?FindWindow? EnumWIndows?

4

1 に答える 1

15

を使用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が必要です。EnumWindowsFALSE

// 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は、それらを含めるように拡張できます。上記の実装で、追加のフィルターを適用できる場所をマークしました。

于 2013-11-23T14:44:41.907 に答える