【问题标题】:C++: Best way to get Window Handle of the only window from a process by process id, process handle and title name [duplicate]C ++:通过进程ID,进程句柄和标题名称从进程中获取唯一窗口的窗口句柄的最佳方法[重复]
【发布时间】:2013-12-08 08:47:19
【问题描述】:

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

那我该怎么做呢? FindWindow? EnumWIndows?

【问题讨论】:

  • 是的,EnumWindows 是你的朋友。这跟效率有什么关系?你需要每秒做几百万次吗?
  • 我只是想学习以正确的方式去做。有问题吗? oO
  • 一点也不。这是正确的方法。
  • 顺便说一句,这不是重复的。我不是在寻找任何方法来获得窗户把手!我正在为我的特殊情况寻找最佳方法。 ...所以 EnumWindows 是最有效的一个是吗?
  • 它是重复的。您的特定情况与链接问题中的情况相同,但附加限制不会产生影响。但是,上一个问题的答案只是提供了基本的指导,并不是一个功能齐全的解决方案,所以这个问题不应该被关闭。

标签: c++ winapi window-handles


【解决方案1】:

使用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;
}

剩下的是公共接口。它填充用于与进程 ID 通信的结构,触发顶级窗口的枚举,并返回窗口句柄。对SetLastErrorGetLastError 的调用是必需的,因为在这种情况下,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 可以扩展以包含这些限制。我在上面的实现中标记了可以应用其他过滤器的位置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-25
    • 2012-05-06
    • 2011-03-02
    相关资源
    最近更新 更多