Qt-Qt使用鼠标钩子Hook(支持判断按下、弹起、滚轮方向)

相关资源:

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

 

.pro

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    Hook.cpp \
    main.cpp \
    mainwindow.cpp

HEADERS += \
    Hook.h \
    mainwindow.h

FORMS += \
    mainwindow.ui

LIBS += -luser32

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
View Code

main.cpp

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}
View Code

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <windows.h>
#include <winuser.h>


#include <QMainWindow>
#include <QKeyEvent>
#include <QDebug>
#include <QDateTime>
#include "Hook.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private slots:
    void on_pushButton_clicked();
    void UpdateCapslockTip(int keyCode, int x, int y, bool downOrUp);
private:
    Ui::MainWindow *ui;
    Hook *m_pHook;
};
#endif // MAINWINDOW_H
View Code

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setWindowTitle(QStringLiteral("Qt使用鼠标钩子Hook(支持判断按下、弹起、滚轮方向)"));

    #ifdef Q_OS_WIN
    m_pHook = new Hook();
    m_pHook->installHook();
    m_pHook->SetKeyboardCall(
                std::bind(&MainWindow::UpdateCapslockTip,
                          this,
                          std::placeholders::_1,
                          std::placeholders::_2,
                          std::placeholders::_3,
                          std::placeholders::_4));
    #endif
}

MainWindow::~MainWindow()
{
    m_pHook->unInstallHook();
    delete m_pHook;
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    ui->textEdit->clear();
}

void MainWindow::UpdateCapslockTip(int keyCode, int x, int y, bool downOrUp)
{
    QString s = "key pressed:--------:%1  x:%2  y:%3  downOrUp:%4";
    s = s.arg(keyCode).arg(x).arg(y).arg(downOrUp);
    ui->textEdit->append(s);
}
View Code

 hook.h

#ifndef HOOK_H
#define HOOK_H

#include<QObject>
#include<QDebug>
#ifdef Q_OS_WIN  // 代表只有WIN系统才会启用
#include"Windows.h"
#include <functional>// 回调函数引入
#include <QDateTime>// 时间函数引入

class Hook
{
public:
    Hook();
    void installHook();
    void unInstallHook();
    static LRESULT CALLBACK mouseProc(int nCode,WPARAM wParam,LPARAM lParam);
    void SetKeyboardCall(const std::function<void (int, int, int, bool)> & func){ m_func = func; }
private:
    static std::function<void(int, int, int, bool)> m_func;
};
#endif

#endif // HOOK_H
View Code

 hook.cpp

#include "Hook.h"

#ifdef Q_OS_WIN
Hook::Hook()
{

}

static HHOOK mouseHook = nullptr;
std::function<void(int, int, int, bool)> Hook::m_func = nullptr;

//钩子处理函数,
LRESULT CALLBACK Hook::mouseProc(int nCode,WPARAM wParam,LPARAM lParam) //钩子消息函数,系统消息队列信息会返回到该函数中
{
//    MOUSEHOOKSTRUCT *mhookstruct = (MOUSEHOOKSTRUCT*)lParam; //鼠标HOOK结构体
    MSLLHOOKSTRUCT *mhookstruct = (MSLLHOOKSTRUCT*)lParam; //鼠标HOOK结构体
    POINT pt = mhookstruct->pt;         //将当前鼠标坐标点的x,y坐标作为参数向主程序窗口发送消息
    // 中间滚轮上下滚动
    if (WM_MOUSEWHEEL == wParam)
    {
        m_func(4, mhookstruct->mouseData, 0, false);
    }
    // 中间滚轮按下
    if (WM_MBUTTONDOWN == wParam)
    {
        m_func(3, pt.x, pt.y, true);
    }
    if (WM_MBUTTONUP == wParam)
    {
        m_func(3, pt.x, pt.y, false);
    }
    // 鼠标移动
    if (WM_MOUSEMOVE == wParam)
    {
//        m_func(0, pt.x, pt.y, false);
    }
    // 鼠标按下左键
    if (WM_LBUTTONDOWN == wParam)
    {
        m_func(1, pt.x, pt.y, true);
    }
    if (WM_LBUTTONUP == wParam)
    {
        m_func(1, pt.x, pt.y, false);
    }
    // 鼠标按下右键
    if (WM_RBUTTONDOWN == wParam)
    {
        m_func(2, pt.x, pt.y, true);
    }
    if (WM_RBUTTONUP == wParam)
    {
        m_func(2, pt.x, pt.y, false);
    }

    return CallNextHookEx(mouseHook, nCode, wParam, lParam);     //继续原有的事件队列
}

void Hook::unInstallHook()
{
    if(mouseHook != nullptr)// 原作者说是担心一次释放不稳定,才释放二次的。
    {
        UnhookWindowsHookEx(mouseHook);//键盘钩子句不为空时销毁掉
        mouseHook = nullptr;
    }
   if(mouseHook != nullptr)
    {
        UnhookWindowsHookEx(mouseHook);//键盘钩子句不为空时销毁掉
        mouseHook = nullptr;
    }
}

void Hook::installHook()
{
    mouseHook = SetWindowsHookEx(WH_MOUSE_LL, mouseProc, nullptr, 0);
}

#endif
View Code

 mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>462</width>
    <height>407</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QWidget" name="widget" native="true">
    <property name="geometry">
     <rect>
      <x>0</x>
      <y>0</y>
      <width>471</width>
      <height>401</height>
     </rect>
    </property>
    <widget class="QLabel" name="label">
     <property name="geometry">
      <rect>
       <x>10</x>
       <y>20</y>
       <width>54</width>
       <height>12</height>
      </rect>
     </property>
     <property name="text">
      <string>按键:</string>
     </property>
    </widget>
    <widget class="QLabel" name="label_2">
     <property name="geometry">
      <rect>
       <x>10</x>
       <y>40</y>
       <width>71</width>
       <height>16</height>
      </rect>
     </property>
     <property name="text">
      <string>输入Key值:</string>
     </property>
    </widget>
    <widget class="QTextEdit" name="textEdit">
     <property name="geometry">
      <rect>
       <x>10</x>
       <y>60</y>
       <width>441</width>
       <height>271</height>
      </rect>
     </property>
     <property name="focusPolicy">
      <enum>Qt::ClickFocus</enum>
     </property>
    </widget>
    <widget class="QPushButton" name="pushButton">
     <property name="geometry">
      <rect>
       <x>20</x>
       <y>340</y>
       <width>80</width>
       <height>20</height>
      </rect>
     </property>
     <property name="focusPolicy">
      <enum>Qt::ClickFocus</enum>
     </property>
     <property name="text">
      <string>清除</string>
     </property>
    </widget>
    <widget class="QPushButton" name="pushButton_2">
     <property name="geometry">
      <rect>
       <x>110</x>
       <y>340</y>
       <width>80</width>
       <height>20</height>
      </rect>
     </property>
     <property name="focusPolicy">
      <enum>Qt::ClickFocus</enum>
     </property>
     <property name="text">
      <string>PushButton</string>
     </property>
    </widget>
    <widget class="QPushButton" name="pushButton_3">
     <property name="geometry">
      <rect>
       <x>200</x>
       <y>340</y>
       <width>80</width>
       <height>20</height>
      </rect>
     </property>
     <property name="focusPolicy">
      <enum>Qt::ClickFocus</enum>
     </property>
     <property name="text">
      <string>PushButton</string>
     </property>
    </widget>
    <widget class="QPushButton" name="pushButton_4">
     <property name="geometry">
      <rect>
       <x>300</x>
       <y>340</y>
       <width>80</width>
       <height>20</height>
      </rect>
     </property>
     <property name="focusPolicy">
      <enum>Qt::ClickFocus</enum>
     </property>
     <property name="text">
      <string>PushButton</string>
     </property>
    </widget>
    <widget class="QLineEdit" name="lineEdit">
     <property name="geometry">
      <rect>
       <x>60</x>
       <y>10</y>
       <width>113</width>
       <height>20</height>
      </rect>
     </property>
    </widget>
    <widget class="QLineEdit" name="lineEdit_2">
     <property name="geometry">
      <rect>
       <x>190</x>
       <y>10</y>
       <width>113</width>
       <height>20</height>
      </rect>
     </property>
    </widget>
    <widget class="QLineEdit" name="lineEdit_3">
     <property name="geometry">
      <rect>
       <x>320</x>
       <y>10</y>
       <width>113</width>
       <height>20</height>
      </rect>
     </property>
    </widget>
    <widget class="QSlider" name="horizontalSlider">
     <property name="geometry">
      <rect>
       <x>20</x>
       <y>380</y>
       <width>160</width>
       <height>16</height>
      </rect>
     </property>
     <property name="orientation">
      <enum>Qt::Horizontal</enum>
     </property>
    </widget>
    <widget class="QRadioButton" name="radioButton">
     <property name="geometry">
      <rect>
       <x>210</x>
       <y>370</y>
       <width>91</width>
       <height>18</height>
      </rect>
     </property>
     <property name="text">
      <string>RadioButton</string>
     </property>
    </widget>
    <widget class="QCheckBox" name="checkBox">
     <property name="geometry">
      <rect>
       <x>320</x>
       <y>370</y>
       <width>73</width>
       <height>18</height>
      </rect>
     </property>
     <property name="text">
      <string>CheckBox</string>
     </property>
    </widget>
   </widget>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>
View Code

  

 

posted on 2022-05-17 11:47  疯狂delphi  阅读(354)  评论(0编辑  收藏  举报

导航