我正在寻找在以下情况下获取 Window Handle 的最佳方法:
我有进程 id和进程句柄,我知道窗口标题名称并且我知道该进程只有一个 window。
那么我该怎么做呢?FindWindow
? EnumWIndows
?
我正在寻找在以下情况下获取 Window Handle 的最佳方法:
我有进程 id和进程句柄,我知道窗口标题名称并且我知道该进程只有一个 window。
那么我该怎么做呢?FindWindow
? EnumWIndows
?
使用FindWindow
要求您知道窗口类或窗口标题。这两者不一定是唯一的。由于您已经拥有进程句柄(及其 ID),因此您可以使用EnumWindows
.
首先,声明一个用于通信的结构。它将进程 ID 传递给枚举过程并返回窗口句柄。
// Structure used to communicate data from and to enumeration procedure
struct EnumData {
DWORD dwProcessId;
HWND hWnd;
};
接下来,我们需要一个回调过程来检索GetWindowThreadProcessId
任何给定窗口的进程 ID (),并将其与我们正在寻找的那个进行比较:
// 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 匹配的第一个顶级窗口。由于要求规定给定进程只会有一个窗口,因此第一个匹配的窗口是正确的窗口。
如果存在其他限制,EnumProc
可以扩展以包括这些限制。我在上面的实现中标记了可以应用其他过滤器的位置。