分享

屏蔽Win键、Alt Tab键的响应

 独孤求财 2012-03-12

屏蔽Win键、Alt+Tab键的响应

时间:2011-5-31来源:yang 作者: peng点击: 33次

  
关键字  Hook        Alt+Tab  

正文:  
    如果你是基于Windows操作系统做系统集成的,你可能希望你的最终产品独占系统资源。你希望规范用户行为,比如你不希望用户通过按Ctrl+Alt+Del终止某个进程,或者按下Win键弹出开始菜单,或者按下Alt+Tab组合键切换到别的应用程序。笔者已有相关一篇文章《Win2K/NT下屏蔽Ctrl+Alt+Del的响应》,介绍了如何通过GINA编程接口屏蔽Ctrl+Alt+Del的响应。作为续篇,本文将继续介绍屏蔽Win键和Alt+Tab组合键的方法。  
 
    由于这些按键的响应是系统级的,我们不可能简单地通过某个程序来控制它们。因此,我们需要使用微软提供的另外一种编程接口——钩子(Hook)。大家可能已经对钩子很了解了(网上有很多介绍钩子技术和应用的文章)。简单来说,钩子是一种通过替换系统提供的标准接口来截获特定的事件(消息),最终达到改变或增强系统默认行为目的的技术。我们现在的任务,就是要在用户按下Win键或Alt+Tab组合键、但系统还没有响应之前截获它们,然后改变系统的默认行为。很显然,我们要做一个全局钩子(钩子函数放在独立的DLL中实现),而且是个低级键盘钩子(Low  Level  Keyboard    hook)。  
 
    第一步,钩子DLL的实现。我们首先要定义一个全局数据区(记住这是一个全局钩子),如下(放在cpp文件的上头):  
#pragma  data_seg("mydata")  
HHOOK glhHook =  NULL;                        //  安装的鼠标钩子句柄  
HINSTANCE glhInstance = NULL;              //  DLL实例句柄  
#pragma data_seg()  
    然后在.def文件中声明这个数据区,如下:  
SECTIONS  
  mydata  READ  WRITE  SHARED  
    当这个DLL被某个进程载入时,程序从WinMain进入,此时我们需要把模块句柄保存下来,如下:  
glhInstance  =  (HINSTANCE)  hModule;  
    接下去,我们就要定义两个导出函数,以及钩子的处理函数。我们重点看一下这个钩子处理函数(另外两个导出函数比较简单,只是通过调用SetWindowsHookEx和UnhookWindowsHookEx实现安装/卸载钩子函数;只需注意SetWindowsHookEx第一个参数为WH_KEYBOARD_LL,第四个参数为0)。  
//  低级键盘钩子处理函数  
LRESULT  CALLBACK  LowLevelKeyboardProc(int  nCode,  WPARAM  wParam,  LPARAM lParam)  
{  
  BOOL  fEatKeystroke  =  FALSE;  
  PKBDLLHOOKSTRUCT  p  =  NULL;  
  if  (nCode  ==  HC_ACTION)    
     {  
         p  =  (PKBDLLHOOKSTRUCT)  lParam;  
         switch  (wParam)    
           {  
               case  WM_KEYDOWN:    
               case  WM_SYSKEYDOWN:  
               case  WM_KEYUP:          
               case  WM_SYSKEYUP:    
           fEatKeystroke  =  (p->vkCode  ==  VK_LWIN)    ¦  ¦  (p->vkCode  ==  VK_RWIN)    ¦  ¦    //  屏蔽Win  
               //  屏蔽Alt+Tab  
   ((p->vkCode  ==  VK_TAB)  &&  ((p->flags  &  LLKHF_ALTDOWN)  !=  0))    ¦  ¦  
               //  屏蔽Alt+Esc  
   ((p->vkCode  ==  VK_ESCAPE)  &&  ((p->flags  &  LLKHF_ALTDOWN)  !=  0))    ¦  ¦  
               //  屏蔽Ctrl+Esc  
   ((p->vkCode  ==  VK_ESCAPE)  &&  ((GetKeyState(VK_CONTROL)  &  0x8000)  !=  0));  
             break;  
                 default:  
                      break;  
           }  
       }  
 
   return  (fEatKeystroke  ?  TRUE  :  CallNextHookE(glhHook,nCode,wParam,lParam));  
}  
    大家可以看到,当程序发现按下的是Win键或者Alt+Tab组合键,就不再调用CallNextHookEx函数将这个消息传递下去。以此,我们做到了屏蔽这些按键的响应。  
 
    第二步,钩子DLL的测试程序。在VC中创建一个基于对话框的应用程序。通过调用LoadLibrary("KeyMask.dll")载入钩子DLL,通过GetProcAddress(m_hDll,"StartKeyMask")和GetProcAddress(m_hDll,"StopKeyMask")导入两个安装/卸载钩子的函数。在主对话框上定义两个按钮分别调用这两个函数,如下:  
 
    当按下“Start_Hook”按钮,我们的钩子函数就起作用了。试一下Win键,或者Alt+Tab组合键,没反应了吧?!“Stop_Hook”按钮可以解除这个钩子。  
 
    讲到这,大家可能觉得钩子其实也是很容易的东西。是的,钩子容易使用,而且功能强大。但是,笔者建议,如果不是十分必要,请尽量少用钩子。因为钩子在实现强大功能的同时,可能也会严重降低你系统的性能。有时候是得不偿失的!  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多