Win32 - 获取主Wnd应用程序的句柄 [英] Win32 - Get Main Wnd Handle of application

查看:176
本文介绍了Win32 - 获取主Wnd应用程序的句柄的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经注入我的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


  1. 致电 GetCurrentProcessId 以获取当前进程的PID

  2. EnumWindows 在桌面的所有顶级窗口上迭代

  3. 对于桌面上的每个窗口,调用
  1. Call GetCurrentProcessId to get the PID of the current process
  2. Call EnumWindows to iterate over all toplevel windows of the desktop
  3. For each window on the desktop, call GetWindowThreadProcessId to 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.

窗口由您注入您的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆