当前位置: 首页 > backend >正文

使用qt 定义全局钩子 捕获系统的键盘事件

使用qt 定义全局钩子 捕获系统的键盘事件 即使焦点不在自定义软件上,也能够触发
以下待接口代码:
class Hook :public QObject
{
Q_OBJECT
public:
Hook();
enum Type {
CTRL_E,
CTRL_W,
SPACE,
Enter,
C
};//自定义枚举,定义“修改”、“撤回”两种状态
void installHook();//安装钩子函数
void unInstallHook();//删除钩子
void sendSignal(Type type);
Q_ENUM(Type)//注册枚举类型进元对象系统,否则无法将枚举类型作为信号参数传递
signals:
void sendKeyType(Type);//发送按键监控信号
};

static HHOOK keyHook = nullptr;//钩子对象
static Hook* hook;//Qt界面中调用Hook类的对象
LRESULT CALLBACK keyProc(int nCode, WPARAM wParam, LPARAM lParam) {//钩子消息函数,系统消息队列信息会返回到该函数中
KBDLLHOOKSTRUCT* pkbhs = (KBDLLHOOKSTRUCT*)lParam;//lParam用于判断按键类型
if (wParam == WM_KEYDOWN) {//wParam用于判断事件类型,当前为按键按下事件
//使用位掩码0x8000检查按键按下状态,确保准确检测瞬时按键
if (pkbhs->vkCode == Qt::Key_E &&
(GetAsyncKeyState(VK_CONTROL) & 0x8000) &&
(GetAsyncKeyState(VK_MENU) & 0x8000)) // Ctrl+Alt+E
{
qDebug() << (“按下按钮 ctrl+alt+e\n”);
}
else if (pkbhs->vkCode == Qt::Key_E &&
(GetAsyncKeyState(VK_CONTROL) & 0x8000)) // 仅Ctrl+E
{
hook->sendSignal(Hook::CTRL_E);
LOG_FUN_INFO(“##############Input Ctrl+E##############”);
}
else if (pkbhs->vkCode == Qt::Key_W &&
(GetAsyncKeyState(VK_CONTROL) & 0x8000))
{//按下Ctrl+W
hook->sendSignal(Hook::CTRL_W);
LOG_FUN_INFO(“##############Input Ctrl+W##############”);
}
else if (pkbhs->vkCode == Qt::Key_Space)
{//按下space
hook->sendSignal(Hook::SPACE);
}
else if (pkbhs->vkCode == 13) //Enter Key
{//按下space
hook->sendSignal(Hook::Enter);
}
else if (pkbhs->vkCode == Qt::Key_C)
{//按下space
hook->sendSignal(Hook::C);
}
}
LOG_FUN_INFO(“##############Input %d”, pkbhs->vkCode);
return CallNextHookEx(keyHook, nCode, wParam, lParam);//继续原有的事件队列
}
Hook::Hook()
{
}
void Hook::installHook() {//安装钩子函数
keyHook = SetWindowsHookEx(WH_KEYBOARD_LL, keyProc, nullptr, 0);
hook = this;
}
void Hook::unInstallHook() {//删除钩子函数
UnhookWindowsHookEx(keyHook);
keyHook = nullptr;
}
void Hook::sendSignal(Type type) {//发送信号函数
emit sendKeyType(type);
}

http://www.xdnf.cn/news/12064.html

相关文章:

  • 《人性的弱点》核心总结
  • AI基础认知
  • 【Python连接数据库基础 06】Pandas与SQL协同:解锁大规模数据处理新境界,让分析效率飙升10倍
  • 代理IP:6G标准化进程中的隐形推手
  • 如何在 React 中监听 div 的滚动事件
  • Pendulum:优雅处理 Python 中的日期与时间
  • vue3动态插入iframe,内容被取消的原因
  • pack 布局管理器
  • 第十三节:第三部分:集合框架:Map集合的遍历方式
  • 数码相片冲印规格参考表
  • Docker load 后镜像名称为空问题的解决方案
  • 国芯思辰ADE芯片成功替代ADS1296R,除颤仪核心部件实现自主可控
  • git删除本地分支和远程分支
  • 非对称加密
  • MuLogin浏览器如何使用Loongproxy?
  • 【AI系列】DPO 与 PPO 的比较与分析
  • 民锋视角下的资金流效率与账户行为建模
  • 解决fastadmin、uniapp打包上线H5项目路由冲突问题
  • Netty内存池之内存分配算法
  • 字符串接龙
  • Java 大视界 — Java 大数据在智能安防视频监控中的异常事件快速响应与处理机制
  • 未来的AI 终端
  • 系统性学习C语言-第十四讲-深入理解指针(4)
  • 《仿盒马》app开发技术分享-- 商品搜索页(顶部搜索bar热门搜索)(端云一体)
  • 中级统计师-经济学基础知识-第一章 经济学基础
  • android与Qt类比
  • 重要通知:6月申报纳税期限延至6月16日(附2025年办税日历 图文版)
  • 树莓派超全系列教程文档--(53)如何使用 SCP 共享文件
  • 嵌入式开发之STM32学习笔记day18
  • 手写Promise实例方法finally