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

原文地址:https://www.cnblogs.com/chyshx/p/12614148.html

时间: 2024-10-10 13:30:26

QT中键盘钩子的使用的相关文章

Qt中的键盘事件,以及焦点的设置(比较详细)

Qt键盘事件属于Qt事件系统,所以事件系统中所有规则对按键事件都有效.下面关注点在按键特有的部分: focus 一个拥有焦点(focus)的QWidget才可以接受键盘事件.有输入焦点的窗口是活动窗口或活动窗口子窗口或子子窗口等. 焦点移动的方式有以下几种: 按下Tab或Shift+Tab 注意:文本编译器(一般需要插入Tab),或者WebView(需要Tab来移动超链接焦点) 等 Qt中,需要输入Tab的地方可以用 Ctrl+Tab 或 Ctrl+Shift+Tab 替代. 点击一个QWidg

2.添加键盘钩子。向进程中注入dll

学习笔记 1.首先要建立mfc的动态链接库.在def文件中放入要导出的函数名. 2.添加函数如下 //安装钩子 //HHOOK SetWindowsHookEx( // int idHook,//钩子的类型WH_KEYBOARD键盘钩子 // HOOKPROC lpfn,//钩子的回调函数,钩子类型不同回调函数不同 // HINSTANCE hwnd,//dll动态链接库的句柄 // DWORD dwthreadid//游戏主进程的id 是GetWindowThreadProcessId的返回值

在WPF中快速实现键盘钩子

大部分的时候,当我们需要键盘事件的时候,可以通过在主窗口注册KeyBinding来实现,不过,有的时候我们需要的是全局键盘事件,想在任何一个地方都能使用,最开始的时候我是通过键盘钩子来实现的, 不过键盘钩子这种DLL调用的方式怎么都看着不大爽,这里介绍一种通过EventManager快速实现键盘事件感知的例子. public class KeyboardEvents { public static event Action<KeyEventArgs> OnKeyDown; static Key

使用raw input 代替全局键盘钩子

//关于raw input 请查看msdn https://msdn.microsoft.com/en-us/library/windows/desktop/ms645536%28v=vs.85%29.aspx //效率 比 键盘钩子高太多 ,但是BCB 中无法识别 RAWINPUTDEVICE 结构 和RAW相关的函数 // rawinput4.cpp : 定义应用程序的入口点. // #include "stdafx.h" #include "rawinput4.h&qu

Qt中如何禁掉所有UI操作以及注意事项(处理各个widget的eventFilter这一层,但是感觉不好,为什么不使用QApplication呢)

刚做完的一个项目,在测试时出现了一个问题:由于多线程的存在,当进行语音识别时:如果用户点击程序界面上的button或者其他接受点击事件后会发出信号的widget时,程序会crash ! 后来尝试着从多线程上去解决,但是比较困难:后来只能从另外一条路来解决,那就是:当语音识别进行时:禁掉一切用户操作! 所谓的禁掉一切UI操作,在手机等手持设备上,尤其是纯触摸屏的设备上,主要就是指的禁止mouse操作!当然了:也可能是禁止键盘操作等.那如何去做这一点呢? 方法:我们可以截获禁止操作的窗口的所有eve

C#实现键盘钩子

前言: 因为项目中需要使用到快捷键,所以上网找资料了解关于快捷键的实现技术,于是有了键盘钩子的使用学习.在网上了解到,键盘钩子其实只是很多种钩子中的其中一种.所谓钩子:请看下面关于钩子的描述(来自百度百科): Windows系统是建立在事件驱动的机制上的,说穿了就是整个系统都是通过消息的传递来实现的.而钩子是Windows系统中非常重要的系统接口,用它可以截获并处理送给其他应用程序的消息,来完成普通应用程序难以实现的功能. 钩子可以监视系统或进程中的各种事件消息,截获发往目标窗口的消息并进行处理

Qt中事件处理的方法(三种处理方法,四种覆盖event函数,notify函数,event过滤,事件处理器。然后继续传递给父窗口。可观察QWidget::event的源码,它是虚拟保护函数,可改写)

一.Qt中事件处理的方式 1.事件处理模式一 首先是事件源产生事件,最后是事件处理器对这些事件进行处理.然而也许大家会问, Qt中有这么多类的事件,我们怎么样比较简便的处理每个事件呢?设想,如果是每个事件都对应同一个事件处理器,在该事件处理器中对不同的事件进行分类处理,这样的弊端有两点:第一,导致该事件处理器过于臃肿复杂:第二,这样不便于扩展,当系统新增加事件类型或者是我们需要使用到自定义事件时,就不得不修改Qt的源码来达到目的.所以Qt设计者的做法是针对不同类型的事件提供不同的事件处理器与之对

(转)QT中QWidget、QDialog及QMainWindow的区别

QWidget类是所有用户界面对象的基类. 窗口部件是用户界面的一个基本单元:它从窗口系统接收鼠标.键盘和其它事件,并且在屏幕上绘制自己.每一个窗口部件都是矩形的,并且它们按Z轴顺序排列.一个窗口部件可以被它的父窗口部件或者它前面的窗口部件盖住一部分. QMainWindow 类提供一个有菜单条.锚接窗口(例如工具条)和一个状态条的主应用程序窗口.主窗口通常用在提供一个大的中央窗口部件(例如文本编辑或者绘制画布)以及周围 菜单.工具条和一个状态条.QMainWindow常常被继承,因为这使得封装

Qt 中一些常用类中文说明

Qt 中一些常用类中文说明是本文讲述的内容,这篇文章主要是介绍Qt 当中经常使用的类,采取的是使用字母索引的方式,下面的类是被经常使用的. QDataStream 为QIODevice提供了一串的二进制的数据 QDataWidgetMapper 提供了从数据模型到部件的映射 QData 日期的功能 QDateEdit 提供了日期的部件用来编辑日期,是基于QDateTimeEdit 部件 QDateTime 提供日期与时间的功能 QDateTimeEdit 提供了编辑日期与实践的部件 QDBusA