鼠标钩子的安装及钩取函数的参数解析
一、鼠标钩子的安装
SetWindowsHookEx(WH_MOUSE,MouseProc,g_hInstance,0);
WH_MOUSE 表明安装的是鼠标钩子
MouseProc 钩子函数的地址
g_hInstance 钩子函数所在dll的地址
0 为0表示是全局钩子
二、钩子函数解析
LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam)
int nCode //不太清楚,反正这个值<=零就返回钩链
WPARAM wParam //鼠标消息的类型 详情见①
LPARAM lParam //一个结构体的指针 这个结构体包含光标和窗口的句柄
typedef struct tagMOUSEHOOKSTRUCT {
POINT pt; //光标的坐标
HWND hwnd; //窗口的句柄
UINT wHitTestCode;
ULONG_PTR dwExtraInfo;
} MOUSEHOOKSTRUCT, FAR *LPMOUSEHOOKSTRUCT, *PMOUSEHOOKSTRUCT; 头文件:windows.h
①WM_LBUTTONDBLCLK 双击鼠标左键消息
WM_LBUTTONDOWN 单击鼠标左键消息
WM_LBUTTONUP 松开鼠标左键消息
WM_MBUTTONDBLCLK 双击鼠标中键(滚轮)消息
WM_MBUTTONDOWN 单击鼠标中键(滚轮)消息
WM_MBUTTONUP 松开鼠标中键(滚轮)消息
WM_RBUTTONDBLCLK 双击鼠标右键消息
WM_RBUTTONDOWN 单击鼠标右键消息
WM_RBUTTONUP 松开鼠标右键消息
WM_MOUSEMOVE 鼠标移动消息
WM_MOUSEWHEEL 鼠标滚轮转动消息
案例:使用鼠标钩子达成当鼠标在窗口移动时在窗口显示坐标
hook.cpp 用来打开可关闭钩子
//HookMain.cpp #include <stdio.h> #include <conio.h> #include <windows.h> #define DEF_DLL_NAME "displayPos.dll" //钩子函数所在的dll #define DEF_HOOKSTART "HookStart" #define DEF_HOOKSTOP "HookStop" typedef void (*PFN_HOOKSTART)(); typedef void (*PFN_HOOKSTOP)(); int main() { HMODULE hDll=NULL; PFN_HOOKSTART HookStart=NULL; PFN_HOOKSTOP HookStop=NULL; char ch=0; //加载KeyHook.dll hDll=LoadLibraryA(DEF_DLL_NAME); //获取导出函数地址 HookStart=(PFN_HOOKSTART)GetProcAddress(hDll,DEF_HOOKSTART); HookStop=(PFN_HOOKSTART)GetProcAddress(hDll,DEF_HOOKSTOP); //开始钩取 HookStart(); //等待直到用户输入“q” printf("press 'q' to quit!\n"); while(_getch()!='q'); //终止钩取 // HookStop(); //卸载KeyHook.dll // FreeLibrary(hDll); return 0; }
displayPos.cpp 被注入进程进行钩取
#include <windows.h> HINSTANCE g_hInstance=NULL; HHOOK g_hHook=NULL; HWND g_hWnd=NULL; // a sample exported function //LRESULT是一个数据类型,指的是从窗口程序或者回调函数返回的32位值 //lParam wParam 是宏定义,一般在消息函数中带着两个类型的参数,通常用来存储窗口消息的参数。wParam用来存储小段消息,如标志。lParam 通常用于存储消息所需的对象。 LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam) { char szPath[MAX_PATH]={0,}; int x; int y; char xs[MAX_PATH] = {0,}; char ys[MAX_PATH] = {0,}; if (nCode>=0) { //0=key press,1=key release if (wParam == WM_MOUSEMOVE )//当移动鼠标时 { //SetWindowTextA(hWnd,"saolei"); LPMOUSEHOOKSTRUCT lpMouse=(MOUSEHOOKSTRUCT *)lParam;//转化为LPMOUSEHOOKSTRUCT结构体指针 ScreenToClient(lpMouse->hwnd,&lpMouse->pt);//将屏幕坐标转化为窗口坐标 x = lpMouse->pt.x; y =lpMouse->pt.y; itoa(x,xs,10); //将坐标转化为字符串 itoa(y,ys,10); strcat(xs,","); strcat(xs,ys); SetWindowTextA(lpMouse->hwnd,xs); //修改标题 } } //若非notepad.exe,则调用CallNextHookEx()函数,将消息传递给应用程序(或下一个“钩子”)。 return CallNextHookEx(g_hHook,nCode,wParam,lParam); } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: // attach to process // return FALSE to fail DLL load g_hInstance=hinstDLL; break; case DLL_PROCESS_DETACH: // detach from process break; case DLL_THREAD_ATTACH: // attach to thread break; case DLL_THREAD_DETACH: // detach from thread break; } return TRUE; // succesful } #ifdef __cplusplus extern "C" { #endif __declspec(dllexport) void HookStart() { //钩子类型、回调函数地址、实例句柄、线程ID g_hHook=SetWindowsHookEx(WH_MOUSE,MouseProc,g_hInstance,0); } __declspec(dllexport) void HookStop() { if(g_hHook) { UnhookWindowsHookEx(g_hHook); g_hHook=NULL; } } #ifdef __cplusplus } #endif
编译环境: vs2010 多字节 已在window7 32位测试通过
WM_LBUTTONDBLCLK 双击鼠标左键消息
WM_LBUTTONDOWN 单击鼠标左键消息
WM_LBUTTONUP 松开鼠标左键消息
WM_MBUTTONDBLCLK 双击鼠标中键(滚轮)消息
WM_MBUTTONDOWN 单击鼠标中键(滚轮)消息
WM_MBUTTONUP 松开鼠标中键(滚轮)消息
WM_RBUTTONDBLCLK 双击鼠标右键消息
WM_RBUTTONDOWN 单击鼠标右键消息
WM_RBUTTONUP 松开鼠标右键消息
WM_MOUSEMOVE 鼠标移动消息
WM_MOUSEWHEEL 鼠标滚轮转动消息