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

 

posted @ 2019-06-20 15:48  狂奔~  阅读(6577)  评论(0编辑  收藏  举报