通过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);