Qt使用钩子后台监控键盘并在界面中响应

当我们的Qt程序需要在后台监听键盘的操作或者屏蔽键盘的操作时,就需要用到系统的API,因此用到Windows钩子,下面简单介绍下使用钩子监控键盘按键,原理较简单,代码上我都注释了,比较容易看懂,一些参数不懂的可以参考官方文档:

官方SetWindowsHookExW API文档:https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexw

官方键盘事件KeyboardProc API文档:https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms644984(v=vs.85)

1、创建钩子处理类Hook:

Hook.h:

#ifndef HOOK_H
#define HOOK_H
#include <windows.h>
#include <QObject>
class Hook:public QObject
{
    Q_OBJECT
public:
    Hook();
    enum Type{CHANGE,CHANGEBACK};//自定义枚举,定义“修改”、“撤回”两种状态
    void installHook(Hook*);//安装钩子函数,指针参数为了发送信号用
    void unInstallHook();//删除钩子
    void sendSignal(Type type);
    Q_ENUM(Type)//注册枚举类型进元对象系统,否则无法将枚举类型作为信号参数传递
signals:
    void sendKeyType(Type);//发送按键监控信号
};

#endif // HOOK_H

Hook.cpp:

#include "hook.h"
#include <QDebug>

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用于判断事件类型,当前为按键按下事件
        if(pkbhs->vkCode == 0x31&&GetAsyncKeyState(VK_CONTROL)){//按下Ctrl+1
            hook->sendSignal(Hook::CHANGE);//安装钩子的对象发出按键监听信号
        }
        if(pkbhs->vkCode == 0x32&&GetAsyncKeyState(VK_CONTROL)){//按下Ctrl+2
            hook->sendSignal(Hook::CHANGEBACK);
        }
    }
    return CallNextHookEx(keyHook,nCode,wParam,lParam);//继续原有的事件队列
}

Hook::Hook()
{

}

void Hook::installHook(Hook* h){//安装钩子函数
    keyHook = SetWindowsHookEx(WH_KEYBOARD_LL,keyProc,nullptr,0);
    hook = h;
}
void Hook::unInstallHook(){//删除钩子函数
    UnhookWindowsHookEx(keyHook);
    keyHook = nullptr;
}

void Hook::sendSignal(Type type){//发送信号函数
    emit sendKeyType(type);
}

2、Qt界面中调用Hook,安装钩子函数,并对接收的信号进行处理:

widget.h:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QObject>
#include "hook.h"
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;
    Hook hook;//钩子对象
private slots:
    void checkType(Hook::Type);
};

#endif // WIDGET_H

widget.cpp:

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QMetaType>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    hook.installHook(&hook);
    qRegisterMetaType<Hook::Type>("Type");//为了信号中能传递自定义枚举类型,如果传递常规参数,可省略该行
    connect(&hook,SIGNAL(sendKeyType(Type)),this,SLOT(checkType(Type)));
}

Widget::~Widget()
{
    delete ui;
    hook.unInstallHook();
}

void Widget::checkType(Hook::Type type){
    switch (type) {
    case Hook::CHANGE:
        ui->plainTextEdit->appendPlainText("按下按钮 Ctrl+1 \n");
        break;
    case Hook::CHANGEBACK:
        ui->plainTextEdit->appendPlainText("按下按钮 Ctrl+2 \n");
        break;
    default:
        break;
    }

}

界面效果(widget无论有没有焦点均能响应):

附文(VK_Code):

Constant/valueDescription

VK_LBUTTON

0x01

Left mouse button

VK_RBUTTON

0x02

Right mouse button

VK_CANCEL

0x03

Control-break processing

VK_MBUTTON

0x04

Middle mouse button (three-button mouse)

VK_XBUTTON1

0x05

X1 mouse button

VK_XBUTTON2

0x06

X2 mouse button

-

0x07

Undefined

VK_BACK

0x08

BACKSPACE key

VK_TAB

0x09

TAB key

-

0x0A-0B

Reserved

VK_CLEAR

0x0C

CLEAR key

VK_RETURN

0x0D

ENTER key

-

0x0E-0F

Undefined

VK_SHIFT

0x10

SHIFT key

VK_CONTROL

0x11

CTRL key

VK_MENU

0x12

ALT key

VK_PAUSE

0x13

PAUSE key

VK_CAPITAL

0x14

CAPS LOCK key

VK_KANA

0x15

IME Kana mode

VK_HANGUEL

0x15

IME Hanguel mode (maintained for compatibility; use VK_HANGUL)

VK_HANGUL

0x15

IME Hangul mode

VK_IME_ON

0x16

IME On

VK_JUNJA

0x17

IME Junja mode

VK_FINAL

0x18

IME final mode

VK_HANJA

0x19

IME Hanja mode

VK_KANJI

0x19

IME Kanji mode

VK_IME_OFF

0x1A

IME Off

VK_ESCAPE

0x1B

ESC key

VK_CONVERT

0x1C

IME convert

VK_NONCONVERT

0x1D

IME nonconvert

VK_ACCEPT

0x1E

IME accept

VK_MODECHANGE

0x1F

IME mode change request

VK_SPACE

0x20

SPACEBAR

VK_PRIOR

0x21

PAGE UP key

VK_NEXT

0x22

PAGE DOWN key

VK_END

0x23

END key

VK_HOME

0x24

HOME key

VK_LEFT

0x25

LEFT ARROW key

VK_UP

0x26

UP ARROW key

VK_RIGHT

0x27

RIGHT ARROW key

VK_DOWN

0x28

DOWN ARROW key

VK_SELECT

0x29

SELECT key

VK_PRINT

0x2A

PRINT key

VK_EXECUTE

0x2B

EXECUTE key

VK_SNAPSHOT

0x2C

PRINT SCREEN key

VK_INSERT

0x2D

INS key

VK_DELETE

0x2E

DEL key

VK_HELP

0x2F

HELP key

0x30

0 key

0x31

1 key

0x32

2 key

0x33

3 key

0x34

4 key

0x35

5 key

0x36

6 key

0x37

7 key

0x38

8 key

0x39

9 key

-

0x3A-40

Undefined

0x41

A key

0x42

B key

0x43

C key

0x44

D key

0x45

E key

0x46

F key

0x47

G key

0x48

H key

0x49

I key

0x4A

J key

0x4B

K key

0x4C

L key

0x4D

M key

0x4E

N key

0x4F

O key

0x50

P key

0x51

Q key

0x52

R key

0x53

S key

0x54

T key

0x55

U key

0x56

V key

0x57

W key

0x58

X key

0x59

Y key

0x5A

Z key

VK_LWIN

0x5B

Left Windows key (Natural keyboard)

VK_RWIN

0x5C

Right Windows key (Natural keyboard)

VK_APPS

0x5D

Applications key (Natural keyboard)

-

0x5E

Reserved

VK_SLEEP

0x5F

Computer Sleep key

VK_NUMPAD0

0x60

Numeric keypad 0 key

VK_NUMPAD1

0x61

Numeric keypad 1 key

VK_NUMPAD2

0x62

Numeric keypad 2 key

VK_NUMPAD3

0x63

Numeric keypad 3 key

VK_NUMPAD4

0x64

Numeric keypad 4 key

VK_NUMPAD5

0x65

Numeric keypad 5 key

VK_NUMPAD6

0x66

Numeric keypad 6 key

VK_NUMPAD7

0x67

Numeric keypad 7 key

VK_NUMPAD8

0x68

Numeric keypad 8 key

VK_NUMPAD9

0x69

Numeric keypad 9 key

VK_MULTIPLY

0x6A

Multiply key

VK_ADD

0x6B

Add key

VK_SEPARATOR

0x6C

Separator key

VK_SUBTRACT

0x6D

Subtract key

VK_DECIMAL

0x6E

Decimal key

VK_DIVIDE

0x6F

Divide key

VK_F1

0x70

F1 key

VK_F2

0x71

F2 key

VK_F3

0x72

F3 key

VK_F4

0x73

F4 key

VK_F5

0x74

F5 key

VK_F6

0x75

F6 key

VK_F7

0x76

F7 key

VK_F8

0x77

F8 key

VK_F9

0x78

F9 key

VK_F10

0x79

F10 key

VK_F11

0x7A

F11 key

VK_F12

0x7B

F12 key

VK_F13

0x7C

F13 key

VK_F14

0x7D

F14 key

VK_F15

0x7E

F15 key

VK_F16

0x7F

F16 key

VK_F17

0x80

F17 key

VK_F18

0x81

F18 key

VK_F19

0x82

F19 key

VK_F20

0x83

F20 key

VK_F21

0x84

F21 key

VK_F22

0x85

F22 key

VK_F23

0x86

F23 key

VK_F24

0x87

F24 key

-

0x88-8F

Unassigned

VK_NUMLOCK

0x90

NUM LOCK key

VK_SCROLL

0x91

SCROLL LOCK key

0x92-96

OEM specific

-

0x97-9F

Unassigned

VK_LSHIFT

0xA0

Left SHIFT key

VK_RSHIFT

0xA1

Right SHIFT key

VK_LCONTROL

0xA2

Left CONTROL key

VK_RCONTROL

0xA3

Right CONTROL key

VK_LMENU

0xA4

Left MENU key

VK_RMENU

0xA5

Right MENU key

VK_BROWSER_BACK

0xA6

Browser Back key

VK_BROWSER_FORWARD

0xA7

Browser Forward key

VK_BROWSER_REFRESH

0xA8

Browser Refresh key

VK_BROWSER_STOP

0xA9

Browser Stop key

VK_BROWSER_SEARCH

0xAA

Browser Search key

VK_BROWSER_FAVORITES

0xAB

Browser Favorites key

VK_BROWSER_HOME

0xAC

Browser Start and Home key

VK_VOLUME_MUTE

0xAD

Volume Mute key

VK_VOLUME_DOWN

0xAE

Volume Down key

VK_VOLUME_UP

0xAF

Volume Up key

VK_MEDIA_NEXT_TRACK

0xB0

Next Track key

VK_MEDIA_PREV_TRACK

0xB1

Previous Track key

VK_MEDIA_STOP

0xB2

Stop Media key

VK_MEDIA_PLAY_PAUSE

0xB3

Play/Pause Media key

VK_LAUNCH_MAIL

0xB4

Start Mail key

VK_LAUNCH_MEDIA_SELECT

0xB5

Select Media key

VK_LAUNCH_APP1

0xB6

Start Application 1 key

VK_LAUNCH_APP2

0xB7

Start Application 2 key

-

0xB8-B9

Reserved

VK_OEM_1

0xBA

Used for miscellaneous characters; it can vary by keyboard.
For the US standard keyboard, the ';:' key

VK_OEM_PLUS

0xBB

For any country/region, the '+' key

VK_OEM_COMMA

0xBC

For any country/region, the ',' key

VK_OEM_MINUS

0xBD

For any country/region, the '-' key

VK_OEM_PERIOD

0xBE

For any country/region, the '.' key

VK_OEM_2

0xBF

Used for miscellaneous characters; it can vary by keyboard.
For the US standard keyboard, the '/?' key

VK_OEM_3

0xC0

Used for miscellaneous characters; it can vary by keyboard.
For the US standard keyboard, the '`~' key

-

0xC1-D7

Reserved

-

0xD8-DA

Unassigned

VK_OEM_4

0xDB

Used for miscellaneous characters; it can vary by keyboard.
For the US standard keyboard, the '[{' key

VK_OEM_5

0xDC

Used for miscellaneous characters; it can vary by keyboard.
For the US standard keyboard, the '\|' key

VK_OEM_6

0xDD

Used for miscellaneous characters; it can vary by keyboard.
For the US standard keyboard, the ']}' key

VK_OEM_7

0xDE

Used for miscellaneous characters; it can vary by keyboard.
For the US standard keyboard, the 'single-quote/double-quote' key

VK_OEM_8

0xDF

Used for miscellaneous characters; it can vary by keyboard.

-

0xE0

Reserved

0xE1

OEM specific

VK_OEM_102

0xE2

Either the angle bracket key or the backslash key on the RT 102-key keyboard

0xE3-E4

OEM specific

VK_PROCESSKEY

0xE5

IME PROCESS key

0xE6

OEM specific

VK_PACKET

0xE7

Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUTSendInputWM_KEYDOWN, and WM_KEYUP

-

0xE8

Unassigned

0xE9-F5

OEM specific

VK_ATTN

0xF6

Attn key

VK_CRSEL

0xF7

CrSel key

VK_EXSEL

0xF8

ExSel key

VK_EREOF

0xF9

Erase EOF key

VK_PLAY

0xFA

Play key

VK_ZOOM

0xFB

Zoom key

VK_NONAME

0xFC

Reserved

VK_PA1

0xFD

PA1 key

VK_OEM_CLEAR

0xFE

Clear key
  • 9
    点赞
  • 31
    收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:技术黑板 设计师:CSDN官方博客 返回首页
评论 4

打赏作者

喵喵叫的猴

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值