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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 19:40:41  来源:igfitidea点击:

Win32 - Get Main Wnd Handle of application

c++windowswinapi

提问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

宿主应用程序可能有多个“主窗口”。要检测它们,您可以

  1. Call GetCurrentProcessIdto get the PID of the current process
  2. Call EnumWindowsto iterate over all toplevel windows of the desktop
  3. For each window on the desktop, call GetWindowThreadProcessIdto get the PID of the process which created the window
  4. If the PID of the window matches the PID of your own process, memorize the window.
  1. 调用GetCurrentProcessId获取当前进程的PID
  2. 调用EnumWindows以遍历桌面的所有顶级窗口
  3. 对于桌面上的每个窗口,调用GetWindowThreadProcessId以获取创建该窗口的进程的 PID
  4. 如果窗口的 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 IsWindowfunction 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 IsWindowand 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 getToplevelWindowsfunction 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 EnumThreadWindowson each thread. I noticed that this is considerably faster in many cases.

更新:这些天(在我给出答案大约四年后)我还会考虑遍历应用程序的线程列表,然后EnumThreadWindows在每个线程上使用。我注意到这在许多情况下要快得多。