C++ 遍历寻找指定进程,通过进程ID获取窗口句柄,以及HWND与CWnd之间转换

问题:

如题,如何遍历寻找指定进程?如何通过进程ID获取窗口句柄?HWND与CWnd之间是如何转换的?

解决:

1、HWND与CWnd之间的转换:使用 GetSafeHwndCWnd::FromHandle

// 已知 CWnd 获取 HWND
CWnd* pCWnd;
HWND hwnd = pCWnd->m_hWnd;
HWND hwnd1 = pCWnd->GetSafeHwnd();

// 已知 HWND 获取 CWnd
HWND hwnd2;
CWnd* pCwnd1 = CWnd::FromHandle(hwnd2);

2、如何遍历寻找指定进程:使用 EnumWindows

// 这里以匹配进程名称 Test Process 为例
::EnumWindows([](HWND hwnd, LPARAM lparam) ->BOOL {
	wchar_t winText[256];
	::GetWindowText(hwnd, winText, 255);
	CString winStr = winText;
	if (winStr.IsEmpty())
		return TRUE; //!< 继续遍历

	if(winStr.Compare(_T("Test Process")) == 0)
		return FALSE;//结束遍历
	
	return TRUE; //!< 继续遍历
}, NULL);

还可以加以判断是否是当前进程,寻找当前进程之外的指定进程:使用 _getpidGetWindowThreadProcessId

	//......
	if(winStr.Compare(_T("Test Process")) == 0)
	{
		DWORD dwId = 0;
		GetWindowThreadProcessId(hwnd, &dwId);
		if (_getpid() == dwId)
			return TRUE;// 是当前进程,继续遍历
		return FALSE;//结束遍历
	}
	//......

3、获取指定进程ID的窗口句柄:使用CALLBACKEnumWindowsstruct

//自定义枚举进程参数
typedef struct  
{
	HWND	hwnd;
	DWORD	processId;
}WindowsArg;

//回调函数
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lparam)
{
	WindowsArg * pArg = (WindowsArg *)lparam;

	DWORD dwId = 0;
	GetWindowThreadProcessId(hwnd, &dwId);
	if (pArg.processId == dwId)
	{
		pArg->hwnd = hwnd;
		return FALSE;//匹配进程ID成功,结束遍历
	}

	return TRUE; //!< 继续遍历
}

//通过进程ID获取窗口句柄
HWND GetHwndByProcessId(DWORD processId)
{
	HWND hwndRet = NULL;
	WindowsArg wa;
	wa.processId = processId;
	wa.hwnd = NULL;
	EnumWindows(EnumWindowsProc, (LPARAM)&wa);
	if (wa.hwnd)
		hwndRet = wa.hwnd;
	return hwndRet ;
}
  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++ 中,可以使用 Windows API 函数来实现遍历进程、查找指定进程、查找指定句柄、关闭指定句柄的功能。示例代码如下: ```c++ #include <windows.h> #include <iostream> #include <tchar.h> BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) { DWORD processId; GetWindowThreadProcessId(hwnd, &processId); if (processId == *((DWORD*)lParam)) { // 找到了指定进程 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId); if (hProcess == NULL) { std::cout << "OpenProcess failed: " << GetLastError() << std::endl; return FALSE; } // 遍历进程中的句柄,查找指定句柄 HANDLE hHandle = NULL; for (DWORD i = 0; i < 65536; i++) { hHandle = (HANDLE)i; if (DuplicateHandle(hProcess, hHandle, GetCurrentProcess(), &hHandle, 0, FALSE, DUPLICATE_SAME_ACCESS)) { TCHAR lpFileName[MAX_PATH]; if (GetFinalPathNameByHandle(hHandle, lpFileName, MAX_PATH, VOLUME_NAME_NT)) { if (_tcsstr(lpFileName, _T("\\Device\\HarddiskVolume2\\path\\to\\file")) != NULL) { // 找到了指定句柄,关闭句柄 if (!CloseHandle(hHandle)) { std::cout << "CloseHandle failed: " << GetLastError() << std::endl; } } } CloseHandle(hHandle); } } CloseHandle(hProcess); return FALSE; } return TRUE; } int main() { // 遍历所有窗口,查找指定进程 DWORD processId = 1234; EnumWindows(EnumWindowsProc, (LPARAM)&processId); return 0; } ``` 其中,1234 是要查找的进程 ID,_T("\\Device\\HarddiskVolume2\\path\\to\\file") 是要关闭的句柄对应的文件路径。遍历进程中的句柄可以使用 DuplicateHandle() 函数,获取句柄对应的文件路径可以使用 GetFinalPathNameByHandle() 函数。如果找到了指定句柄,可以使用 CloseHandle() 函数关闭句柄。注意要在关闭句柄之前使用 DuplicateHandle() 函数复制句柄,以避免关闭了错误的句柄
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值