WINDOWS键盘事件的挂钩监控原理及其应用技术

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

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)
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、利用本文提供的方法设置自己的应用程序功能按键,在保证程序功 能按键不会 与其它系统发生冲突的同时,有效地利用了系统中现有资 源,而且在实现应用程序 功能的同时灵活应用了系统中提供的各种功 能调用。
{ 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按键的状 态,供组合按键 处理时判断使用。 swБайду номын сангаасtch (iMessage) { case 0x7fff: //自定义消息类型 if(lParam==0x3L) {//设置Micro键的状态
5、编制挂钩安装和下载函数InstallFilter(); 6、编制挂钩函数KeyboardProc(),在其中设置监控功能,并确定继续 调下一个钩 子函数还是直接返回WINDOWS应用程序。 7、在WINDOWS主程序中需要初始化DLL并安装相应挂钩函数,由挂 接的钩子函数负 责与主程序通信; 8、在不需要监控时由下载功能卸掉挂接函数。 四、 WINDOWS下键盘挂钩监控函数的应用技术 目前标准的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;
WINDOWS键盘事件的挂钩监控原理及其应用技术 WINDOWS 的消息处理机制为了能在应用程序中监控系统的各种事 件消息,提供了挂接 各种反调函数(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 动 态链接库中。挂接函数必须严格按照下述格式进行声明,以键盘挂钩函 数为例: 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(),传递主窗口程序句柄;
相关文档
最新文档