WINDOWS键盘事件的挂钩监控道理及其应用技能
副标题#e#
WINDOW的动静处理惩罚机制为了能在应用措施中监控系统的各类事件动静,提供了挂接各类反调函数(HOOK)的成果。这种挂钩函数(HOOK)雷同扩充间断驱动措施,挂钩上可以挂接多个反调函数组成一个挂接函数链。系统发生的各类动静首先被送到各类挂接函数,挂接函数按照各自的成果对动静举办监督、修改和节制等,然后交还节制权或将动静通报给下一个挂接函数乃至最终到达窗口函数。WINDOW系统的这种反调函数挂接要领固然会略加影响到系统的运行效率,但在许多场所下长短常有用的,通过公道有效地操作键盘事件的挂钩函数监控机制可以到达预想不到的精采结果。
一、在WINDOWS键盘事件上挂接监控函数的要领
WINDOW下可举办挂接的过滤函数包罗11种:
WH_CALLWNDPROC 窗口函数的过滤函数
WH_CBT 计较机培训过滤函数
WH_DEBUG 调试过滤函数
WH_GETMESSAGE 获打动静过滤函数
WH_HARDWARE 硬件动静过滤函数
WH_JOURNALPLAYBACK 动静重放过滤函数
WH_JOURNALRECORD 动静记录过滤函数
WH_MOUSE 鼠标过滤函数
WH_MSGFILTER 动静过滤函数
WH_SYSMSGFILTER 系统动静过滤函数
WH_KEYBOARD 键盘过滤函数
个中键盘过滤函数是最常用最有用的过滤函数范例,不管是哪一种范例的过滤函数,其挂接的根基要领都是沟通的。
WINDOW挪用挂接的反调函数时老是先挪用挂接链首的谁人函数,因此必需将键盘挂钩函数操作函数SetWindowsHookEx()将其挂接在函数链首。至于动静是否通报给函数链的下一个函数是由每个详细函数成果确定的,假如动静需要传统给下一个函数,可挪用API函数的CallNextHookEx()来实现,假如不通报直接返回即可。挂接函数可以是用来监控所有线程动静的全局性函数,也可以是单独监控某一线程的局部性函数。假如挂接函数是局部函数,可以将它放到一个.DLL动态链接库中,也可以放在一个局部模块中;假如挂接函数是全局的,那么必需将其放在一个.DLL动态链接库中。挂接函数必需严格凭据下述名目举办声明,以键盘挂钩函数为例:
#p#副标题#e#
int FAR PASCAL KeyboardProc(int nCode,WORD wParam,DWORD lParam)
个中KeyboardProc为界说挂接函数名,该函数必需在模块界说文件中操作EXPORTS呼吁举办说明;nCode抉择挂接函数是否对当前动静举办处理惩罚;wParam和lParam为详细的动静内容。
二、键盘事件挂接函数的安装与下载
在措施中可以操作函数SetWindowsHookEx()来挂接过滤函数,在挂接函数时必需指出该挂接函数的范例、函数的进口地点以及函数是全局性的照旧局部性的,挂接函数的详细挪用名目如下:
SetWindowsHookEx(iType,iProc,hInst,iCode)
个中iType为挂接函数范例,键盘范例为WH_KEYBOARD,iProc为挂接函数地点,hInst为挂接函数链接库实例句柄,iCode为监控代码-0暗示全局性函数。假如挂接函数需要将动静通报给下一个过滤函数,则在该挂接函数返回前还需要挪用一次CallNextHookEx()函数,当需要下载挂接函数时,只要挪用一次UnhookWindowsHookEx(iProc)函数即可实现。假如函数是全局性的,那么它必需放在一个.DLL动态链接库中,这时该函数挪用要领可以和其它普通.DLL函数一样有三种:
1.在DEF界说文件中直接用函数名或序号说明:
EXPORTS
WEP @1 RESIDENTNAME
InitHooksDll @2
InstallFilter @3
KeyboardProc @4
用序号说明名目为:链接库名.函数名(如本例中说明要领为KEYDLL.KeyboardProc)。
2.在应用措施中操作函数直接挪用:
首先在应用措施中操作LoadLibrary(LPSTR "链接库名")将动态链接库装入,并取得装载库模块句柄hInst,然后直接操作GetProcAddress(HINSTANCE hInst,LPSTR "函数进程名")获取函数地点,然后直接挪用该地点即可,措施竣事前操作函数FreeLibrary( )释放装入的动态链接库即可。
3.操作输入库.LIB要领
操作IMPLIB.EXE措施在成立动态链接库的同时成立相应的输入库.LIB,然后直接在项目文件中增加该输入库。
三、WINDOWS挂钩监控函数的实现步调
WINDOWS挂钩函数只有放在动态链接库DLL中才气实现所有事件的监控成果。在.DLL中形成挂钩监控函数根基要领及其根基布局如下:
1、首先声明DLL中的变量和进程;
2、然后体例DLL主模块LibMain(),成立模块实例;
3、成立系统退出DLL机制WEP()函数;
4、完成DLL初始化函数InitHooksDll(),通报主窗口措施句柄;
5、体例挂钩安装和下载函数InstallFilter();
6、体例挂钩函数KeyboardProc(),在个中配置监控成果,并确定继承调下一个钩
子函数照旧直接返回WINDOWS应用措施。
7、在WINDOWS主措施中需要初始化DLL并安装相应挂钩函数,由挂接的钩子函数负
责与主措施通信;
8、在不需要监控时由下载成果卸掉挂接函数。
四、WINDOWS下键盘挂钩监控函数的应用技能
#p#分页标题#e#
今朝尺度的104 键盘上都有两个非凡的按键,其上别离用WINDOW措施徽标和鼠标下拉列表标识,本文暂且别离称为Micro左键和Micro右键,前者用来模仿鼠标左键激活开始菜单,后者用来模仿鼠标右键激活属性菜单。这两个非凡按键只有在按下后当即抬起即完成 CLICK进程才气实现其成果,而且没有和其它按键举办组合利用。由于WINDOWS 系统中将按键分别得越发具体,使应用措施中很难机动界说本身的专用快捷键,好比在开拓.IME等应用措施时很难找到不与WORD8.0等其它应用措施斗嘴的成果按键。假如将尺度104键盘中的这两个非凡按键作为模仿CTRL和ALT 等专用按键,使其和其它按键组合,就可以在本身的应用措施中自由地配置专用成果键,为应用措施实现各类成果快捷键提供机动性。正常环境下WINDOWS 键盘事件驱动措施并不将这两个按键的动静举办正常表明,这就必需操作键盘事件的挂钩监控函数来实现其特定的成果。其要领如下:
1、首先体譬喻下一个简朴动态链接库措施,并编译成DLL文件。
#include "windows.h"
int FAR PASCAL LibMain(HANDLE hModule,UINT wDataSeg,UINT cbHeapSize,LPSTR lpszCmdLine);
int WINAPI WEP(int bSystemExit);
int WINAPI InitHooksDll(HWND hwndMainWindow);
int WINAPI InstallFilter(BOOL nCode);
LRESULT CALLBACK KeyHook(int nCode,WORD wParam,DWORD lParam);
static HANDLE hInstance; // 全局句柄
static HWND hWndMain; // 主窗口句柄
static int InitCalled=0; // 初始化符号
static HHOOK hKeyHook;
FARPROC lpfnKeyHook=(FARPROC)KeyHook;
BOOL HookStates=FALSE;
int FAR PASCAL LibMain(
HANDLE hModule,
UINT wDataSeg,
UINT cbHeapSize,
LPSTR lpszCmdLine)
{
if (cbHeapSize!=0) UnlockData(0);
hInstance = hModule;
return 1;
}
int WINAPI WEP (int bSystemExit)
{ return 1;}
int WINAPI InitHooksDll(HWND hwndMainWindow)
{ hWndMain = hwndMainWindow;
InitCalled = 1;
return (0);
}
int WINAPI InstallFilter(BOOL nCode)
{ if (InitCalled==0) return (-1);
if (nCode==TRUE) {
hKeyHook=SetWindowsHookEx(WH_KEYBOARD,
(HOOKPROC)lpfnKeyHook,hInstance,0);
HookStates=TRUE;
} else {
UnhookWindowsHookEx(hKeyHook);
HookStates=FALSE;
}
return(0);
}
LRESULT CALLBACK KeyHook(int nCode,WORD wParam,DWORD lParam)
{
static BOOL msflag=FALSE;
if(nCode>=0) {
if(HookStates==TRUE){
if((wParam==0xff)|| //WIN3.X下按键值
(wParam==0x5b)||(wParam==0x5c)){//WIN95下按键值
if((i==0x15b)||(i==0x15c)){ //按键按下处理惩罚
msflag=TRUE;
PostMessage(hWndMain,0x7fff,0x1,0x3L);
} else if((i==0xc15b)||(i==0xc15c)){//按键抬起处理惩罚
msflag=FALSE;
PostMessage(hWndMain,0x7fff,0x2,0x3L);
}
}
}
}
return((int)CallNextHookEx(hKeyHook,nCode,wParam,lParam));
}
该措施的主要成果是监控键盘按键动静,将两个非凡按键Micro按下和抬起动静转换成自界说范例的动静,并将自界说动静发送给应用措施主窗口函数。
2、在应用措施主函数中成立窗口后,挪用InitHooksDll()函数来初始化动态链接库,并将应用措施主窗口句柄通报给链接库,然后挪用InstallFilter()函数挂接键盘事件监控回调函数。
InitHooksDll(hIMEWnd); //初始化DLL
InstallFilter(TRUE); //安装键盘回调函数
3、在应用措施主窗口函数处理惩罚自界说动静时,生存Micro按键的状态,供组合按键处理惩罚时判定利用。
switch (iMessage) {
case 0x7fff: //自界说动静范例
if(lParam==0x3L){//配置Micro键的状态
if(wParam==0x1) MicroFlag=TRUE;
else if(wParam==0x2) MicroFlag=FALSE;
}
break;
4、在举办按键组合处理惩罚时,首先判定Micro键是否按下,然后再举办其它按键的判定处理惩罚。
case WM_KEYDOWN: // 按键按下处理惩罚
if(MicroFlag==TRUE){//Micro键按下
if((BYTE)HIBYTE(wParam)==0x5b){
//Micro+"["组合键
......//按键成果处理惩罚
} else if((BYTE)HIBYTE(wParam)==0x5d){
//Micro+"]"组合键
......//按键成果处理惩罚
}
}
break;
5、当应用措施退出时应留意下载键盘监控函数,即挪用InstallFilter(FALSE)函数一次。
6、操作本文提供的要领配置本身的应用措施成果按键,在担保措施成果按键不会与其它系统产生斗嘴的同时,有效地操作了系统中现有资源,并且在实现应用措施成果的同时机动应用了系统中提供的各类成果挪用。