QT中键盘钩子的使用

Posted chyshx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QT中键盘钩子的使用相关的知识,希望对你有一定的参考价值。

Qt是一个跨平台开发的框架,可以实现一套代码多平台编译运行。但是有时候我们想实现的功能却和平台深度挂钩,比如本文想要描述的键盘钩子,也就是KeyBoard Hook。在Windows平台开发时,如果我们需要监听键盘的操作或者屏蔽一些键盘操作时,比较容易的办法就是使用Windows 自带的API,包含SetWindowsHookEx、CallNextHookEx、UnhookWindowsHookEx。但是Mac系统下是没有这些API供我们使用的,那么在使用Qt进行扩平台开发时,我们该如何做呢?
可以想到的办法就是使用条件编译的方式,让我们的软件能够在Windows平台下先支持键盘钩子。那如果进行条件编译呢,主要需要关注一下几个地方:
1.首先需要在Qt的工程文件中,添加lib文件user32.lib,因为该lib是一个系统lib,所以我们只需要指定名称即可,需要注意的是我们希望是只在win系统下引入库,所以我们可以进行lib引用的限定(也可以通过在项目节点上右键,添加库的方式添加,效果一样),如下所示:
技术图片

 

 2.windows.h文件的导入,QT已经自带一些预定义宏来标识系统类型,如Q_OS_WIN代表windows系统,Q_OS_MAC代表MAC OS,这些内容可以查看帮助文档。此时,我们将windows.h的include操作就可以放到一个系统类型判断条件中了,如下所示:
技术图片

 

 这样一来,当把整个功能移植到MAC上进行编译时,由于条件不满足,所以也就不会引入这个windows.h文件。

3.安装钩子以及卸载钩子的操作,也可以放到条件编译中去,如图:

技术图片

 

 这样确保函数的定义都在Windows系统下定义和实现,在其他平台编译时不会出错。

4.最后一步就是调用时夜的根据不同的系统去调用,比如当前是Windows,那么我们就可以调用这些定义的API。

技术图片

 

 这些是本人在研究跨平台桌面程序开发时遇到的关于与平台挂钩的键盘钩子功能时的处理方式。

附上本人的键盘钩子代码。

Hook.h

 1 #ifndef HOOK_H
 2 #define HOOK_H
 3 #include<QObject>
 4 #ifdef Q_OS_WIN
 5 #include"Windows.h"
 6 
 7 class Hook
 8 {
 9 public:
10     Hook();
11     void installHook();
12     void unInstallHook();
13 };
14 
15 #endif
16 #endif // HOOK_H

Hook.c

 1 #include "hook.h"
 2 #include<QDebug>
 3 #ifdef Q_OS_WIN
 4 Hook::Hook()
 5 {
 6 
 7 }
 8 
 9 static HHOOK keyHook=nullptr;
10 LRESULT CALLBACK keyProc(int nCode,WPARAM wParam,LPARAM lParam)
11 {
12     KBDLLHOOKSTRUCT *pkbhs=(KBDLLHOOKSTRUCT*)lParam;
13     if(nCode == HC_ACTION){
14             if(pkbhs->vkCode == VK_ESCAPE && GetAsyncKeyState(VK_CONTROL)& 0x8000 && GetAsyncKeyState(VK_SHIFT)&0x8000){
15                         qDebug() << "Ctrl+Shift+Esc";
16             }else if(pkbhs->vkCode == VK_ESCAPE && GetAsyncKeyState(VK_CONTROL) & 0x8000){
17                 qDebug() << "Ctrl+Esc";
18             }else if(pkbhs->vkCode == VK_TAB && pkbhs->flags & LLKHF_ALTDOWN){
19                 qDebug() << "Alt+Tab";
20             }else if(pkbhs->vkCode == VK_ESCAPE && pkbhs->flags &LLKHF_ALTDOWN){
21                 qDebug() << "Alt+Esc";
22             }else if(pkbhs->vkCode == VK_LWIN || pkbhs->vkCode == VK_RWIN){
23                 qDebug() << "LWIN/RWIN";
24             }else if(pkbhs->vkCode == VK_F4 && pkbhs->flags & LLKHF_ALTDOWN){
25                 qDebug() << "Alt+F4";
26             }
27             return 1;//返回1表示截取消息不再传递,返回0表示不作处理,消息继续传递
28         }
29         return CallNextHookEx(keyHook, nCode, wParam, lParam);
30 }
31 
32 void Hook::unInstallHook()
33 {
34     if(keyHook!=nullptr)
35     {
36         UnhookWindowsHookEx(keyHook);//键盘钩子句不为空时销毁掉
37         keyHook=nullptr;
38     }
39    if(keyHook!=nullptr)
40     {
41         UnhookWindowsHookEx(keyHook);//键盘钩子句不为空时销毁掉
42         keyHook=nullptr;
43     }
44 }
45 
46 void Hook::installHook()
47 {
48     keyHook =SetWindowsHookEx( WH_KEYBOARD_LL,keyProc,nullptr,0);
49     qDebug() << "0";
50 }
51 #endif

 

以上是关于QT中键盘钩子的使用的主要内容,如果未能解决你的问题,请参考以下文章

使用低级键盘钩子更改键盘字符

全局键盘钩子

delphi键盘钩子没效果

QtApplets-MyHook

想用VC++做个全局键盘改键,键盘钩子代码,详细怎么做。跪求代码。

VC 键盘钩子问题