2013-07-27 57 views
0

我试图限制我的程序用户访问键盘。要做到这一点我已经定义了一个低的水平键盘钩子:低级别键盘挂钩:区分键码

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

不要对局部问题使用全局解决方案。只需过滤WM_CHAR消息。 –

回答

2

其实之前回答你的问题,我对你几个问题:

  1. 你为什么要这么做全球,利用全球低级别键盘钩子?

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

  2. 即使你决定使用全局钩子,你确定你真的需要禁用所有非字母数字键的? Backspace和Delete怎么样?用户不应该删除东西吗?那么Tab呢?输入?那么修饰键,如Shift,Ctrl和Alt:那些允许的呢?

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

但是,如果你坚持忽视我的建议,解决方案很简单:调查传递给挂钩过程的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); 
+0

感谢您的所有建议。我需要使用全局钩子,因为编辑框是这样构造的:password = CreateWindowEx(0,TEXT(“EDIT”),TEXT(“”),WS_TABSTOP | WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL | ES_LEFT | WS_BORDER,m_screenSize.cx/2 - 100,m_screenSize.cy/2 - 100,200,25,hWnd,NULL,(HINSTANCE)GetModuleHandle(0),NULL);我将使用vKCode参数! – armanxxx

+0

@armanxxx这不是使用全局钩子的理由。事实上,如果它是一个单一的控件,那就是你应该不使用全局钩子的时候。这是[控制子类](http://msdn.microsoft.com/en-us/library/windows/desktop/bb773183.aspx)并处理['WM_KEYDOWN'消息](http:// msdn。 microsoft.com/en-us/library/windows/desktop/ms646280.aspx)(或['WM_CHAR'消息](http://msdn.microsoft.com/en-us/library/windows/desktop/ms646276.aspx ))过滤掉不需要的输入。行! –

+0

行!我会尝试的。 – armanxxx