很容易啊,你看一看帮助不就知道啦,有一点要注意的就是DLL的共享数据区的处理。
可以在MSDN中找到帮助和例子的,要不到微软得网站找,很全面,不仅仅是鼠标的钩子,还有别的。

解决方案 »

  1.   

    留下你的email,我发源代码给你
      

  2.   

    WINDOWS键盘事件的挂钩监控原理及其应用技术     WINDOW的消息处理机制为了能在应用程序中监控系统的各种事件消息,
        提供了挂接各种反调函数(HOOK)的功能。这种挂钩函数(HOOK)类似扩充中断
        驱动程序,挂钩上可以挂接多个反调函数构成一个挂接函数链。系统产生的
        各种消息首先被送到各种挂接函数,挂接函数根据各自的功能对消息进行监
        视、修改和控制等,然后交还控制权或将消息传递给下一个挂接函数以致最
        终达到窗口函数。WINDOW系统的这种反调函数挂接方法虽然会略加影响到
        系统的运行效率,但在很多场合下是非常有用的,通过合理有效地利用键盘
        事件的挂钩函数监控机制可以达到预想不到的良好效果。一、在WINDOWS键盘事件上挂接监控函数的方法WINDOW下可进行挂接的过滤函数包括11种:
    H_CALLWNDPROC 窗口函数的过滤函数
    H_CBT 计算机培训过滤函数
    H_DEBUG 调试过滤函数
    H_GETMESSAGE 获取消息过滤函数
    H_HARDWARE 硬件消息过滤函数
    H_JOURNALPLAYBACK 消息重放过滤函数
    H_JOURNALRECORD 消息记录过滤函数
    H_MOUSE 鼠标过滤函数
    H_MSGFILTER 消息过滤函数
    H_SYSMSGFILTER 系统消息过滤函数
    H_KEYBOARD 键盘过滤函数键盘过滤函数是最常用最有用的过滤函数类型,不管是哪一种类型的过滤函数,其挂接的基本方法都是相同的。
    WINDOW调用挂接的反调函数时总是先调用挂接链首的那个函数,因此必须将键盘挂钩函数利用函数SetWindowsHookEx()
    将其挂接在函数链首。至于消息是否传递给函数链的下一个函数是由每个具体函数功能确定的,如果消息
    需要传统给下一个函数,可调用API函数的CallNextHookEx()来实现,如果不传递直接返回即可。挂接函数
    可以是用来监控所有线程消息的全局性函数,也可以是单独监控某一线程的局部性函数。如果挂接函数是局部
    函数,可以将它放到一个.DLL动态链接库中,也可以放在一个局部模块中;如果挂接函数是全局的,那么必须
    将其放在一个.DLL动态链接库中。挂接函数必须严格按照下述格式进行声明,以键盘挂钩函数为例:
    LRESULT CALLBACK 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下键盘挂钩监控函数的应用技术前标准的104 键盘上都有两个特殊的按键,其上分别用WINDOW程序徽标和鼠标下拉列表标识,本文暂且分别
    称为Micro左键和Micro右键,前者用来模拟鼠标左键激活开始菜单,后者用来模拟鼠标右键激活属性菜单。
    这两个特殊按键只有在按下后立即抬起即完成 CLICK过程才能实现其功能,并且没有和其它按键进行组合使用。
    由于WINDOWS 系统中将按键划分得更加详细,使应用程序中很难灵活定义自己的专用快捷键,比如在开发.IME等
    应用程序时很难找到不与WORD8.0等其它应用程序冲突的功能按键。如果将标准104键盘中的这两个特殊按键
    作为模拟CTRL和ALT 等专用按键,使其和其它按键组合,就可以在自己的应用程序中自由地设置专用功能键,
    为应用程序实现各种功能快捷键提供灵活性。正常情况下WINDOWS 键盘事件驱动程序并不将这两个按键的消息
    进行正常解释,这就必须利用键盘事件的挂钩监控函数来实现其特定的功能。其方法如下:
    #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、利用本文提供的方法设置自己的应用程序功能按键,在保证程序功能按键不会与其它系统发生冲突的同时,
    有效地利用了系统中现有资源,而且在实现应用程序功能的同时灵活应用了系统中提供的各种功能调用。
      

  3.   

    WINDOWS键盘事件的挂钩监控原理及其应用技术     WINDOW的消息处理机制为了能在应用程序中监控系统的各种事件消息,
        提供了挂接各种反调函数(HOOK)的功能。这种挂钩函数(HOOK)类似扩充中断
        驱动程序,挂钩上可以挂接多个反调函数构成一个挂接函数链。系统产生的
        各种消息首先被送到各种挂接函数,挂接函数根据各自的功能对消息进行监
        视、修改和控制等,然后交还控制权或将消息传递给下一个挂接函数以致最
        终达到窗口函数。WINDOW系统的这种反调函数挂接方法虽然会略加影响到
        系统的运行效率,但在很多场合下是非常有用的,通过合理有效地利用键盘
        事件的挂钩函数监控机制可以达到预想不到的良好效果。一、在WINDOWS键盘事件上挂接监控函数的方法WINDOW下可进行挂接的过滤函数包括11种:
    H_CALLWNDPROC 窗口函数的过滤函数
    H_CBT 计算机培训过滤函数
    H_DEBUG 调试过滤函数
    H_GETMESSAGE 获取消息过滤函数
    H_HARDWARE 硬件消息过滤函数
    H_JOURNALPLAYBACK 消息重放过滤函数
    H_JOURNALRECORD 消息记录过滤函数
    H_MOUSE 鼠标过滤函数
    H_MSGFILTER 消息过滤函数
    H_SYSMSGFILTER 系统消息过滤函数
    H_KEYBOARD 键盘过滤函数键盘过滤函数是最常用最有用的过滤函数类型,不管是哪一种类型的过滤函数,其挂接的基本方法都是相同的。
    WINDOW调用挂接的反调函数时总是先调用挂接链首的那个函数,因此必须将键盘挂钩函数利用函数SetWindowsHookEx()
    将其挂接在函数链首。至于消息是否传递给函数链的下一个函数是由每个具体函数功能确定的,如果消息
    需要传统给下一个函数,可调用API函数的CallNextHookEx()来实现,如果不传递直接返回即可。挂接函数
    可以是用来监控所有线程消息的全局性函数,也可以是单独监控某一线程的局部性函数。如果挂接函数是局部
    函数,可以将它放到一个.DLL动态链接库中,也可以放在一个局部模块中;如果挂接函数是全局的,那么必须
    将其放在一个.DLL动态链接库中。挂接函数必须严格按照下述格式进行声明,以键盘挂钩函数为例:
    LRESULT CALLBACK 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下键盘挂钩监控函数的应用技术前标准的104 键盘上都有两个特殊的按键,其上分别用WINDOW程序徽标和鼠标下拉列表标识,本文暂且分别
    称为Micro左键和Micro右键,前者用来模拟鼠标左键激活开始菜单,后者用来模拟鼠标右键激活属性菜单。
    这两个特殊按键只有在按下后立即抬起即完成 CLICK过程才能实现其功能,并且没有和其它按键进行组合使用。
    由于WINDOWS 系统中将按键划分得更加详细,使应用程序中很难灵活定义自己的专用快捷键,比如在开发.IME等
    应用程序时很难找到不与WORD8.0等其它应用程序冲突的功能按键。如果将标准104键盘中的这两个特殊按键
    作为模拟CTRL和ALT 等专用按键,使其和其它按键组合,就可以在自己的应用程序中自由地设置专用功能键,
    为应用程序实现各种功能快捷键提供灵活性。正常情况下WINDOWS 键盘事件驱动程序并不将这两个按键的消息
    进行正常解释,这就必须利用键盘事件的挂钩监控函数来实现其特定的功能。其方法如下:
    #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、利用本文提供的方法设置自己的应用程序功能按键,在保证程序功能按键不会与其它系统发生冲突的同时,
    有效地利用了系统中现有资源,而且在实现应用程序功能的同时灵活应用了系统中提供的各种功能调用。
      

  4.   

    要使用某种类型的钩子,开发人员就得提供一个钩子过程,并用函数SetWindowsHookEx把它安装到与这个钩子相应的链中去。钩子过程必须符合下列的语法规则:
    LRESULT CALLBACK HookProc( Int nCode, WPARAM wParam, LPARAM lParam )
    HookProc是一个占位符,是应用程序定义的名字,因为Windows系统必须调用钩子过程,所以就需要在应用程序模块定义文件的EXPORTS语句中列出其实际名字或者是相应的序数值。
    参数nCode是钩子代码,钩子过程根据它来确定所要完成的动作。钩子代码的值取决于钩子的类型;每种类型都具有属于它自己的特性集的钩子代码。参数wParam和lParam的值取决于钩子代码,但它们通常含有被发送或投递消息的信息。
    SetWindowsHookEx总是把钩子过程安装在钩子过程链的开始,如果一个由某种类型的钩子监视的事件发生,Windows系统就调用与钩子相应的钩子链开始的过程,链中的每一个钩子过程都要决定是否要把事件传到下一个过程,钩子过程调用函数CallNextHookEx把事件传到下一个过程。
    注意有些类型的钩子过程只能监视消息,Windows系统只把消息传到每一个钩子过程,而不管是否有哪个消息调用了CallNextHookEx。
    钩子过程可能是全局的,用于监视系统中所有的线程的消息;也可以是特定线程,只为某个线程监视。全局钩子过程可以被任何应用程序调用,所以过程必须在一个独立的动态链接库(DLL)模块中。线程特有的钩子过程只由相应的线程调用,如果应用程序要为它自己的某个线程安装钩子过程,那么钩子过程可以在应用程序代码的同一个模块中,也可以在一个DLL中。但如果应用程序安装的钩子过程用于其它应用程序的某个线程,那么该过程必须是在DLL中。
    钩子种类
    每种钩子允许应用程序监视Windows系统消息处理机构中的某个方面。
    钩子WH_MOUSE
    钩子WH_MOUSE允许应用程序监视由函数GetMessage和PeekMessage返回的鼠标消息。应用程序可用WH_MOUSE钩子来监视投递到消息队列的鼠标输入消息。