C / C ++在没有轮询的情况下按下键

时间:2014-05-12 02:50:26

标签: c++ c io kernel polling

我正在学习C / C ++,最近我创建了一个键盘记录器,主要是因为它是一个简单的学习项目。所以我所做的是在循环中运行GetAsynKeyState()以检查密钥的状态。当我检查CPU时,它的周期很好;我一直在运行带有条件的循环。

在我做这类事情上似乎很浪费,我相信更大更先进的软件不会使用这种技术。

问题:按下某个键时,会为内核创建一个中断来处理。我的程序可以像内核一样“被唤醒”,或者是唯一一个不断检查按键的解决方案吗?专业申请会做什么?

此外,编程语言实现了事件监听器,他们如何实现这一点,轮询还是其他一些魔术?

2 个答案:

答案 0 :(得分:0)

钩子是一种在到达应用程序之前拦截事件(例如,鼠标操作或击键)的机制。接收这些事件的函数称为过滤器函数(请参阅下面的MyKbHook。)为了调用过滤器,必须将过滤器函数附加到Windows挂钩(请参阅下面的SetWindowHookEx)。

如果挂钩附加了多个过滤器功能,Windows会维护一系列过滤器功能。最后安装的功能位于链的开头,第一个安装的功能位于最后。

LRESULT CALLBACK MyKbHook( int nId, WPARAM wParam, LPARAM lParam )
{
   char keyPressed;

   KBDLLHOOKSTRUCT *pHook = (KBDLLHOOKSTRUCT *)lParam;
   switch( wParam )
   {
       case WM_KEYUP: 
       {
          //get the key code
          keyPressed= (char)pHook->vkCode;
       }
       break;
       default:
           return CallNextHookEx( NULL, nId, wParam, lParam );
       break;
   }


   //Each function implementing a hook must call the next hook in chain before return
   return CallNextHookEx( NULL, nId, wParam, lParam);
}


// somewhere in your code where you want start tracking
    HHOOK hookKB = SetWindowHookEx(WH_KEYBOARD,(HOOKPROC)MyKbHook,hInst,0);

// when you do not need it anymore you SHOULD uninstall it
 UnhookWindowsHookEx(hookKB);

答案 1 :(得分:0)

专业方法取决于OS到OS。在Windows上,您只需使用Windows消息。根据您的具体需要,您通常会WM_CHARWM_KEYDOWN使用。比挂钩容易得多。