三. 用钩子机制实现截获鼠标左右键按压次数。
建立钩子程序时需要把钩子处理整合到动态链接库中,所以例程中需要建立两个project。
1. 钩子处理动态链接库
(1) 选择mfc appwizard(dll)创建一个新project,命名为“spy”。
(2) 选择mfc extension dll类型。
(3) 创建一个新的头文件,命名为“hook.h”,修改它的代码如下:
extern "C" LRESULT CALLBACK mouseproc(int code,WPARAM wparam,LPARAM lparam); //钩子处理函数
extern "C" bool WINAPI starthook(); //启动钩子函数
extern "C" bool WINAPI stophook(); //撤销钩子函数
extern "C" int WINAPI getresultl(); //取得鼠标左键单击次数的函数
extern "C" int WINAPI getresultr(); //取得鼠标右键单击次数的函数
(4) 修改spy.cpp程序代码如下:
#include "hook.h" //包含头文件hook
#pragma data_seg("publicdata") //定义全局数据段
HHOOK hhook=NULL; //钩子句柄
HINSTANCE pinstance=NULL;//钩子模块句柄
UINT mouseclickl=0; //记录鼠标左键单击次数的变量
UINT mouseclickr=0;//记录鼠标右键单击次数
#pragma data_seg()
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{ if (dwReason == DLL_PROCESS_ATTACH)
{…… //省略部分机器生成代码
new CDynLinkLibrary(SpyDLL);
pinstance=hInstance;//取得模块句柄
}
……;
}
extern "C" LRESULT CALLBACK mouseproc(int code, WPARAM wparam,LPARAM lparam)//钩子处理函
{
if (code<0) //若code〈0,则直接调用callnexthookex返回
return CallNextHookEx(hhook, code, wparam, lparam);
if(wparam==WM_LBUTTONDOWN)
{ mouseclickl ;//记录鼠标左键单击次数 }
if(wparam==WM_RBUTTONDOWN)
{ mouseclickr ;//记录鼠标右键单击次数 }
return CallNextHookEx(hhook, code, wparam,lparam);
}
extern "C" bool WINAPI starthook()//启动钩子函数
{
hhook=SetWindowsHookEx(WH_MOUSE,mouseproc,pinstance,0);//挂上钩子
if(hhook!=NULL)
return true;
else return false;
}
extern "C" bool WINAPI stophook() //撤销钩子函数
{ return UnhookWindowsHookEx(hhook); //撤销钩子}
extern "C" int WINAPI getresultl()//返回鼠标左键单击次数
{ return mouseclickl;}
extern "C" int WINAPI getresultr()//返回鼠标右键单击次数
{ return mouseclickr;}
(5) 修改spy.def程序代码如下:
exports
stophook @2
starthook @1
getresultl @3
getresultr @4
(6) 编译project,生成spy.dll文件和spy.lib文件。
2. 建立使用钩子的程序
(1) 生成一个单文档的可执行文件(exe)的project。
(2) 修改资源中的主选单,增加一个选单项“监控”,下有三个子选单项,分别为“启动”、“撤销”和“取出”。
(3) 在project中加入spy.lib文件。
(4) 分别修改“启动”、“撤销”和“取出”选单项的command响应函数如下:
#include "E:\DevStudio\MyProjects\spy\hook.h" //路径可不同
void CMainFrame::OnMenuitem32771() //“启动”选单项的响应函数
{ starthook(); }
void CMainFrame::OnMenuitem32772() //“撤销”选单项的响应函数
{ stophook();}
void CMainFrame::OnMenuitem32773() //“取出”选单项的响应函数
{ int resultl=getresultl();
int resultr=getresultr();
char buffer[80];
wsprintf(buffer,"在程序运行期间,你共单击鼠标左键%d次,右键%d次!",resultl,resultr);
::MessageBox(this->m_hWnd,buffer,"message",MB_OK);
