通过Windows进程ID获取窗口句柄

xingyun86 2018-7-1 1810


通过Windows进程ID获取窗口句柄

通过Windows进程ID获取窗口句柄
方法一:使用EnumWindows的方式

///< 枚举窗口参数
typedef struct
{
    HWND    hwndWindow;     // 窗口句柄
    DWORD   dwProcessID;    // 进程ID
}EnumWindowsArg;
///< 枚举窗口回调函数
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
    EnumWindowsArg *pArg = (EnumWindowsArg *)lParam;
    DWORD  dwProcessID = 0;
    // 通过窗口句柄取得进程ID
    ::GetWindowThreadProcessId(hwnd, &dwProcessID);
    if (dwProcessID == pArg->dwProcessID)
    {
        pArg->hwndWindow = hwnd;
        // 找到了返回FALSE
        return FALSE;
    }
    // 没找到,继续找,返回TRUE
    return TRUE;
}
///< 通过进程ID获取窗口句柄
HWND CProcessTimeRestart::GetWindowHwndByPID(DWORD dwProcessID)
{
    HWND hwndRet = NULL;
    EnumWindowsArg ewa;
    ewa.dwProcessID = dwProcessID;
    ewa.hwndWindow = NULL;
    EnumWindows(EnumWindowsProc, (LPARAM)&ewa);
    if (ewa.hwndWindow)
    {
        hwndRet = ewa.hwndWindow;
    }
    return hwndRet;
}

方法二:使用GetTopWindow和GetNextWindow的方式

///< 通过进程ID获取窗口句柄
HWND CProcessTimeRestart::GetWindowHwndByPorcessID(DWORD dwProcessID)
{
    DWORD dwPID = 0;
    HWND hwndRet = NULL;
    // 取得第一个窗口句柄
    HWND hwndWindow = ::GetTopWindow(0);
    while (hwndWindow)
    {
        dwPID = 0;
        // 通过窗口句柄取得进程ID
        DWORD dwTheardID = ::GetWindowThreadProcessId(hwndWindow, &dwPID);
        if (dwTheardID != 0)
        {
            // 判断和参数传入的进程ID是否相等
            if (dwPID == dwProcessID)
            {
                // 进程ID相等,则记录窗口句柄
                hwndRet = hwndWindow;
                break;
            }
        }
        // 取得下一个窗口句柄
        hwndWindow = ::GetNextWindow(hwndWindow, GW_HWNDNEXT);
    }
    // 上面取得的窗口,不一定是最上层的窗口,需要通过GetParent获取最顶层窗口
    HWND hwndWindowParent = NULL;
    // 循环查找父窗口,以便保证返回的句柄是最顶层的窗口句柄
    while (hwndRet != NULL)
    {
        hwndWindowParent = ::GetParent(hwndRet);
        if (hwndWindowParent == NULL)
        {
            break;
        }
        hwndRet = hwndWindowParent;
    }
    // 返回窗口句柄
    return hwndRet;
}

=======================================================================
__inline static
void EnumWindows(int(*cb)(HWND, void*) = NULL, void* pv = NULL, HWND hWnd = ::GetDesktopWindow())
{
    for (HWND hWndNext = ::GetWindow(hWnd, GW_CHILD); (hWndNext != NULL); hWndNext = ::GetWindow(hWndNext, GW_HWNDNEXT))if (cb != NULL && cb(hWndNext, pv) == 0)break;
}
__inline static
void EnumVisibleWindows(int(*cb)(HWND, void*) = NULL, void* pv = NULL, HWND hWnd = ::GetDesktopWindow())
{
    for (HWND hWndNext = ::GetWindow(hWnd, GW_CHILD); (hWndNext != NULL); hWndNext = ::GetWindow(hWndNext, GW_HWNDNEXT))if (::IsWindowVisible(hWndNext) == TRUE)if (cb != NULL && cb(hWndNext, pv) == 0)break;
}

通过以上两种窗口获得的句柄,和使用FindWindow获得的句柄是一样的。
可以通过SendMessage向窗口发送消息

HWND hwnd = ::FindWindow(NULL, "Test");
::SendMessage(hwnd, WM_CLOSE, 0, 0);



×
打赏作者
最新回复 (0)
只看楼主
全部楼主
返回