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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM