gpt4 book ai didi

c++ - Win32 - 获取应用程序的主窗口句柄

转载 作者:可可西里 更新时间:2023-11-01 12:42:13 24 4
gpt4 key购买 nike

我已经将我的 dll 注入(inject)到进程中。如何获取主机应用程序的主窗口句柄?

最佳答案

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

  1. 调用 GetCurrentProcessId 获取当前进程的PID
  2. 调用 EnumWindows 遍历桌面的所有顶层窗口
  3. 对于桌面上的每个窗口,调用 GetWindowThreadProcessId 获取创建窗口的进程的 PID
  4. 如果窗口的 PID 与您自己进程的 PID 匹配,则记住该窗口。

这会为您提供由您将 DLL 注入(inject)到的进程创建的顶层窗口列表。但是,请注意,这种方法可能会产生在您处理构建的窗口列表时已被销毁的窗口。因此,在对 Windows 进行操作时,请确保使用 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 在每个线程上。我注意到在许多情况下这要快得多。

关于c++ - Win32 - 获取应用程序的主窗口句柄,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6202547/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com