低级键盘钩:区分键码

时间:2013-07-27 04:43:19

标签: c++ visual-c++ keyboard hook keyboard-hook

我正在尝试限制程序用户对键盘的访问权限。为此,我已经定义了一个低级键盘钩子:

LRESULT CALLBACK lowLevelKeyboardProc(int key, WPARAM wParam, LPARAM lParam)
{
    KBDLLHOOKSTRUCT* pkbhs = (KBDLLHOOKSTRUCT*)lParam;

    switch (key)
    {
        case HC_ACTION:
....

并挂上它:

m_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)lowLevelKeyboardProc, 0, 0);

我需要用户只能使用字母数字字符,〜,@,#...只能使用密码中的字符(可打印的字符)。 使用低级键盘钩子参数区分这些字符和所有其他字符的最简单方法是什么:int key,WPARAM wParam,LPARAM lParam?

程序用c ++编写,在VC2010中编译。

感谢所有帮助!

1 个答案:

答案 0 :(得分:2)

在真正回答你的问题之前,我有几个问题要问你:

  1. 为什么要使用全局低级键盘钩子全局

    虽然有时它们是解决问题的唯一方法,但由于许多原因,通常强烈建议不要使用这样的全局钩子。有许多更好的方法可以防止用户输入无效或不可接受的数据。例如,我只是禁用特定控件或控件集(例如所有文本框)所不需要的键。这样,用户仍然可以使用键盘快捷键和其他非字母数字键与您的应用程序进行交互,这对于可访问性原因至关重要。请记住,全局挂钩会影响计算机上运行的其他线程的所有,而不仅仅是您的应用程序 - 这可能不是您想要的。

  2. 即使您决定使用全局挂钩,您确定确实需要禁用所有非字母数字键吗?退格和删除怎么样?用户不应该删除东西吗? Tab怎么样?输入?那些修改键,比如Shift,Ctrl和Alt:那些是允许的吗?

  3. 认真重新考虑是否确实需要低级别的挂钩才能继续使用此设计。如果您需要有关设计其他解决方案的帮助,请提出一个新问题,描述您想要完成的任务(例如,我想阻止用户在文本框控件中输入任何非字母数字字符;这是我使用的代码创建我的文本框...... )。

    但如果你坚持忽略我的建议,解决方案就相当简单:调查传递给钩子程序的KBDLLHOOKSTRUCT structure成员。 vkCode成员会为您提供已按下的密钥的virtual key code。机会是,这是您需要的所有信息。但是,如果不是这样,密钥的硬件扫描代码也在scanCode成员中提供。

    不幸的是,您目前拥有的代码是错误的。钩子回调过程的第一个参数确实是int,但不是一个密钥代码。相反,它是一个代码,用于指示钩子过程如何处理消息。像这样使用它:

    LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
       // If nCode is greater than or equal to HC_ACTION, process the message.
       if (nCode >= HC_ACTION)
       {
          KBDLLHOOKSTRUCT* pkbhs = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
    
          // Handle the keys as you wish here.
          // 
          // Remember that pkbhs->vkCode gives you the virtual key code
          // of the key that was pressed.
          // 
          // To prevent a particular key from being processed, you should
          // return a non-zero value (e.g. 1) immediately.
       }
    
       // Pass the message on.
       return CallNextHookEx(m_hHook, nCode, wParam, lParam);
    }
    

    当你安装钩子时,绝对不需要转换函数指针。像这样的无意义演员只是隐藏潜在的编译时错误,导致运行时崩溃。简单地写一下:

    m_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, lowLevelKeyboardProc, 0, 0);