Win32 - 获取主Wnd应用程序的句柄 [英] Win32 - Get Main Wnd Handle of application
问题描述
我已经注入我的dll进程。
如何获取主机应用程序的主窗口句柄?
I have injected my dll into process. How can I get Main window handle of host application?
推荐答案
主机应用程序可能有多个 。要检测它们,您可以
The host application may have multiple 'main windows'. To detect them, you could
- 致电
GetCurrentProcessId
以获取当前进程的PID -
EnumWindows
在桌面的所有顶级窗口上迭代 - 对于桌面上的每个窗口,调用
- 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.
窗口由您注入您的DLL进程创建。但是,请注意,这种方法可能会产生在处理构造的窗口列表时被销毁的窗口。因此,在使用Windows执行操作时,请务必使用 IsWindow
函数,以确保手边的窗口仍然有效(这仍然容易出现竞争条件,因为窗口可能会在您调用之间变得无效) IsWindow
并实际访问窗口,但时间窗口小得多)。
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).
这是一个C ++函数实现这个算法。它实现了一个 getToplevelWindows
函数,它产生一个 std :: vector< HWND>
当前过程。
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.
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;
}
更新:我给了答案)我也会考虑遍历的列表线程,然后使用 EnumThreadWindows
。我注意到,在很多情况下,这是相当快。
UPDATE: These days (about four years after I gave the answer) I would also consider traversing the list of threads of the application and then using EnumThreadWindows
on each thread. I noticed that this is considerably faster in many cases.
这篇关于Win32 - 获取主Wnd应用程序的句柄的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!