C ++: the best way to get the Window Handle of a single window from a process using a process identifier, a process descriptor, and a title name

I am looking for a better way to get a Window Handle in the following situation:
I have a process id and , I know the titlename window , and I know that the process has only one strong> window .

So how would I do that? FindWindow ? EnumWIndows ?

+7
c ++ winapi window-handles
source share
1 answer

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.

+11
source share

All Articles