qt动态库实现无边框窗体的消息处理 nativeEvent的使用
需求:
在动态库中创建一个窗口句柄,可以给外部调用,库的调用者,通过这个句柄发送消息到底层库,库里面可以实现对消息的处理
m_FHandle=AllocateHWnd(WndProcDllMsg); // windows
1,动态库编写部分
.pro 工程文件
#-------------------------------------------------
#
# Project created by QtCreator --19T19::
#
#------------------------------------------------- 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 = ;
} 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 + )
{
// 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 --20T11::
#
#------------------------------------------------- QT += core gui greaterThan(QT_MAJOR_VERSION, ): 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 = );
~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( == sub){// 加载失败
qDebug() <<"加载函数 add 失败!"<<endl;
}
int ss = sub(,); GetHandleMSG getHandleMSG = (GetHandleMSG)mylib.resolve("getHandleMSG");
if( == getHandleMSG){// 加载失败
qDebug()<<"加载函数 getHandleMSG 失败!"<<endl;
}
HandleMSG *pLib = getHandleMSG();
int sum = pLib->add(,); qDebug() << "from dll: " << sum << ss <<endl; connect(ui->pushButton,&QPushButton::clicked,this,[=]{
PostMessage(pLib->getHWDN(), WM_USER + , , ); //发送消息 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(,)));
}); } 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
qt动态库实现无边框窗体的消息处理 nativeEvent的使用的更多相关文章
- Qt无边框窗体-最大化时支持拖拽还原
目录 一.概述 二.效果展示 三.demo制作 1.设计窗体 2.双击放大 四.拖拽 五.相关文章 原文链接:Markdown模板 一.概述 用Qt进行开发界面时,既想要实现友好的用户交互又想界面漂亮 ...
- Qt无边框窗体-模拟模态窗体抖动效果
目录 一.概述 二.效果展示 三.功能实现 四.相关文章 原文链接:Qt无边框窗体-模拟模态窗体抖动效果 一.概述 用Qt开发windows客户端界面确实是一大利器,兼顾性能的同时,速度相对来说也不错 ...
- Qt 无边框窗体改变大小 完美实现(全部自己实现)
近期,做项目用到无边框窗体,令人蛋疼的是无边框窗体大小的改变要像右边框那样,上下左右四周,而且要流畅. 网上也找了些代码,发现居然还要连接到windows事件,这显然不合常理,后来自己新建了demo, ...
- Qt 无边框窗体改变大小 完美实现
近期,做项目用到无边框窗体,令人蛋疼的是无边框窗体大小的改变要像右边框那样,上下左右四周,而且要流畅. 网上也找了些代码,发现居然还要连接到windows事件,这显然不合常理,后来自己新建了demo, ...
- Qt:移动无边框窗体(使用Windows的SendMessage)
移动无边框窗体的代码网上很多,其原理都是一样的,但是是有问题的,我这里只是对其修正一下 网上的代码仅仅实现了两个事件 void EditDialog::mousePressEvent(QMouseEv ...
- 移动无边框窗体(设置标志位更流畅,或者发送WM_SYSCOMMAND和SC_MOVE + HTCAPTION消息)
移动无边框窗体的代码网上很多,其原理都是一样的,但是是有问题的,我这里只是对其修正一下 网上的代码仅仅实现了两个事件 void EditDialog::mousePressEvent(QMouseEv ...
- C#WinForm无边框窗体移动方法、模仿鼠标单击标题栏移动窗体位置
C#WinForm无边框窗体移动方法.模仿鼠标单击标题栏移动窗体位置 这里介绍俩种办法 方法一:直接通过修改窗体位置从而达到移动窗体的效果 方法二:直接伪装发送单击任务栏消息,让应用程序误以为单击任务 ...
- C#自定义Winform无边框窗体
C#自定义Winform无边框窗体 在实际项目中,WinForm窗体或者控件不能满足要求,所以就需要自己设计窗体等,当然设计界面可以用的东西很多,例如WPF.或者一些第三方的库等.本例中将采用WinF ...
- WinForm无边框窗体移动方法
C#WinForm无边框窗体移动方法.模仿鼠标单击标题栏移动窗体位置 这里介绍俩种办法 方法一:直接通过修改窗体位置从而达到移动窗体的效果 方法二:直接伪装发送单击任务栏消息,让应用程序误以为单击任务 ...
随机推荐
- WUSTOJ 1341: Lake and Island(Java)
题目链接:1341: Lake and Island Description 北园孩子的专属福利来啦~学校从北区宿舍到湖心岛修建了一条通道让北园的同学们可以上去一(kuang)同(xiu)玩(en)耍 ...
- 题解-CSA Round#18 Randomly Permuted Costs
Problem CSA Round 18 题意概要:给定一个有重边有自环 \(n\) 点 \(m\) 边的有向无环图(DAG),每条边有其权值,每当你走到一个点 \(x\) 时,所有从 \(x\) 连 ...
- Yii2 redis 使用
首先要安装一下redis的扩展 composer require yiisoft/yii2-redis 在配置文件中添加redis配置 'components' => [ .... 'redis ...
- springboot 使用consul 读取配置文件(遇到的坑太多,没记录)
最终成功版. pom引入mavn依赖: <!--consul--> <dependency> <groupId>org.springframework.cloud& ...
- kafka的生产者配置以及发送信息的三种方式
1.Fire-and-forget 这种方式是不管发送成功与否,客户端都会返回成功.尽管大多数的时候Kafka 在发送失败后,会自己重新自动再一次发送消息,但是也会存在丢失消息的风险 Producer ...
- C# ObservableCollection两个字段排序的情况
相对于System.Linq的OrderBy及OrderByDescending方法,调用后产生IOrderedEnumberable对象,这个对象为排序后的返回值,但原对象未发生变化. 试想,有这种 ...
- shell 脚本总结
一.SHELL脚本是什么?它是必需的吗? 一个SHELL脚本就是一个文本文件,它包含一个或多个命令.系统管理员会经常需要使用多个命令来完成一项任务,此时可以添加这些所有命令在一个文本文件(SHELL脚 ...
- BKP和RTC
Stm32内部有多个BKP寄存器,在主电源被切断或者系统产生复位的时候,BKP寄存器仍然可以利用备用电源的支持保持其重要内容. BKP在实际应用中可以存入重要数据,防止被恶意查看. BKP有入侵检测, ...
- Dockerfile的编写(主观汇聚篇)
目录 一.什么是dockerfile 二.Dockerfile的基本结构 Dockerfile文件说明 三.总结 一.什么是dockerfile dockerfile是使用者用来自定义构建一个dock ...
- java - day018 - 线程续
生产者,消费者 线程间的通信模型 等待和通知 在生产者和消费者模型中 消费者暂停等待数据 生产者产生数据后发出通知 object 方法 wait(); notify(); 通知一个 notifyAll ...