C++ Win32 - 获取应用程序的主 Wnd 句柄
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6202547/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Win32 - Get Main Wnd Handle of application
提问by Hooch
I have injected my dll into process. How can I get Main window handle of host application?
我已将我的 dll 注入进程。如何获取主机应用程序的主窗口句柄?
回答by Frerich Raabe
The host application may have multiple 'main windows'. To detect them, you could
宿主应用程序可能有多个“主窗口”。要检测它们,您可以
- Call
GetCurrentProcessId
to get the PID of the current process - Call
EnumWindows
to iterate over all toplevel windows of the desktop - For each window on the desktop, call
GetWindowThreadProcessId
to get the PID of the process which created the window - If the PID of the window matches the PID of your own process, memorize the window.
- 调用
GetCurrentProcessId
获取当前进程的PID - 调用
EnumWindows
以遍历桌面的所有顶级窗口 - 对于桌面上的每个窗口,调用
GetWindowThreadProcessId
以获取创建该窗口的进程的 PID - 如果窗口的 PID 与您自己进程的 PID 匹配,请记住该窗口。
That gives you a list of toplevel windows created by the process which you injected your DLL into. However, please note that this approach may yield windows which have been destroyed by the time you process the constructed list of windows. Hence, when doing something with the windows, make sure to use the IsWindow
function to ensure that the window at hand is still valid (this is still prone to race conditions since the window may become invalid between your call to IsWindow
and actually accessing the window, but the time window is much smaller).
这为您提供了由您注入 DLL 的进程创建的顶级窗口列表。但是,请注意,这种方法可能会产生在您处理构建的窗口列表时已被破坏的窗口。因此,在对窗口执行某些操作时,请确保使用该IsWindow
函数来确保手头的窗口仍然有效(这仍然容易出现竞争条件,因为在您调用IsWindow
窗口和实际访问窗口之间该窗口可能变得无效,但是时间窗口要小得多)。
Here's a C++ function implementing this algorithm. It implements a getToplevelWindows
function which yields a std::vector<HWND>
containing the handles of all toplevel windows of the current process.
这是一个实现该算法的 C++ 函数。它实现了一个getToplevelWindows
函数,该函数产生一个std::vector<HWND>
包含当前进程的所有顶级窗口的句柄。
struct EnumWindowsCallbackArgs {
EnumWindowsCallbackArgs( DWORD p ) : pid( p ) { }
const DWORD pid;
std::vector<HWND> handles;
};
static BOOL CALLBACK EnumWindowsCallback( HWND hnd, LPARAM lParam )
{
EnumWindowsCallbackArgs *args = (EnumWindowsCallbackArgs *)lParam;
DWORD windowPID;
(void)::GetWindowThreadProcessId( hnd, &windowPID );
if ( windowPID == args->pid ) {
args->handles.push_back( hnd );
}
return TRUE;
}
std::vector<HWND> getToplevelWindows()
{
EnumWindowsCallbackArgs args( ::GetCurrentProcessId() );
if ( ::EnumWindows( &EnumWindowsCallback, (LPARAM) &args ) == FALSE ) {
// XXX Log error here
return std::vector<HWND>();
}
return args.handles;
}
UPDATE:These days (about four years after I gave the answer) I would also consider traversing the list of threadsof the application and then using EnumThreadWindows
on each thread. I noticed that this is considerably faster in many cases.
更新:这些天(在我给出答案大约四年后)我还会考虑遍历应用程序的线程列表,然后EnumThreadWindows
在每个线程上使用。我注意到这在许多情况下要快得多。