zoukankan      html  css  js  c++  java
  • QtQt使用鍵盘钩子Hook(支持判断按下、弹起、自动)

    相关资料:

    https://www.cnblogs.com/chyshx/p/12614148.html      钩子的使用

    http://www.bubuko.com/infodetail-3073312.html      虚拟键码表(供函数GetAsyncKeyState()使用)

    https://blog.csdn.net/joyopirate/article/details/109077913       Qt利用钩子函数实现键盘监听

    https://download.csdn.net/download/zhujianqiangqq/71923476         csdn代码包下载

    实例代码:

    .pro

     1 QT       += core gui
     2 
     3 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
     4 
     5 CONFIG += c++11
     6 
     7 # The following define makes your compiler emit warnings if you use
     8 # any Qt feature that has been marked deprecated (the exact warnings
     9 # depend on your compiler). Please consult the documentation of the
    10 # deprecated API in order to know how to port your code away from it.
    11 DEFINES += QT_DEPRECATED_WARNINGS
    12 
    13 # You can also make your code fail to compile if it uses deprecated APIs.
    14 # In order to do so, uncomment the following line.
    15 # You can also select to disable deprecated APIs only up to a certain version of Qt.
    16 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    17 
    18 SOURCES += \
    19     Hook.cpp \
    20     main.cpp \
    21     mainwindow.cpp
    22 
    23 HEADERS += \
    24     Hook.h \
    25     mainwindow.h
    26 
    27 FORMS += \
    28     mainwindow.ui
    29 
    30 LIBS += -luser32
    31 
    32 # Default rules for deployment.
    33 qnx: target.path = /tmp/$${TARGET}/bin
    34 else: unix:!android: target.path = /opt/$${TARGET}/bin
    35 !isEmpty(target.path): INSTALLS += target
    View Code

    main.cpp

     1 #include "mainwindow.h"
     2 
     3 #include <QApplication>
     4 
     5 int main(int argc, char *argv[])
     6 {
     7     QApplication a(argc, argv);
     8     MainWindow w;
     9     w.show();
    10     return a.exec();
    11 }
    View Code

    manwindow.h

     1 #ifndef MAINWINDOW_H
     2 #define MAINWINDOW_H
     3 
     4 #include <windows.h>
     5 #include <winuser.h>
     6 
     7 
     8 #include <QMainWindow>
     9 #include <QKeyEvent>
    10 #include <QDebug>
    11 #include <QDateTime>
    12 #include "Hook.h"
    13 
    14 QT_BEGIN_NAMESPACE
    15 namespace Ui { class MainWindow; }
    16 QT_END_NAMESPACE
    17 
    18 class MainWindow : public QMainWindow
    19 {
    20     Q_OBJECT
    21 
    22 public:
    23     MainWindow(QWidget *parent = nullptr);
    24     ~MainWindow();
    25 private slots:
    26     void on_pushButton_clicked();
    27     void UpdateCapslockTip(int keyCode, bool downOrUp, bool aotu);
    28 private:
    29     Ui::MainWindow *ui;
    30     Hook *m_pHook;
    31 };
    32 #endif // MAINWINDOW_H
    View Code

    mainwindow.cpp

     1 #include "mainwindow.h"
     2 #include "ui_mainwindow.h"
     3 
     4 MainWindow::MainWindow(QWidget *parent)
     5     : QMainWindow(parent)
     6     , ui(new Ui::MainWindow)
     7 {
     8     ui->setupUi(this);
     9     setWindowTitle(QStringLiteral("Qt使用鍵盘钩子Hook(支持判断按下、弹起、自动)"));
    10 
    11     #ifdef Q_OS_WIN
    12     m_pHook = new Hook();
    13     m_pHook->installHook();
    14     m_pHook->SetKeyboardCall(std::bind(&MainWindow::UpdateCapslockTip, this, std::placeholders::_1,std::placeholders::_2,std::placeholders::_3));
    15     #endif
    16 }
    17 
    18 MainWindow::~MainWindow()
    19 {
    20     m_pHook->unInstallHook();
    21     delete ui;
    22 }
    23 
    24 void MainWindow::on_pushButton_clicked()
    25 {
    26     ui->textEdit->clear();
    27 }
    28 
    29 void MainWindow::UpdateCapslockTip(int keyCode, bool downOrUp, bool aotu)
    30 {
    31     QString s = "key pressed:--------:%1  downOrUp:%2  aotu:%3";
    32     s = s.arg(keyCode).arg(downOrUp).arg(aotu);
    33     ui->textEdit->append(s);
    34     qDebug() << "key pressed:--------:" << keyCode
    35              << "downOrUp:" << downOrUp
    36              << "aotu:" << aotu;
    37 }
    View Code

    hook.h

     1 #ifndef HOOK_H
     2 #define HOOK_H
     3 
     4 #include<QObject>
     5 #include<QDebug>
     6 #ifdef Q_OS_WIN  // 代表只有WIN系统才会启用
     7 #include"Windows.h"
     8 #include <functional>// 回调函数引入
     9 #include <QDateTime>// 时间函数引入
    10 
    11 class Hook
    12 {
    13 public:
    14     Hook();
    15     void installHook();
    16     void unInstallHook();
    17     static LRESULT CALLBACK keyProc(int nCode,WPARAM wParam,LPARAM lParam);
    18     void SetKeyboardCall(const std::function<void (int,bool,bool)> & func){ m_func = func; }
    19 private:
    20     static std::function<void(int,bool,bool)> m_func;
    21 };
    22 #endif
    23 
    24 #endif // HOOK_H
    View Code

    hook.cpp

      1 #include "Hook.h"
      2 
      3 #ifdef Q_OS_WIN
      4 Hook::Hook()
      5 {
      6 
      7 }
      8 
      9 static HHOOK keyHook = nullptr;
     10 std::function<void(int,bool,bool)> Hook::m_func = nullptr;
     11 bool m_bAuto = false;// 是否为自动按键,false代表是手动按下,true代表是自动按下。
     12 int m_nKey = 0;// 上次的按键值
     13 bool m_bDownOrUp = false;// 是否按下,false弹起,true按下。
     14 
     15 LRESULT CALLBACK Hook::keyProc(int nCode,WPARAM wParam,LPARAM lParam)
     16 {
     17     // GetAsyncKeyState 判断正在按下某键 取异步键状态 物理键状态(实际的)
     18     // GetKeyState GetKeyboardState 判断刚按过了某键 逻辑键状态(虚拟的)
     19 //    KBDLLHOOKSTRUCT *pkbhs=(KBDLLHOOKSTRUCT*)lParam;
     20 //    if(nCode == HC_ACTION){
     21 //            if(pkbhs->vkCode == VK_ESCAPE && GetAsyncKeyState(VK_CONTROL)& 0x8000 && GetAsyncKeyState(VK_SHIFT)&0x8000){
     22 //                        qDebug() << "Ctrl+Shift+Esc";
     23 //            }else if(pkbhs->vkCode == VK_ESCAPE && GetAsyncKeyState(VK_CONTROL) & 0x8000){
     24 //                qDebug() << "Ctrl+Esc";
     25 //            }else if(pkbhs->vkCode == VK_TAB && pkbhs->flags & LLKHF_ALTDOWN){
     26 //                qDebug() << "Alt+Tab";
     27 //            }else if(pkbhs->vkCode == VK_ESCAPE && pkbhs->flags &LLKHF_ALTDOWN){
     28 //                qDebug() << "Alt+Esc";
     29 //            }else if(pkbhs->vkCode == VK_LWIN || pkbhs->vkCode == VK_RWIN){
     30 //                qDebug() << "LWIN/RWIN";
     31 //            }else if(pkbhs->vkCode == VK_F4 && pkbhs->flags & LLKHF_ALTDOWN){
     32 //                qDebug() << "Alt+F4";
     33 //            }
     34 //            return CallNextHookEx(keyHook, nCode, wParam, lParam);//返回1表示截取消息不再传递,返回0表示不作处理,消息继续传递
     35 //        }
     36 
     37     // 当前进程
     38     HWND hwnd = GetForegroundWindow();
     39     DWORD Fid = GetWindowThreadProcessId(hwnd, NULL);
     40     DWORD Cid = GetCurrentThreadId();
     41     if (Fid != Cid)
     42     {
     43         return CallNextHookEx(keyHook, nCode, wParam, lParam);
     44     }
     45 
     46      KBDLLHOOKSTRUCT *pKBDLLHook= (KBDLLHOOKSTRUCT*)lParam;
     47 
     48      if(nCode == HC_ACTION){
     49          // 处理自动按下
     50          if (m_nKey == (int)pKBDLLHook->vkCode)
     51          {
     52              m_bAuto = true;
     53          }else
     54          {
     55              m_bAuto = false;
     56              m_nKey = pKBDLLHook->vkCode;
     57          }
     58 
     59          if (wParam== WM_KEYDOWN)
     60          {
     61              m_bDownOrUp = true;
     62          }
     63          if (wParam== WM_KEYUP)
     64          {
     65              m_bDownOrUp = false;
     66              m_bAuto = false;
     67              m_nKey = 0;
     68          }
     69      }
     70 
     71      if (m_func)
     72      {
     73          m_func(pKBDLLHook->vkCode, m_bDownOrUp, m_bAuto);
     74      }
     75 
     76 //     if (GetAsyncKeyState(VK_LSHIFT)&0x8000)
     77 //     {
     78 //         QDateTime dateTime;
     79 //         QString s;
     80 //         s = "WM_KEYUP:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_LSHIFT";
     81 //         qDebug() << s;
     82 //     }
     83 //     if (GetAsyncKeyState(VK_RSHIFT)&0x8000)
     84 //     {
     85 //         QDateTime dateTime;
     86 //         QString s;
     87 //         s = "WM_KEYUP:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_RSHIFT";
     88 //         qDebug() << s;
     89 //     }
     90 //     if (GetAsyncKeyState(VK_UP)&0x8000)
     91 //     {
     92 //         QDateTime dateTime;
     93 //         QString s;
     94 //         s = "WM_KEYUP:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_UP";
     95 //         qDebug() << s;
     96 //     }
     97 //     if (GetAsyncKeyState(VK_DOWN)&0x8000)
     98 //     {
     99 //         QDateTime dateTime;
    100 //         QString s;
    101 //         s = "WM_KEYUP:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_DOWN";
    102 //         qDebug() << s;
    103 //     }
    104 //     if (GetAsyncKeyState(VK_LEFT)&0x8000)
    105 //     {
    106 //         QDateTime dateTime;
    107 //         QString s;
    108 //         s = "WM_KEYUP:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_LEFT";
    109 //         qDebug() << s;
    110 //     }
    111 //     if (GetAsyncKeyState(VK_RIGHT)&0x8000)
    112 //     {
    113 //         QDateTime dateTime;
    114 //         QString s;
    115 //         s = "WM_KEYUP:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_RIGHT";
    116 //         qDebug() << s;
    117 //     }
    118 //     if (GetAsyncKeyState(VK_RETURN)&0x8000)
    119 //     {
    120 //         QDateTime dateTime;
    121 //         QString s;
    122 //         s = "WM_KEYUP:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_RETURN";
    123 //         qDebug() << s;
    124 //     }
    125 //     if (GetAsyncKeyState(VK_ESCAPE )&0x8000)
    126 //     {
    127 //         QDateTime dateTime;
    128 //         QString s;
    129 //         s = "WM_KEYUP:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_ESCAPE ";
    130 //         qDebug() << s;
    131 //     }
    132 
    133 //    if (wParam== WM_KEYUP && pKBDLLHook->vkCode== VK_F10)
    134 //    {
    135 //        QDateTime dateTime;
    136 //        QString s;
    137 //        s = "WM_KEYUP:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_F10";
    138 //        qDebug() << s;
    139 //    }
    140 //    if (wParam== WM_KEYDOWN  && pKBDLLHook->vkCode== VK_F10)
    141 //    {
    142 //        QDateTime dateTime;
    143 //        QString s;
    144 //        s = "WM_KEYDOWN:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_F10";
    145 //        qDebug() << s;
    146 //    }
    147 //    if (wParam== WM_KEYUP && pKBDLLHook->vkCode== VK_TAB)
    148 //    {
    149 //        QDateTime dateTime;
    150 //        QString s;
    151 //        s = "WM_KEYUP:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_TAB";
    152 //        qDebug() << s;
    153 //    }
    154 //    if (wParam== WM_KEYDOWN  && pKBDLLHook->vkCode== VK_TAB)
    155 //    {
    156 //        QDateTime dateTime;
    157 //        QString s;
    158 //        s = "WM_KEYDOWN:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_TAB";
    159 //        qDebug() << s;
    160 //    }
    161 //    if (wParam== WM_KEYUP && pKBDLLHook->vkCode== 'A')
    162 //    {
    163 //        QDateTime dateTime;
    164 //        QString s;
    165 //        s = "WM_KEYUP:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - A";
    166 //        qDebug() << s;
    167 //    }
    168 //    if (wParam== WM_KEYDOWN  && pKBDLLHook->vkCode== 'A')
    169 //    {
    170 //        QDateTime dateTime;
    171 //        QString s;
    172 //        s = "WM_KEYDOWN:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - A";
    173 //        qDebug() << s;
    174 //    }
    175 //    if (pKBDLLHook->flags & LLKHF_ALTDOWN)
    176 //    {
    177 //        QDateTime dateTime;
    178 //        QString s;
    179 //        s = ":" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - LLKHF_ALTDOWN";
    180 //        qDebug() << s;
    181 //    }
    182 //    if (GetAsyncKeyState(VK_CONTROL)& 0x8000)
    183 //    {
    184 //        QDateTime dateTime;
    185 //        QString s;
    186 //        s = ":" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_CONTROL";
    187 //        qDebug() << s;
    188 //    }
    189 //    if (GetAsyncKeyState(VK_SHIFT)&0x8000)
    190 //    {
    191 //        QDateTime dateTime;
    192 //        QString s;
    193 //        s = ":" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - VK_SHIFT";
    194 //        qDebug() << s;
    195 //    }
    196 //    if (GetKeyState(VK_CONTROL)&0x8000)
    197 //    {
    198 //        QDateTime dateTime;
    199 //        QString s;
    200 //        s = ":" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - GetKeyState VK_CONTROL";
    201 //        qDebug() << s;
    202 //    }
    203 //    if (GetKeyState(VK_SHIFT)&0x8000)
    204 //    {
    205 //        QDateTime dateTime;
    206 //        QString s;
    207 //        s = ":" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - GetKeyState VK_SHIFT";
    208 //        qDebug() << s;
    209 //    }
    210 //    if (wParam== WM_KEYUP && (pKBDLLHook->vkCode == VK_LWIN || pKBDLLHook->vkCode == VK_RWIN))
    211 //    {
    212 //        QDateTime dateTime;
    213 //        QString s;
    214 //        s = "WM_KEYUP:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - WM_KEYUP WIN";
    215 //        qDebug() << s;
    216 //    }
    217 //    if (wParam== WM_KEYDOWN  && (pKBDLLHook->vkCode == VK_LWIN || pKBDLLHook->vkCode == VK_RWIN))
    218 //    {
    219 //        QDateTime dateTime;
    220 //        QString s;
    221 //        s = "WM_KEYDOWN:" + dateTime.currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") + " - WM_KEYDOWN WIN";
    222 //        qDebug() << s;
    223 //    }
    224     return CallNextHookEx(keyHook, nCode, wParam, lParam);
    225 }
    226 
    227 void Hook::unInstallHook()
    228 {
    229     if(keyHook != nullptr)// 原作者说是担心一次释放不稳定,才释放二次的。
    230     {
    231         UnhookWindowsHookEx(keyHook);//键盘钩子句不为空时销毁掉
    232         keyHook = nullptr;
    233     }
    234    if(keyHook != nullptr)
    235     {
    236         UnhookWindowsHookEx(keyHook);//键盘钩子句不为空时销毁掉
    237         keyHook = nullptr;
    238     }
    239 }
    240 
    241 void Hook::installHook()
    242 {
    243     keyHook = SetWindowsHookEx(WH_KEYBOARD_LL, keyProc, nullptr, 0);
    244 }
    245 
    246 #endif
    View Code

     

    作者:疯狂Delphi
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.

    欢迎关注我,一起进步!扫描下方二维码即可加我

  • 相关阅读:
    http://blog.csdn.net/zhang_xinxiu/article/details/38655311
    三分钟了解Activity工作流
    在eclipse中设计BPMN 2.0工作流定义的根本步骤
    http://blog.csdn.net/bluejoe2000/article/details/39521405#t9
    activity的测试工程activiti-explorer使用
    如何让Activiti-Explorer使用sql server数据库
    Java中对List集合排序的两种方法
    常用 Git 命令清单
    推荐!手把手教你使用Git
    理解RESTful架构
  • 原文地址:https://www.cnblogs.com/FKdelphi/p/15737135.html
Copyright © 2011-2022 走看看