Using FindWindow requires that you either know the window class or window title. Both are not necessarily unique. Since you have alread a process handle (and its identifier), you can implement a robust solution using EnumWindows .
First declare the structure used for communication. It passes the process identifier to the enumeration procedure and returns the window handle back.
// Structure used to communicate data from and to enumeration procedure struct EnumData { DWORD dwProcessId; HWND hWnd; };
Next, we need a callback procedure that extracts the process identifier ( GetWindowThreadProcessId ) for any given window and compares it with the one we are looking for:
// 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; }
The public interface remains. It fills in the structure used to communicate with the process identifier, starts enumerating top-level windows, and returns a window handle. SetLastError and GetLastError calls are SetLastError , since EnumWindows returns FALSE for error and success in this case:
// 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 ) ); }
This will result in the first top-level window corresponding to the given process identifier. Since the requirements indicate that there will only be a single window for this process, the first match corresponds to the correct window.
If additional restrictions exist, EnumProc can be deployed to include them. I noted the place in the implementation above where additional filters can be applied.
Iinspectable
source share