C++ Qt 应用程序 - 使用原始输入数据 (Raw Input) 实现键盘鼠标监听
cpp/n#ifndef MAINWINDOW_H/n#define MAINWINDOW_H/n#include <QMainWindow>/n#include <QFileDialog>/n#include <QFile>/n#include <QMessageBox>/n#include <QTextCodec>/n#include <QFileInfo>/n#include 'lanrenapi.h'/n/nQT_BEGIN_NAMESPACE/nnamespace Ui { class MainWindow; }/nQT_END_NAMESPACE/n/nclass MainWindow : public QMainWindow/n{/n Q_OBJECT/n/npublic:/n MainWindow(QWidget *parent = nullptr);/n ~MainWindow();/n/n LONG lpPrevWndFunc;/n //自动判断编码格式/n QString GetCorrectUnicode(const QByteArray &ba);/n void clicked_bt_load(bool clicked);/n void clicked_bt_save(bool clicked);/n void clicked_bt_save_as(bool clicked);/n void clicked_bt_replace(bool clicked);/n static LRESULT CALLBACK func_Message(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);/nprivate:/n Ui::MainWindow *ui;/n HWND hwnd;/n};/n#endif // MAINWINDOW_H/n/n/n/n/nCPP文件/n#include /'mainwindow.h/'/n#include /'ui_mainwindow.h/'/n/nMainWindow::MainWindow(QWidget *parent)/n : QMainWindow(parent)/n , ui(new Ui::MainWindow)/n{/n/n ui->setupUi(this);/n //设置窗口透明度:/n this->setWindowOpacity(0.8);/n connect(ui->bt_load,&QPushButton::clicked,this,&clicked_bt_load);/n connect(ui->bt_save,&QPushButton::clicked,this,&clicked_bt_save);/n connect(ui->bt_save_as,&QPushButton::clicked,this,&clicked_bt_save_as);/n connect(ui->bt_replace,&QPushButton::clicked,this,&clicked_bt_replace);/n //获取窗口的句柄/n HWND hwnd=(HWND)(this->winId());/n //hook原始输入数据 键盘/n if (lanrenAPI::hookRawInputData(hwnd,HID_USAGE_GENERIC_KEYBOARD)==0){/n/n QMessageBox::information(this,/'错误!/',/'创建原始键盘数据设备!/');/n }/n //hook原始输入数据 鼠标/n if (lanrenAPI::hookRawInputData(hwnd,HID_USAGE_GENERIC_MOUSE)==0){/n QMessageBox::information(this,/'错误!/',/'创建原始鼠标数据设备!/');/n }/n LONG lpPrevWndFunc;/n LONG MainWindow::lpPrevWndFunc = 0;/n //建立消息机制,收到数据会通知/n lpPrevWndFunc=SetWindowLongPtr(hwnd,GWLP_WNDPROC,(LONG_PTR)&func_Message);/n/n}/nMainWindow::~MainWindow()/n{/n delete ui;/n}/n/nvoid MainWindow::clicked_bt_load(bool clicked){/n/n QString fileName= QFileDialog::getOpenFileName(this,/'导入脚本/',/'C://Users//Administrator/',tr(/'TEXT (*.txt)/'));/n/n/n //读取内容 放到textEdit中/n //默认编码格式是 utf-8/n QFile file(fileName);/n //设置打开方式/n file.open(QIODeviceBase::ReadOnly);/n/n while(!file.atEnd()){/n QByteArray array= file.readLine();/n QTextCodec * codec=QTextCodec::codecForName(GetCorrectUnicode(array).toLatin1());/n/n ui->pte_jb->moveCursor(QTextCursor::End);/n ui->pte_jb->insertPlainText(codec->toUnicode(array));/n }/n //关闭文件/n file.close();/n/n ui->cb_history->addItem(fileName);/n}/nvoid MainWindow::clicked_bt_save(bool clicked){/n/n QString str=ui->pte_jb->toPlainText();/n char* ch;/n QByteArray ba = str.toUtf8(); // must/n ch=ba.data();/n/n QFile file(ui->cb_history->currentText());/n //写文件/n file.open(QIODevice::WriteOnly);/n file.write(ch);/n file.close();/n/n}/nvoid MainWindow::clicked_bt_save_as(bool clicked){/n QString fileName= QFileDialog::getSaveFileName(this,/'另存脚本/',/'C://Users//Administrator/',tr(/'TEXT (*.txt)/'));/n char* ch;/n QByteArray ba = fileName.toUtf8(); // must/n ch=ba.data();/n/n QFile file(ui->cb_history->currentText());/n //写文件/n file.open(QIODevice::WriteOnly);/n file.write(ch);/n file.close();/n/n}/n/nvoid MainWindow::clicked_bt_replace(bool clicked){/n LARGE_INTEGER start;/n QueryPerformanceCounter(&start);/n/n lanrenAPI::setWindowsMousePenetrate(hwnd,true);/n LARGE_INTEGER end;/n QueryPerformanceCounter(&end);/n qDebug() << end.QuadPart-start.QuadPart;/n}/nLRESULT APIENTRY func_Message(/n HWND hwnd, // handle to window/n UINT uMsg, // message identifier/n WPARAM wParam, // first message parameter/n LPARAM lParam) // second message parameter/n{/n if (uMsg==RID_INPUT){/n RAWINPUT rawdata;/n GetRawInputData((HRAWINPUT)lParam,RID_INPUT,&rawdata,(PUINT)40,16);/n switch (rawdata.header.dwType)/n {/n case RIM_TYPEKEYBOARD:/n qDebug() << /'键盘数据到达/';/n/n case RIM_TYPEMOUSE:/n qDebug() << /'鼠标数据到达/';/n }/n }/n/n return CallWindowProcA (MainWindow::lpPrevWndFunc, hwnd, uMsg, wParam, lParam);/n}/n//自动判断编码格式/nQString MainWindow::GetCorrectUnicode(const QByteArray &ba)/n{/n QTextCodec::ConverterState state;/n QTextCodec *codec = QTextCodec::codecForName(/'UTF-8/');/n QString text = codec->toUnicode( ba.constData(), ba.size(), &state);/n if (state.invalidChars > 0)/n {/n text = QTextCodec::codecForName( /'GBK/' )->toUnicode(ba);/n return QString(/'GBK/');/n }/n else/n {/n text = ba;/n return QString(/'UTF-8/');/n }/n}/n/n我头文件中确实有在public中声明了 lpPrevWndFunc 为什么还是报错/n/n/nd://QTProjects//JBMN//mainwindow.cpp:116: error: 'lpPrevWndFunc' was not declared in this scope/n../JBMN/mainwindow.cpp: In function 'LRESULT func_Message(HWND, UINT, WPARAM, LPARAM)':/n../JBMN/mainwindow.cpp:116:29: error: 'lpPrevWndFunc' was not declared in this scope/n 116 | return CallWindowProcA (lpPrevWndFunc, hwnd, uMsg, wParam, lParam);/n | ^~~~~~~~~~~~~/n/n内容:在函数内部使用静态变量 lpPrevWndFunc 时需要加上类名 MainWindow::,即将函数 func_Message 内的 return 语句修改为:/n/ncpp/nreturn CallWindowProcA(MainWindow::lpPrevWndFunc, hwnd, uMsg, wParam, lParam);/n```
原文地址: https://www.cveoy.top/t/topic/nr6L 著作权归作者所有。请勿转载和采集!