問題描述
我已將我的 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
遍歷桌面的所有頂級窗口 - 對于桌面上的每個窗口,調用
GetWindowThreadProcessId代碼>獲取創建窗口的進程的PID
- 如果窗口的 PID 與您自己進程的 PID 匹配,請記住該窗口.
這為您提供了由您注入 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
,其中包含當前進程的所有頂級窗口的句柄.
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 句柄的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!