[窗口] SetWindowsHookEx 监控窗口消息

本文探讨了如何通过Windows API中的SetWindowsHookEx函数实现监控自身窗口消息,并介绍了DLL注入技术,用于监听指定窗口的消息。作者展示了如何在DLL中捕获和处理窗口消息,以及如何在exe中调用这些处理函数。
摘要由CSDN通过智能技术生成

监控自身窗口消息

意义不大,因为自身的窗口消息完全可以用消息循环捕获。

(exe)

#include <iostream>
#include <Windows.h>
using namespace std;

LRESULT CALLBACK __WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {

	PAINTSTRUCT ps;
	HDC hdc;
	switch (msg) {
		// 完全可以在这里添加消息处理代码 ,取代 SetWindowsHookEx
	default:
		break;
	}

	return DefWindowProc(hWnd, msg, wParam, lParam);
}

HHOOK glhHook = NULL;
HINSTANCE glhInstance = GetModuleHandle(0);
LRESULT WINAPI __HookProc(int nCode, WPARAM wparam, LPARAM lparam) {

	PCWPSTRUCT pcs = (PCWPSTRUCT)lparam;

	// 消息类型和对应的附加信息
	cout << "message:" << pcs->message << endl;
	cout << "lParam:" << pcs->lParam << endl;
	cout << "wParam:" << pcs->wParam << endl;
	cout << "-------------------" << endl;

	return CallNextHookEx(glhHook, nCode, wparam, lparam);
}


int main()
{
	// 窗口属性初始化
	HINSTANCE hIns = GetModuleHandle(0);
	WNDCLASSEX wc;
	wc.cbSize = sizeof(wc);								// 定义结构大小
	wc.style = CS_HREDRAW | CS_VREDRAW;					// 如果改变了客户区域的宽度或高度,则重新绘制整个窗口 
	wc.cbClsExtra = 0;									// 窗口结构的附加字节数
	wc.cbWndExtra = 0;									// 窗口实例的附加字节数
	wc.hInstance = hIns;								// 本模块的实例句柄
	wc.hIcon = NULL;									// 图标的句柄
	wc.hIconSm = NULL;									// 和窗口类关联的小图标的句柄
	wc.hbrBackground = (HBRUSH)COLOR_WINDOW;			// 背景画刷的句柄
	wc.hCursor = NULL;									// 光标的句柄
	wc.lpfnWndProc = __WndProc;							// 窗口处理函数的指针
	wc.lpszMenuName = NULL;								// 指向菜单的指针
	wc.lpszClassName = L"LYSM_class";					// 指向类名称的指针

	// 为窗口注册一个窗口类
	if (!RegisterClassEx(&wc)) {
		cout << "RegisterClassEx error : " << GetLastError() << endl;
	}

	// 创建窗口
	HWND hWnd = CreateWindowEx(
		WS_EX_LTRREADING,			// 窗口扩展样式:默认
		L"LYSM_class",				// 窗口类名
		L"LYSM_title",				// 窗口标题
		WS_OVERLAPPEDWINDOW,		// 窗口样式:重叠窗口
		0,							// 窗口初始x坐标
		0,							// 窗口初始y坐标
		800,						// 窗口宽度
		600,						// 窗口高度
		0,							// 父窗口句柄
		0,							// 菜单句柄 
		hIns,						// 与窗口关联的模块实例的句柄
		0							// 用来传递给窗口WM_CREATE消息
	);
	if (hWnd == 0) {
		cout << "CreateWindowEx error : " << GetLastError() << endl;
	}
	UpdateWindow(hWnd);
	ShowWindow(hWnd, SW_SHOW);


	// 监听自己的消息
	glhHook = SetWindowsHookEx(WH_CALLWNDPROC,__HookProc, glhInstance, GetCurrentThreadId());
	if (NULL == glhHook) {
		cout << "SetWindowsHookEx error : " << GetLastError() << endl;
	}

	// 消息循环(没有会导致窗口卡死)
	MSG msg = { 0 };
	while (msg.message != WM_QUIT) {
		// 从消息队列中删除一条消息
		if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
			DispatchMessage(&msg);
		}
	}


	cout << "finished." << endl;
	getchar();
end:

	getchar();
	return 0;
}

监控其他窗口消息

(dll)
因为只需要 dll 的一个导出函数,所以创建一个空的 dll 项目即可。 log.h 的内容参考这里

#include "log.h"
#include <Windows.h>

extern "C" __declspec(dllexport) LRESULT CALLBACK HookWndProc(int nCode, WPARAM wParam, LPARAM lParam) {


    PCWPSTRUCT pcs = (PCWPSTRUCT)lParam;

    // 消息类型和对应的附加信息
    DP3("[LYSM] message:%d ,lParam:%d , wParam:%d \n", pcs->message, pcs->lParam, pcs->wParam);


    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

因为编译器的问题,导出函数的名字和原本的函数名会有不同,如下:
在这里插入图片描述


(exe)

#include <iostream>
#include <Windows.h>
using namespace std;


VOID DoInject(DWORD TargetWindowThreadId)
{
	HMODULE hDll = LoadLibrary(L"D:\\MyCode\\Test_Dll_1\\Debug\\Test_Dll_1.dll");
	if (hDll == NULL) {
		cout << "LoadLibrary error : " << GetLastError() << endl;
		return;
	}

	FARPROC KeyboardProc = (FARPROC)GetProcAddress(hDll, "_HookWndProc@12");
	if (KeyboardProc == NULL) {
		cout << "GetProcAddress error : " << GetLastError() << endl;
		return;
	}

	HHOOK g_hHook = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)KeyboardProc, hDll, TargetWindowThreadId);
	if (!g_hHook) {
		cout << "SetWindowsHookEx error : " << GetLastError() << endl;
		return;
	}

}

int main()
{
	// 传入监听窗口的线程ID,为了方便测试我写死了。
	DoInject(10516);

	cout << "finished." << endl;
	getchar();
end:

	getchar();
	return 0;
}

效果图:
在这里插入图片描述

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的C++窗口钩子的示例代码: ```cpp #include <iostream> #include <Windows.h> // 窗口钩子回调函数 LRESULT CALLBACK WindowHookCallback(int nCode, WPARAM wParam, LPARAM lParam) { // 判断事件类型 if (nCode == HC_ACTION) { // 获取窗口消息结构体 CWPSTRUCT* pMsg = (CWPSTRUCT*)lParam; // 判断消息类型 if (pMsg->message == WM_ACTIVATE) { // 窗口激活事件发生时执行自定义逻辑 std::cout << "Window activated!" << std::endl; } } // 调用下一个钩子或者默认处理 return CallNextHookEx(NULL, nCode, wParam, lParam); } int main() { // 安装窗口钩子 HHOOK hHook = SetWindowsHookEx(WH_CALLWNDPROC, WindowHookCallback, NULL, 0); if (hHook == NULL) { std::cout << "Failed to install window hook!" << std::endl; return 1; } // 进入消息循环 MSG msg; while (GetMessage(&msg, NULL, 0, 0) > 0) { TranslateMessage(&msg); DispatchMessage(&msg); } // 卸载窗口钩子 UnhookWindowsHookEx(hHook); return 0; } ``` 上述示例代码演示了如何使用`SetWindowsHookEx`函数安装窗口钩子,并在窗口激活事件发生时执行自定义逻辑。需要注意的是,该示例仅监听窗口激活事件(`WM_ACTIVATE`消息),你可以根据需要修改钩子回调函数中的逻辑和事件类型。 请注意,窗口钩子需要在一个消息循环中运行,以便接收系统发送的消息并进行处理。示例代码中的`while`循环用于获取和分发消息,直到获取到退出消息为止。 在实际使用中,你可能需要根据具体的需求和事件类型来编写钩子回调函数的逻辑。此外,还需要注意在适当的时候卸载钩子,以避免对系统造成不必要的影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值