EnumWindows枚举屏幕上的所有顶层窗口,不包括子窗口
BOOL EnumWindows(WNDENUMPROC lpEnumFunc,LPARAM lParam);
第一个参数是WNDENUMPROC类型的回调函数,每个枚举窗口都会被调用一次,而且会把窗口的句柄作为参数传给该回调函数,如果该回调函数返回FALSE则停止枚举
第二个参数可以传入我们自定义的数据,这里传入一个包含进程号和窗口句柄的结构,进程号假设已经获取到,在找到该进程号对应的窗口时将窗口句柄赋值给该结构的句柄变量
回调函数的形式
BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam);
第一个参数为窗口句柄,第二个参数是传给EnumWindows的lParam参数
struct ProcessWindowData
HWND hWnd;
unsigned long lProcessId;
BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
ProcessWindowData& wndData = *(ProcessWindowData*)lParam;
unsigned long lProcessId = 0;
::GetWindowThreadProcessId(hWnd, &lProcessId);
if ((wndData.lProcessId != lProcessId) || (::GetWindow(hWnd, GW_OWNER) != (HWND)0) || !::IsWindowVisible(hWnd))
return TRUE;
wndData.hWnd = hWnd;
return FALSE;
HWND GetMainWindowHwnd(unsigned long lProcessId)
ProcessWindowData wndData;
wndData.hWnd = 0;
wndData.lProcessId = lProcessId;
::EnumWindows(EnumWindowsProc, (LPARAM)&wndData);
return wndData.hWnd;
如果要枚举指定桌面的窗口可以使用EnumDesktopWindows
EnumWindows枚举屏幕上的所有顶层窗口,不包括子窗口BOOL EnumWindows(WNDENUMPROC lpEnumFunc,LPARAM lParam);第一个参数是WNDENUMPROC类型的回调函数,每个枚举窗口都会被调用一次,而且会把窗口的句柄作为参数传给该回调函数,如果该回调函数返回FALSE则停止枚举第二个参数可以传入我们自定义的数据,这里传入一个包含进程号和窗口句...
如题,如何遍历寻找指定进程?如何通过进程ID获取窗口句柄?HWND与CWnd之间是如何转换的?
1、HWND与CWnd之间的转换:使用 GetSafeHwnd 和 CWnd::FromHandle
// 已知 CWnd 获取 HWND
CWnd* pCWnd;
HWND hwnd = pCWnd->m_hWnd;
HWND hwnd1 = pCWnd->GetSafeHwnd();
// 已知 HWND 获取 CWnd
HWND hwnd2;
CWnd* pCwnd1 = CW
很多文章介绍获取UE4主窗口都是通过GetActiveWindow或者FindWindow等方法,这种方法不是很方便,也不准确。
可以通过UEngine的Viewport获取NativeWindow来得到UE4的主窗口句柄,通过句柄可以调用WINAPI函数来修改窗口风格等。
调用Windows窗口函数需要包含以下头文件和编译模块。
引用头文件
# include <windows/WindowsWindow.h>
#include "Windows/AllowWindowsPlatform
基于Arduino智能节水灌溉项目,原理+PCB图+源码等开源.zip基于Arduino智能节水灌溉项目,原理+PCB图+源码等开源.zip基于Arduino智能节水灌溉项目,原理+PCB图+源码等开源.zip基于Arduino智能节水灌溉项目,原理+PCB图+源码等开源.zip基于Arduino智能节水灌溉项目,原理+PCB图+源码等开源.zip基于Arduino智能节水灌溉项目,原理+PCB图+源码等开源.zip基于Arduino智能节水灌溉项目,原理+PCB图+源码等开源.zip基于Arduino智能节水灌溉项目,原理+PCB图+源码等开源.zip基于Arduino智能节水灌溉项目,原理+PCB图+源码等开源.zip基于Arduino智能节水灌溉项目,原理+PCB图+源码等开源.zip基于Arduino智能节水灌溉项目,原理+PCB图+源码等开源.zip基于Arduino智能节水灌溉项目,原理+PCB图+源码等开源.zip基于Arduino智能节水灌溉项目,原理+PCB图+源码等开源.zip基于Arduino智能节水灌溉项目,原理+PCB图+源码等开源.zip基于Arduino智
1. 使用进程的ID获取进程句柄,可以使用函数OpenProcess()。
2. 使用函数EnumWindows()枚举所有的顶层窗口,获取每个窗口的进程ID,使用函数GetWindowThreadProcessId()。
3. 比对每个窗口的进程ID是否与目标进程的ID匹配,如果匹配则说明该窗口属于目标进程。
4. 使用函数IsWindowVisible()判断该窗口是否可见。
5. 如果窗口可见,则说明该窗口是目标进程的主窗口,可以使用该窗口的句柄作为进程的窗口界面句柄。
以下是示例代码:
DWORD dwProcessId = ...; // 目标进程的ID
// 获取目标进程的句柄
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessId);
if (hProcess == NULL) {
// 处理错误
return;
// 枚举所有窗口
HWND hWnd = NULL;
while ((hWnd = FindWindowEx(NULL, hWnd, NULL, NULL)) != NULL) {
// 获取窗口所属进程的ID
DWORD dwThreadId = GetWindowThreadProcessId(hWnd, NULL);
if (dwThreadId == 0) {
// 处理错误
continue;
DWORD dwWindowProcessId = GetProcessIdOfThread(OpenThread(THREAD_QUERY_INFORMATION, FALSE, dwThreadId));
if (dwWindowProcessId == 0) {
// 处理错误
continue;
if (dwWindowProcessId != dwProcessId) {
// 不是目标进程的窗口,继续枚举
continue;
// 判断窗口是否可见
if (!IsWindowVisible(hWnd)) {
// 窗口不可见,继续枚举
continue;
// 该窗口是目标进程的主窗口,作为进程的窗口界面句柄
HWND hProcessWindow = hWnd;
break;
// 关闭目标进程的句柄
CloseHandle(hProcess);
注意:如果目标进程有多个窗口,则该方法只能获取到其中一个窗口的句柄,需要根据实际情况选择。