Qt之Hook(键盘钩子)的简单使用(挂接截图程序,含源码+注释) 您所在的位置:网站首页 qt截屏函数 Qt之Hook(键盘钩子)的简单使用(挂接截图程序,含源码+注释)

Qt之Hook(键盘钩子)的简单使用(挂接截图程序,含源码+注释)

2023-06-29 02:22| 来源: 网络整理| 查看: 265

一、后台钩子截图调用示例

在这里插入图片描述

二、钩子的个人理解 挂接钩子的步骤:SetWindowsHookEx -> UnhookWindowsHookEx,直接用SetWindowsHookEx 函数挂接到对应的钩子类型和处理函数中;当钩子使用完后需要调用UnhookWindowsHookEx函数卸载(因为钩子消耗系统性能)。 SetWindowsHookEx 函数原型如下: //! int idHook 所监控的挂钩类型 //! HOOKPROC lpfn 监控信息的处理函数 //! HINSTANCEhMod 监控信息的动态链接位置 nullptr则与本线程相关 //! DWORD dwThreadId 挂钩线程id 0则代表当前 决定了此钩子是系统钩子还是线程钩子 //! 返回值 函数执行成功,则返回值为对应的钩子句柄;若此函数执行失败,则返回值为NULL(0) HHOOK SetWindowsHookEx(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId);

SetWindowsHookEx 函数原型如下:

//! hHook 要卸载的钩子句柄 BOOL UnhookWindowsHookEx(HHOOK hHook); 各个类型的钩子原型一致,如下: /** * @brief Hookproc * @param code 这是一个整数值,用于指定发送到钩子过程的消息类型。它可以是几个值中的一个,例如HC_ACTION、HC_NOREMOVE或HC_CREATE * @param wParam 一个指向宽字符值的指针,其中包含有关发送到钩子过程的消息的附加信息,其值取决于code的值 * @param lParam 一个指向长字符值的指针,其中包含有关发送到钩子过程的消息的附加信息,其值取决于code的值 * @return 如果返回0,则消息未被处理,将继续由其他钩子或目标窗口处理。如果返回非零值,则消息已被钩子过程处理,不会被其他钩子或目标窗口处理 */ LRESULT Hookproc(int code, WPARAM wParam, LPARAM lParam) 不同的钩子对应的数据结构体及参数含义不同,如当关联键盘钩子(WH_KEYBOARD_LL)时,其lParam参数代表的结构体为KBDLLHOOKSTRUCT;当关联鼠标钩子(WH_MOUSE_LL)时,其wParam代表鼠标操作的类型(如左键按下、放开等),lParam参数代表的结构体为MSLLHOOKSTRUCT。具体可按需求查看对应内容。推荐的链接:官方链接、钩子(HOOK)函数教程 三、源码 CHook.h #ifndef CHOOK_H #define CHOOK_H // 干净的钩子类 class CHook { public: explicit CHook(); ~CHook(); }; #endif // CHOOK_H CHook.cpp #include "CHook.h" #include "CMainWindow.h" #include #include // 引用全局变量 extern CMainWindow *g_mainWdindow; HHOOK g_hook; // 钩子对象 /** * @brief Hookproc * @param code 这是一个整数值,用于指定发送到钩子过程的消息类型。它可以是几个值中的一个,例如HC_ACTION、HC_NOREMOVE或HC_CREATE * @param wParam 一个指向宽字符值的指针,其中包含有关发送到钩子过程的消息的附加信息,其值取决于code的值 * @param lParam 一个指向长字符值的指针,其中包含有关发送到钩子过程的消息的附加信息,其值取决于code的值 * @return 如果返回0,则消息未被处理,将继续由其他钩子或目标窗口处理。如果返回非零值,则消息已被钩子过程处理,不会被其他钩子或目标窗口处理 */ LRESULT Hookproc(int code, WPARAM wParam, LPARAM lParam) { // lParam强转为键盘数据结构体 KBDLLHOOKSTRUCT *data = (KBDLLHOOKSTRUCT *)lParam; //! GetAsyncKeyState //! 获取指定按钮状态:非0则为按下状态,为0则为未按下状态 // 当Ctrl、Alt、X都按下时进入 if(GetAsyncKeyState(VK_LCONTROL) && GetAsyncKeyState(VK_LMENU) && 0x58 == data->vkCode && g_mainWdindow->screenShotFlag()) { // 调用截图 g_mainWdindow->startScreenShot(); } return CallNextHookEx(g_hook, code, wParam, lParam); } CHook::CHook() { //! SetWindowsHookEx 函数解释 //! int idHook 所监控的挂钩类型 //! HOOKPROC lpfn 监控信息的处理函数 //! HINSTANCEhMod 监控信息的动态链接位置 nullptr则与本线程相关 //! DWORD dwThreadId 挂钩线程id 0则代表当前 决定了此钩子是系统钩子还是线程钩子 //! 返回值 函数执行成功,则返回值就是该挂钩处理过程的句柄;若此函数执行失败,则返回值为NULL(0) g_hook = SetWindowsHookEx(WH_KEYBOARD_LL, Hookproc, nullptr, 0); } CHook::~CHook() { // 卸载钩子 UnhookWindowsHookEx(g_hook); } main.cpp #include "CMainWindow.h" #include #include "CHook.h" CMainWindow *g_mainWdindow; int main(int argc, char *argv[]) { QApplication a(argc, argv); // 创建钩子对象 CHook hook; // 创建程序对象 g_mainWdindow = new CMainWindow; // 初始化程序 g_mainWdindow->initialize(); int ret = a.exec(); // 反初始化 g_mainWdindow->uninitialize(); delete g_mainWdindow; return ret; } 总结

使用钩子时注意数据的类型及参数的含义,不同的钩子其参数及含义不同需要好好记一下;包括钩子可以封装在库中或子线程中调用,该部分文中没有体现,值得研究一下。

相关文章

Qt之QGraphicsView实现截图(漏洞百出且BUG丛生版,部分源码+注释)

友情提示——哪里看不懂可私哦,让我们一起互相进步吧 (创作不易,请留下一个免费的赞叭 谢谢 o/)

注:文章为作者编程过程中所遇到的问题和总结,内容仅供参考,若有错误欢迎指出。 注:如有侵权,请联系作者删除



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有