问题描述
我正在寻找在以下情况下获取窗口句柄的最佳方法:
我有进程ID 和进程句柄,我知道窗口标题名称,而且我知道该进程只有一个窗口强>.
I'm looking for the best way to get a Window Handle in the following situation:
I have the process id and process handle, I know the window titlename and I know that the process has only one window.
那我该怎么办呢? FindWindow
? EnumWIndows
?
So how would I do it? FindWindow
? EnumWIndows
?
推荐答案
使用 FindWindow
要求您知道窗口类或窗口标题.两者不一定都是唯一的.由于您已经拥有流程句柄(及其ID),因此可以使用 EnumWindows
.
首先,声明用于通信的结构.它将进程ID传递给枚举过程,并返回窗口句柄.
First, declare a structure used for communication. It passes a process ID 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;
};
接下来,我们需要一个回调过程来检索进程ID( GetWindowThreadProcessId
),然后将其与我们要查找的窗口进行比较:
Next, we need a callback procedure that retrieves the process ID (GetWindowThreadProcessId
) for any given window and compares it to 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;
}
剩下的就是公共接口.它使用进程ID填充用于通信的结构,触发顶级窗口的枚举,并返回窗口句柄.对SetLastError
和在这种情况下,错误和成功都是如此:
What's left is the public interface. It populates the structure used for communication with the process ID, triggers the enumeration of top-level windows, and returns the window handle. The calls to SetLastError
and GetLastError
are required, since EnumWindows
returns FALSE
for both 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 ) );
}
这将检索与给定进程ID匹配的第一个顶级窗口.由于要求指出,给定进程将永远只有一个窗口,因此匹配的第一个窗口是正确的窗口.
This will retrieve the first top-level window that matches a given process ID. Since the requirements state that there will only ever be a single window for the given process, the first one that matches is the correct window.
如果存在其他限制,可以将EnumProc
扩展为包括这些限制.我已经在上面的实现中标记了地点,可以在其中应用其他过滤器.
If additional restrictions exist, EnumProc
can be expanded to include those. I have marked the spot in the implementation above, where additional filters can be applied.
这篇关于C ++:按进程ID,进程句柄和标题名称从进程中获取唯一窗口的窗口句柄的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!