关于Low Level Keyboard Hook的郁闷,万恶的SDK啊~~

本文介绍了解决Windows键盘钩子(WH_KEYBOARD_LL)不起作用的问题,通过创建具有消息循环的新线程来确保钩子回调函数LowLevelKeyboardProc能够捕获到键盘输入事件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天要做点事情,需要屏蔽Win键的几个组合键,于是想到用WH_KEYBOARD_LL,随便看了下VS6.0自带的MSDN里LowLevelKeyboardProc的描述:
The LowLevelKeyboardProc hook procedure is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The system calls this function every time a new keyboard input event is about to be posted into a thread input queue. The keyboard input can come from the local keyboard driver or from calls to thekeybd_event function. If the input comes from a call to keybd_event, the input was "injected".

于是写了类似下面的代码:
void f()
{
    HHOOK hHook = NULL;
    HANDLE hThread = NULL;
  __try
  {
      hHOOK = SetWindowHookEx(hInstance,WH_KEYBOARD_LL,LowLevelKeyboardProc,0);
      if(NULL == hHook) __leave;

      hThread=(HANDLE) _beginthread(.......); 
      if ((HANDLE)1 == hThread) __leave;

      WaitForSingleObject(hThread);
  }
  __finally
 {
      if (NULL != hThread) CloseHandle(hThread);
      if (NULL != hHook) UnhookWindowsHookEx(hHook);
  }
}

结果发现,安装的HOOK不起作用,研究了很久也不明白怎么回事,正在郁闷中,突然看到Win2K3的SDK Documentation里对LowLevelKeyboardProc的描述是:
The LowLevelKeyboardProc hook procedure is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The system calls this function every time a new keyboard input event is about to be posted into a thread input queue. The keyboard input can come from the local keyboard driver or from calls to the keybd_event function. If the input comes from a call to keybd_event, the input was "injected". However, the WH_KEYBOARD_LL hook is not injected into another process. Instead, the context switches back to the process that installed the hook and it is called in its original context. Then the context switches back to the application that generated the event.  

天啊,平白无故的多出来一段,真是万恶的SDK啊~~!这样的话,问题就很清楚了,安装Hook的线程没有消息循环,所以没有机会执行LowLevelKeyboardProc。于是改造:

void f()
{
    HANDLE hHOOKThread = NULL;
    HANDLE hThread = NULL;

  __try
  {
      DWORD TID;
 
      hHOOKThread = (HANDLE) _beginthreadex(NULL,0,HookThreadProc,NULL,0,&TID);
      if(NULL == hHOOKThread) __leave;

      hThread=(HANDLE) _beginthread(.......); 
      if ((HANDLE)1 == hThread) __leave;

      WaitForSingleObject(hThread);

      PostThreadMessage(TID,WM_QUIT,0,0);
  }
  __finally
 {
      if (NULL != hThread) CloseHandle(hThread);
      if (NULL !=hHOOKThread) CloseHandle(hHOOKThread);
      if (NULL != hHook) UnhookWindowsHookEx(hHook);
  }
}

unsigned __stdcall HookThreadProc(void * lpParam)
{
      HOOK hHook = SetWindowsHookEx(hInstance,WH_KEYBOARD_LL,LowLevelKeyboardProc,0);
      if (NULL == hHook) return;
      MSG msg;
      while(GetMessage(&msg,NULL,0,0));
      UnhookWindowsHookEx(hHook);
}

问题解决。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值