qt动态库实现无边框窗体的消息处理 nativeEvent的使用
需求:
在动态库中创建一个窗口句柄,可以给外部调用,库的调用者,通过这个句柄发送消息到底层库,库里面可以实现对消息的处理
m_FHandle=AllocateHWnd(WndProcDllMsg); // windows
1,动态库编写部分
.pro 工程文件
#------------------------------------------------- # # Project created by QtCreator 2019-06-19T19:47:22 # #------------------------------------------------- QT += widgets QT -= gui TARGET = HandleMSG TEMPLATE = lib DEFINES += HANDLEMSG_LIBRARY SOURCES += handlemsg.cpp HEADERS += handlemsg.h\ handlemsg_global.h unix { target.path = /usr/lib INSTALLS += target }
头文件handlemag.h
#ifndef HANDLEMSG_H #define HANDLEMSG_H #include "handlemsg_global.h" #include <QWidget> #include "windows.h" class HANDLEMSGSHARED_EXPORT HandleMSG: public QWidget { public: HandleMSG(); int add(int a,int b); bool nativeEvent(const QByteArray &eventType, void *message, long *result); HWND getHWDN(); private: int m_ia; }; extern "C" Q_DECL_EXPORT int sub(int a, int b);//导出函数, 客户端可用 QLibrary 加载 extern "C" Q_DECL_EXPORT HandleMSG* getHandleMSG(); #endif // HANDLEMSG_H
handlemsg_gloab.h
#ifndef HANDLEMSG_GLOBAL_H #define HANDLEMSG_GLOBAL_H #include <QtCore/qglobal.h> #if defined(HANDLEMSG_LIBRARY) # define HANDLEMSGSHARED_EXPORT Q_DECL_EXPORT #else # define HANDLEMSGSHARED_EXPORT Q_DECL_IMPORT #endif #endif // HANDLEMSG_GLOBAL_H
handlemsg.cpp
#include "handlemsg.h" HandleMSG::HandleMSG() { m_ia = 0; } int HandleMSG::add(int a, int b) { return a + b + m_ia; } int sub(int a, int b) { return a-b; } HandleMSG *getHandleMSG() { return new HandleMSG(); } // 响应windows 消息,实现无边框窗体的消息处理 // 可参考https://jingyan.baidu.com/article/54b6b9c0e8a41f2d583b47eb.html bool HandleMSG::nativeEvent(const QByteArray &eventType, void *message, long *result) { if (eventType == "windows_generic_MSG") { // PostMessage((HWND)this->winId(), WM_USER + 777, 10, 20); 发送消息 PMSG msg = (PMSG)message; if (msg->message == WM_USER + 777) { // BYTE nFunCode = LOBYTE(LOWORD(msg->wParam)); // BYTE nExecuteState = HIBYTE(LOWORD(msg->wParam)); m_ia++; } } return false; } HWND HandleMSG::getHWDN() { HWND handle = (HWND)this->winId(); return handle; }
Used to define private messages for use by private window classes, usually of the form WM_USER+x, where x is an integer value.
#define WM_USER 0x0400
2,动态库的使用
.pro文件
#------------------------------------------------- # # Project created by QtCreator 2019-06-20T11:03:30 # #------------------------------------------------- QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = LoadDll TEMPLATE = app SOURCES += main.cpp\ mainwindow.cpp HEADERS += mainwindow.h \ handlemsg.h \ handlemsg_global.h FORMS += mainwindow.ui LIBS += -L$$PWD HandleMSG.dll
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include "handlemsg.h" #include <QDebug> #include <QPushButton> #include <QLibrary> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); typedef int (*Sub)(int a, int b); typedef HandleMSG* (*GetHandleMSG)();//定义函数指针,获取类TestDLL对象; QLibrary mylib("HandleMSG.dll"); if(!mylib.load()){// 加载 dll 失败 qDebug() <<"加载 HandleMSG.dll 失败!"<<endl; } Sub sub = (Sub)mylib.resolve("sub"); if(0 == sub){// 加载失败 qDebug() <<"加载函数 add 失败!"<<endl; } int ss = sub(2,3); GetHandleMSG getHandleMSG = (GetHandleMSG)mylib.resolve("getHandleMSG"); if(0 == getHandleMSG){// 加载失败 qDebug()<<"加载函数 getHandleMSG 失败!"<<endl; } HandleMSG *pLib = getHandleMSG(); int sum = pLib->add(2,3); qDebug() << "from dll: " << sum << ss <<endl; connect(ui->pushButton,&QPushButton::clicked,this,[=]{ PostMessage(pLib->getHWDN(), WM_USER + 777, 10, 20); //发送消息 SendMessage // WINUSERAPI WINBOOL WINAPI PostMessageW (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); }); connect(ui->pushButton,&QPushButton::clicked,ui->label,[=]{ ui->label->setText(QString::number(pLib->add(2,3))); }); } MainWindow::~MainWindow() { delete ui; }
关于qt动态库和静态库的参考文章https://www.cnblogs.com/woxinfeixiang2015/p/8334112.html
http://blog.sina.com.cn/s/blog_a6fb6cc90102vsdn.html
nativeEventFilter详解https://blog.csdn.net/luoshabugui/article/details/82428500