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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20162359/
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-27 22:56:07  来源:igfitidea点击:

C++: Best way to get Window Handle of the only window from a process by process id, process handle and title name

c++winapiwindow-handles

提问by Forivin

I'm looking for the best way to get a Window Handle in the following situation:
I have the process idand process handle, I know the window titlenameand I know that the process has only one window.

我正在寻找在以下情况下获得 Window Handle 的最佳方法:
我有process idprocess handle,我知道window titlename并且我知道 process只有一个 window

So how would I do it? FindWindow? EnumWIndows?

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

回答by IInspectable

Using FindWindowrequires that you either know the window class or the window title. Both of these are not necessarily unique. Since you alread have the process handle (and its ID) you can implement a robust solution using EnumWindows.

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

First, declare a structure used for communication. It passes a process ID to the enumeration procedure and returns the window handle back.

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

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

Next, we need a callback procedure that retrieves the process ID (GetWindowThreadProcessId) for any given window and compares it to the one we are looking for:

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

// 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;
}

What's left is the public interface. It populates the structure used for communication with the process ID, triggers the enumeration of top-level windows, and returns the window handle. The calls to SetLastErrorand GetLastErrorare required, since EnumWindowsreturns FALSEfor both error and success in this case:

剩下的是公共接口。它填充用于与进程 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 ) );
}

This will retrieve the first top-level window that matches a given process ID. Since the requirements state that there will only ever be a single window for the given process, the first one that matches is the correct window.

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

If additional restrictions exist, EnumProccan be expanded to include those. I have marked the spot in the implementation above, where additional filters can be applied.

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