C++ Qt 窗口消息钩子 | 键盘鼠标数据获取 | 代码示例
C++ Qt 窗口消息钩子 | 键盘鼠标数据获取 | 代码示例
本示例演示如何使用 C++ Qt 框架实现窗口消息钩子,并获取键盘和鼠标数据。
头文件 (mainwindow.h)
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QFileDialog>
#include <QFile>
#include <QMessageBox>
#include <QTextCodec>
#include <QFileInfo>
#include 'lanrenapi.h'
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
static WNDPROC lpPrevWndFunc;
//自动判断编码格式
QString GetCorrectUnicode(const QByteArray &ba);
void clicked_bt_load(bool clicked);
void clicked_bt_save(bool clicked);
void clicked_bt_save_as(bool clicked);
void clicked_bt_replace(bool clicked);
static APIENTRY func_Message(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
private:
Ui::MainWindow *ui;
HWND hwnd;
};
#endif // MAINWINDOW_H
源文件 (mainwindow.cpp)
#include "mainwindow.h"
#include "ui_mainwindow.h"
// 定义 lpPrevWndFunc 变量
WNDPROC MainWindow::lpPrevWndFunc = nullptr;
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//设置窗口透明度:
this->setWindowOpacity(0.8);
connect(ui->bt_load,&QPushButton::clicked,this,&clicked_bt_load);
connect(ui->bt_save,&QPushButton::clicked,this,&clicked_bt_save);
connect(ui->bt_save_as,&QPushButton::clicked,this,&clicked_bt_save_as);
connect(ui->bt_replace,&QPushButton::clicked,this,&clicked_bt_replace);
//获取窗口的句柄
HWND hwnd=(HWND)(this->winId());
//hook原始输入数据 键盘
if (lanrenAPI::hookRawInputData(hwnd,HID_USAGE_GENERIC_KEYBOARD)==0){
QMessageBox::information(this,"错误!","创建原始键盘数据设备!");
}
//hook原始输入数据 鼠标
if (lanrenAPI::hookRawInputData(hwnd,HID_USAGE_GENERIC_MOUSE)==0){
QMessageBox::information(this,"错误!","创建原始鼠标数据设备!");
}
//建立消息机制,收到数据会通知
lpPrevWndFunc=(WNDPROC)SetWindowLongPtr(hwnd,GWLP_WNDPROC,(LONG_PTR)&func_Message);
qDebug()<<lpPrevWndFunc;
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::clicked_bt_load(bool clicked){
QString fileName= QFileDialog::getOpenFileName(this,"导入脚本","C:\Users\Administrator",tr("TEXT (*.txt)"));
//读取内容 放到textEdit中
//默认编码格式是 utf-8
QFile file(fileName);
//设置打开方式
file.open(QIODeviceBase::ReadOnly);
while(!file.atEnd()){
QByteArray array= file.readLine();
QTextCodec * codec=QTextCodec::codecForName(GetCorrectUnicode(array).toLatin1());
ui->pte_jb->moveCursor(QTextCursor::End);
ui->pte_jb->insertPlainText(codec->toUnicode(array));
}
//关闭文件
file.close();
ui->cb_history->addItem(fileName);
}
void MainWindow::clicked_bt_save(bool clicked){
QString str=ui->pte_jb->toPlainText();
char* ch;
QByteArray ba = str.toUtf8(); // must
ch=ba.data();
QFile file(ui->cb_history->currentText());
//写文件
file.open(QIODevice::WriteOnly);
file.write(ch);
file.close();
}
void MainWindow::clicked_bt_save_as(bool clicked){
QString fileName= QFileDialog::getSaveFileName(this,"另存脚本","C:\Users\Administrator",tr("TEXT (*.txt)"));
char* ch;
QByteArray ba = fileName.toUtf8(); // must
ch=ba.data();
QFile file(ui->cb_history->currentText());
//写文件
file.open(QIODevice::WriteOnly);
file.write(ch);
file.close();
}
void MainWindow::clicked_bt_replace(bool clicked){
LARGE_INTEGER start;
QueryPerformanceCounter(&start);
lanrenAPI::setWindowsMousePenetrate(hwnd,true);
LARGE_INTEGER end;
QueryPerformanceCounter(&end);
qDebug() << end.QuadPart-start.QuadPart;
}
LRESULT APIENTRY func_Message(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam) // second message parameter
{
if (uMsg==RID_INPUT){
RAWINPUT rawdata;
GetRawInputData((HRAWINPUT)lParam,RID_INPUT,&rawdata,(PUINT)40,16);
switch (rawdata.header.dwType)
{
case RIM_TYPEKEYBOARD:
qDebug() << "键盘数据到达";
case RIM_TYPEMOUSE:
qDebug() << "鼠标数据到达";
}
}
return CallWindowProcA (MainWindow::lpPrevWndFunc, hwnd, uMsg, wParam, lParam);
}
//自动判断编码格式
QString MainWindow::GetCorrectUnicode(const QByteArray &ba)
{
QTextCodec::ConverterState state;
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
QString text = codec->toUnicode( ba.constData(), ba.size(), &state);
if (state.invalidChars > 0)
{
text = QTextCodec::codecForName( "GBK" )->toUnicode(ba);
return QString("GBK");
}
else
{
text = ba;
return QString("UTF-8");
}
}
错误解决
:-1: error: debug/mainwindow.o:mainwindow.cpp:(.rdata$.refptr._ZN10MainWindow13lpPrevWndFuncE[.refptr._ZN10MainWindow13lpPrevWndFuncE]+0x0): undefined reference to `MainWindow::lpPrevWndFunc' 报这个错误咋办
这是链接错误,编译器找不到定义 MainWindow::lpPrevWndFunc 的实现。你需要在 MainWindow 类外部定义和初始化 lpPrevWndFunc 变量,例如:
// 头文件 (mainwindow.h)
WNDPROC MainWindow::lpPrevWndFunc = nullptr;
说明
lanrenAPI类需要替换为您的实际代码,用于实现原始输入数据钩子功能。- 该示例仅演示了基本的窗口消息钩子实现,您可能需要根据您的实际需求进行调整。
- 请确保您已经正确配置了 Qt 开发环境。
- 使用
qDebug()输出调试信息可以帮助您理解代码逻辑。 - 为了更安全地处理 Unicode 字符,建议使用
QString类来存储和操作文本。 - 为了确保代码的跨平台兼容性,建议使用 Qt 提供的 API 来处理文件操作。
总结
本文介绍了使用 C++ Qt 框架实现窗口消息钩子的方法,并提供了获取键盘和鼠标数据的示例代码。通过本文的介绍,您可以更好地理解窗口消息钩子的工作原理,并将其应用于您的 Qt 项目中。
原文地址: https://www.cveoy.top/t/topic/nr8k 著作权归作者所有。请勿转载和采集!