监控自身窗口消息
意义不大,因为自身的窗口消息完全可以用消息循环捕获。
(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;
}
效果图: