找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 14548|回复: 0
打印 上一主题 下一主题
收起左侧

使用WH_KEYBOARD_LL 低级键盘钩子屏蔽系统热键

[复制链接]
跳转到指定楼层
楼主
ID:71922 发表于 2015-1-11 00:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  VC中使用低级钩子捕获系统按键

在VC中捕按键可以在OnKeyDown 或 OnKeyUp 事件中进行捕获,不过这有很大的局限性,这里只能捕获用户按键。但在一些特殊的工程(项目)中往往需要捕获某些系统按键以完成特殊的功能,我们就不得不选择钩子了,一般情况下大家都会选择 WH_KEYBOARD 这个钩子类型,但是在编写过程会发现这个钩子类型并不能捕获所有的系统按键,怎么办呢?那就得选择 WH_KEYBOARD_LL (低级键盘钩子)了,使用它可以捕获全部的系统按键,一个不漏……
在使用低级键盘钩子之前,先在 StdAfx.h 的第一行添加一条: #define _WIN32_WINNT 0x400               (这里假定你是用的 MFC 的 DLL),不然在编译的时候会提示说 WH_KEYBOARD_LL 没有定义。网上还有另一种方法:首先定义 #define WH_KEYBOARD_LL 13     ; 然后 Winuser.h 中定义的 tagKBDLLHOOKSTRUCT 代码拷贝到工程中。
下面代码用以捕获系统按键:
/*
用户模块
return TRUE; --->丢弃该消息
*/
LRESULT CALLBACK Hotkey_Filter(int nCode, WPARAM wParam, LPARAM lParam)
{
           KBDLLHOOKSTRUCT *Key_Info = (KBDLLHOOKSTRUCT*)lParam;
            if (HC_ACTION == nCode)
            {
                        if (WM_KEYDOWN == wParam || WM_SYSKEYDOWN)  //如果按键为按下状态
                        {
                                    if (Key_Info->vkCode == VK_LWIN || Key_Info->vkCode == VK_RWIN) //屏敝 WIN(左右) 键
                                    {
                                                return TRUE;
                                    }
                                    if (Key_Info->vkCode == 0x4D && ((GetKeyState(VK_LWIN) & 0x8000) ||
                                                                                                   (GetKeyState(VK_RWIN) & 0x8000))) //屏敝 WIN+D 组合键(左右)
                                    {
                                                return TRUE;
                                    }
                                    if (Key_Info->vkCode == 0x44 && ((GetKeyState(VK_LWIN) & 0x8000) ||
                                                                                                   (GetKeyState(VK_LWIN) & 0x8000)))  //屏敝 WIN+M 组合键(左右)
                                    {
                                                return TRUE;
                                    }
                                    if (Key_Info->vkCode == 0x1b && GetKeyState(VK_CONTROL) & 0x8000) //屏敝 CTRL + ESC 组合键
                                    {
                                                return TRUE;
                                    }
                                    if (Key_Info->vkCode == VK_TAB && Key_Info->flags & LLKHF_ALTDOWN) //屏敝 ATL + TAB 组合键
                                    {
                                                return TRUE;
                                    }
                                     if (Key_Info->vkCode == VK_ESCAPE && Key_Info->flags & LLKHF_ALTDOWN) //屏敝 ATL + ESC 组合键
                                    {
                                                return TRUE;
                                    }
                        }

            }
            return CallNextHookEx(h_HotKey, nCode, wParam, lParam); //回调
}
BOOL Hotkey_Install(DWORD ThreadID)
{
            h_HotKey = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)Hotkey_Filter, //安装低级键盘钩子
           GetModuleHandle("hotkey"), ThreadID);
            if (NULL == h_HotKey)
            {
                        MessageBox(NULL, "安装钩子出错 !", "error", MB_ICONSTOP);
                        return FALSE;
            }
            return TRUE;
}
BOOL Hotkey_UnInstall()
{
            UnhookWindowsHookEx(h_HotKey); //卸载钩子
            return TRUE;
}
  *** 注意***
此钩子必须是系统级的钩子,也就是说在安装钩子的时候,ThreadID 的值必须为0。
在这儿需要特别说明的是:if (WM_KEYDOWN == wParam || WM_SYSKEYDOWN) ,如果不加这句,按键信息会被响应两次(KeyUP & KeyDown),
开始我只写了 if  (WM_KEYDOWN == wParam) ,在捕获 ALT+TAB 时就一直出错,找不到方向,后来才想到 ALT 键盘是系统键,所以必须得加上
WM_SYSKEYDOWN,这样才能捕获 ALT+TAB ! if (WM_KEYDOWN == wParam || WM_SYSKEYDOWN) 也可以写成 if (WM_KEYDOWN == wParam || WM_SYSKEYDOWN  ==  wParam)
如果要想屏敝 CTRL+ALT+DEL 键的话,也可能用相当的方法!不过可以用一种更简单的方法来屏敝 CTRL+ALT+DEL :屏敝这个组合键的其中任意一个
按键便可达到相同的效果。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表