1、WH_KEYBOARD 和 WH_KEYBOARD_LL 有什么区别?    很多地方都讲得很笼统。让我感觉就是没区别。2、为什么我使用 WH_KEYBOARD_LL ,编译器告诉我 undeclared symbol?    我查了一下 WH_KEYBOARD_LL 的定义,它在 _WIN32_WINNT > 4000 时会被编译,我不明白这是什么意思。我的系统是Windows2000 professional,开发环境是Visual C++ 6.03、我试图通过修改lParam的值实现过滤键,但不管用?    当我的钩子(WH_KEYBOARD类型的HHOOK)钩到键盘消息时,我把消息的lParam参数的16到23位(资料上写这8位是键盘的扫描码)修改成某一个值,比如0x1E,即键盘上的a,然后把新的lParam作为参数传递给 CallNextHookEx 。我的想法就是不管用户按了什么键,经过我的钩子后都相当于在按“a”键。在调试过程中确认了lParam的16~23位被修改了。
    不过这个程序最终什么都没做,虽然传递给 CallNextHookEx 的是修改后的lParam,但应用程序还是能接收到正确的键值。    可能是我从整体设计上就出了问题,请教高手。

解决方案 »

  1.   

    附加信息:我实现的键盘钩子是全局钩子,安装在dll文件中。经测试能正确钩到键盘消息。4、为什么我调用 UnhookWindowsHookEx 总是失败?
        我把HHOOK句柄 hhkKey 放到一个共享内存段中供多个DLL共享(我这么做是防止出现重复的钩子)。dll有两个导出函数,StartHook() 和 EndHook(),StartHook中执行:hhkKey = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, hInstance, NULL);EndHook() 中执行
    UnhookWindowsHookEx(hhkKey);    我用一个基于对话框的MFC程序作为界面,设定了一个CheckBox,选中时调用 StartHook(),取消选择时调用 EndHook()。经测试,UnhookWindowsHookEx(hhkKey) 总是返回一个NULL值,根据MSDN上的资料意即失败。
      

  2.   

    2、为什么我使用 WH_KEYBOARD_LL ,编译器告诉我 undeclared symbol?    我查了一下 WH_KEYBOARD_LL 的定义,它在 _WIN32_WINNT > 4000 时会被编译,我不明白这是什么意思。我的系统是Windows2000 professional,开发环境是Visual C++ 6.0#if (_WIN32_WINNT >= 0x0400)
    #define WH_KEYBOARD_LL     13
    #define WH_MOUSE_LL        14
    #endif // (_WIN32_WINNT >= 0x0400)你直接把那个参数填为13也可以
      

  3.   

    或者在stdafx.h里面#ifndef _WIN32_WINNT    
         // Allow use of features specific to Windows NT 4 or later.
    #define _WIN32_WINNT 0x0400     
         // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
    #endif
      

  4.   

    4、为什么我调用 UnhookWindowsHookEx 总是失败?
    看你的全局共享数据段是否正确设置,需要rws属性
      

  5.   

    我是这样实现共享数据的:#pragma data_seg("shared")
    HHOOK hhkKey = NULL;
    #pragma data_seg()然后在链接设置中增加:/section:shared,rws我最关心的是第三小问,可没人回答我。 :<
      

  6.   

    1、WH_KEYBOARD 和 WH_KEYBOARD_LL 有什么区别?    很多地方都讲得很笼统。让我感觉就是没区别。
    钩的位置不同,WH_KEYBOARD_LL 要比WH_KEYBOARD 先触发,WH_KEYBOARD_LL 是由系统调用你的回调函数,而WH_KEYBOARD则是你钩的进程来调用你的回调函数。这就意味着,WH_KEYBOARD要插入进程,如果是全局钩子,就会插入每一个进程,WH_KEYBOARD_LL 不需要插入进程(所以据说根本不需要放在dll里面,放在exe里面也能运行)
      

  7.   

    2、为什么我使用 WH_KEYBOARD_LL ,编译器告诉我 undeclared symbol?    我查了一下 WH_KEYBOARD_LL 的定义,它在 _WIN32_WINNT > 4000 时会被编译,我不明白这是什么意思。我的系统是Windows2000 professional,开发环境是Visual C++ 6.0
    在stdafx.h中加上一句#define _WIN32_WINNT 0x5000即可3、我试图通过修改lParam的值实现过滤键,但不管用?    当我的钩子(WH_KEYBOARD类型的HHOOK)钩到键盘消息时,我把消息的lParam参数的16到23位(资料上写这8位是键盘的扫描码)修改成某一个值,比如0x1E,即键盘上的a,然后把新的lParam作为参数传递给 CallNextHookEx 。我的想法就是不管用户按了什么键,经过我的钩子后都相当于在按“a”键。在调试过程中确认了lParam的16~23位被修改了。
        不过这个程序最终什么都没做,虽然传递给 CallNextHookEx 的是修改后的lParam,但应用程序还是能接收到正确的键值。lParam是一个指针啊,不要修改lParam的值,而是修改它所指向的KBDLLHOOKSTRUCT里面的值啊
      

  8.   

    wParam才是关键吧???
    你试试修改wParam应该可以了
      

  9.   

    MSDN上很确切地描述了lParam的每一位,似乎并不是指针。可网上又确实能找到资料证明lParam是指向KBDLLHOOKSTRUCT的指针。天,疯了。
      

  10.   

    改进:通过 #define _WIN32_WINNT 0x0500,成功地引入了 WH_KEYBOARD_LL 钩子和 KBDLLHOOKSTRUCT 结构。修正了 UnhookWindowsHookEx 失败的问题,原因是我把一个 == 打成了 = 。我挂接了 WH_KEYBOARD_LL 钩子,获取 lParam 指向的 KBDLLHOOKSTRUCT 结构中的 vkCode 和 scanCode 数据域。我将此二者修改为 0x00000041 和 0x0000001E (键盘上a的vitual key和scan code值),然后调用 CallNextHookEx 继续传递消息。不过,事实证明:这个程序仍然什么都不做!我快疯了!快来帮帮我吧。
      

  11.   

    我目前是这样做的:实现一个低级钩子 WH_KEYBOARD_LL,检测 scanCode 值,如果是我需要过滤的(比如 p ),则调用keybd_event模拟一次输入(比如a )。但这样做有问题,比如一直p键,我期待的输出是一串a,但实际上不会这么输出。
      

  12.   

    修正了一下,现在基本能工作了:
    检测到我要的键,如果是按下,发一个按下的消息(用keybd_event)
    如果是抬起,发一个抬起的消息(用keybd_event)
    然后return TRUE终止消息继续传递
      

  13.   

    你的LowLevelKeyboardProc的返回值肯定有问题
      

  14.   

    什么叫返回值有问题?
    我是改变lParam指向的KBDLLHOOKSTRUCT中的内容后返回CallNextHookEx()。
      

  15.   

    测试了一下,改wParam也没用。