windows Win32 -获取应用程序的主Wnd句柄

os8fio9y  于 2022-11-18  发布在  Windows
关注(0)|答案(2)|浏览(350)

我已经将我的dll注入到进程中。我如何获得宿主应用程序的主窗口句柄?

8ehkhllq

8ehkhllq1#

宿主应用程序可能有多个“主窗口”。要检测它们,您可以
1.调用GetCurrentProcessId以获取当前进程的PID
1.调用EnumWindows以遍历桌面的所有顶层窗口
1.对于桌面上的每个窗口,调用GetWindowThreadProcessId以获取创建该窗口的进程的PID
1.如果窗口的PID与您自己的进程的PID匹配,请记住该窗口。
这会给你一个顶层窗口的列表,这些窗口是由你注入DLL的进程创建的。但是,请注意,这种方法可能会产生在你处理构建的窗口列表时已经被破坏的窗口。因此,当你对这些窗口做一些事情时,确保使用IsWindow函数来确保当前窗口仍然有效(这仍然容易出现竞争条件,因为在调用IsWindow和实际访问窗口之间,窗口可能变得无效,但时间窗口要小得多)。
下面是一个实现该算法的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;
}

**更新:**这些天(大约在我给出答案的四年后),我也会考虑应用程序的traversing the list of threads,然后在每个线程上使用EnumThreadWindows。我注意到在许多情况下,这要快得多。

aiazj4mn

aiazj4mn2#

小除了前面的回答--主应用程序窗口没有父窗口,所以GetParent()将为它返回零。

相关问题