C++:通过进程ID、进程句柄和标题名称从进程中获取唯一窗口的窗口句柄的最佳方法

标签 c++ winapi window-handles

<分区>

我正在寻找在以下情况下获取窗口句柄的最佳方法:
我有进程 ID进程句柄,我知道窗口标题名,我知道该进程只有一个窗口强>.

那我该怎么做呢? 查找窗口EnumWIndows?

最佳答案

使用 FindWindow要求您知道窗口类或窗口标题。这两者不一定是唯一的。由于您已经拥有进程句柄(及其 ID),因此您可以使用 EnumWindows 实现强大的解决方案.

首先,声明一个用于通信的结构体。它将进程 ID 传递给枚举过程并返回窗口句柄。

// Structure used to communicate data from and to enumeration procedure
struct EnumData {
    DWORD dwProcessId;
    HWND hWnd;
};

接下来,我们需要一个回调过程来检索任何给定窗口的进程 ID (GetWindowThreadProcessId),并将其与我们正在寻找的进行比较:

// Application-defined callback for EnumWindows
BOOL CALLBACK EnumProc( HWND hWnd, LPARAM lParam ) {
    // Retrieve storage location for communication data
    EnumData& ed = *(EnumData*)lParam;
    DWORD dwProcessId = 0x0;
    // Query process ID for hWnd
    GetWindowThreadProcessId( hWnd, &dwProcessId );
    // Apply filter - if you want to implement additional restrictions,
    // this is the place to do so.
    if ( ed.dwProcessId == dwProcessId ) {
        // Found a window matching the process ID
        ed.hWnd = hWnd;
        // Report success
        SetLastError( ERROR_SUCCESS );
        // Stop enumeration
        return FALSE;
    }
    // Continue enumeration
    return TRUE;
}

剩下的就是公共(public)接口(interface)。它填充用于与进程 ID 通信的结构,触发顶级窗口的枚举,并返回窗口句柄。对 SetLastError 的调用和 GetLastError是必需的,因为在这种情况下 EnumWindows 对错误和成功都返回 FALSE:

// Main entry
HWND FindWindowFromProcessId( DWORD dwProcessId ) {
    EnumData ed = { dwProcessId };
    if ( !EnumWindows( EnumProc, (LPARAM)&ed ) &&
         ( GetLastError() == ERROR_SUCCESS ) ) {
        return ed.hWnd;
    }
    return NULL;
}

// Helper method for convenience
HWND FindWindowFromProcess( HANDLE hProcess ) {
    return FindWindowFromProcessId( GetProcessId( hProcess ) );
}

这将检索与给定进程 ID 匹配的第一个顶级窗口。由于要求规定给定进程只会有一个窗口,因此第一个匹配的是正确的窗口。

如果存在其他限制,EnumProc 可以扩展以包含这些限制。我在上面的实现中标记了可以应用其他过滤器的位置。

关于C++:通过进程ID、进程句柄和标题名称从进程中获取唯一窗口的窗口句柄的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20162359/

相关文章:

windows - Windows 编程中的 _spawnl 和 Createprocess(...) API 有什么区别?

java - 如果在单个窗口中打开多个选项卡,getWindowHandles 返回一个窗口句柄

c# - 我可以在没有窗口的情况下发送/接收窗口消息吗?

c++ - 连接函数错误 10047 (winsock2)

c++ - 为什么调用closesock后socket accept函数不释放?

c++ - OpenCV:设置图像边框,无填充

c++ - 移除 stdc++ 库依赖

c++ - 执行时动态库链接

python - 在 Python 中使用 Selenium 抓取 JavaScript 呈现的内容

c++ - 有没有办法在 C++ 中将 auto 作为参数传递?