我已经将我的dll注入到进程中。我如何获得宿主应用程序的主窗口句柄?
8ehkhllq1#
宿主应用程序可能有多个“主窗口”。要检测它们,您可以1.调用GetCurrentProcessId以获取当前进程的PID1.调用EnumWindows以遍历桌面的所有顶层窗口1.对于桌面上的每个窗口,调用GetWindowThreadProcessId以获取创建该窗口的进程的PID1.如果窗口的PID与您自己的进程的PID匹配,请记住该窗口。这会给你一个顶层窗口的列表,这些窗口是由你注入DLL的进程创建的。但是,请注意,这种方法可能会产生在你处理构建的窗口列表时已经被破坏的窗口。因此,当你对这些窗口做一些事情时,确保使用IsWindow函数来确保当前窗口仍然有效(这仍然容易出现竞争条件,因为在调用IsWindow和实际访问窗口之间,窗口可能变得无效,但时间窗口要小得多)。下面是一个实现该算法的C++函数,它实现了一个getToplevelWindows函数,该函数生成一个std::vector<HWND>,其中包含当前进程的所有顶层窗口的句柄。
GetCurrentProcessId
EnumWindows
GetWindowThreadProcessId
IsWindow
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; }
**更新:**这些天(大约在我给出答案的四年后),我也会考虑应用程序的traversing the list of threads,然后在每个线程上使用EnumThreadWindows。我注意到在许多情况下,这要快得多。
EnumThreadWindows
aiazj4mn2#
小除了前面的回答--主应用程序窗口没有父窗口,所以GetParent()将为它返回零。
2条答案
按热度按时间8ehkhllq1#
宿主应用程序可能有多个“主窗口”。要检测它们,您可以
1.调用
GetCurrentProcessId
以获取当前进程的PID1.调用
EnumWindows
以遍历桌面的所有顶层窗口1.对于桌面上的每个窗口,调用
GetWindowThreadProcessId
以获取创建该窗口的进程的PID1.如果窗口的PID与您自己的进程的PID匹配,请记住该窗口。
这会给你一个顶层窗口的列表,这些窗口是由你注入DLL的进程创建的。但是,请注意,这种方法可能会产生在你处理构建的窗口列表时已经被破坏的窗口。因此,当你对这些窗口做一些事情时,确保使用
IsWindow
函数来确保当前窗口仍然有效(这仍然容易出现竞争条件,因为在调用IsWindow
和实际访问窗口之间,窗口可能变得无效,但时间窗口要小得多)。下面是一个实现该算法的C++函数,它实现了一个
getToplevelWindows
函数,该函数生成一个std::vector<HWND>
,其中包含当前进程的所有顶层窗口的句柄。**更新:**这些天(大约在我给出答案的四年后),我也会考虑应用程序的traversing the list of threads,然后在每个线程上使用
EnumThreadWindows
。我注意到在许多情况下,这要快得多。aiazj4mn2#
小除了前面的回答--主应用程序窗口没有父窗口,所以GetParent()将为它返回零。