文章的目的为了记录使用C++ 进行QT Widget 开发学习的经历。临时学习,完成app的开发。开发流程和要点有些记忆模糊,赶紧记录,防止忘记。
相关链接:
开源 C++ QT Widget 开发(一)工程文件结构-CSDN博客
开源 C++ QT Widget 开发(二)基本控件应用-CSDN博客
开源 C++ QT Widget 开发(三)图表--波形显示器-CSDN博客
开源 C++ QT Widget 开发(四)文件--二进制文件查看编辑-CSDN博客
开源 C++ QT Widget 开发(五)通讯--串口调试-CSDN博客
开源 C++ QT Widget 开发(六)通讯--TCP调试-CSDN博客
开源 C++ QT Widget 开发(七)线程--多线程及通讯-CSDN博客
开源 C++ QT Widget 开发(八)网络--Http文件下载-CSDN博客
开源 C++ QT Widget 开发(九)图表--仪表盘-CSDN博客
开源 C++ QT Widget 开发(十)IPC进程间通信--共享内存-CSDN博客
开源 C++ QT Widget 开发(十一)进程间通信--Windows 窗口通信-CSDN博客
开源 C++ QT Widget 开发(十二)图表--环境监测表盘-CSDN博客
推荐链接:
开源 java android app 开发(一)开发环境的搭建-CSDN博客
开源 java android app 开发(二)工程文件结构-CSDN博客
开源 java android app 开发(三)GUI界面布局和常用组件-CSDN博客
开源 java android app 开发(四)GUI界面重要组件-CSDN博客
开源 java android app 开发(五)文件和数据库存储-CSDN博客
开源 java android app 开发(六)多媒体使用-CSDN博客
开源 java android app 开发(七)通讯之Tcp和Http-CSDN博客
开源 java android app 开发(八)通讯之Mqtt和Ble-CSDN博客
开源 java android app 开发(九)后台之线程和服务-CSDN博客
开源 java android app 开发(十)广播机制-CSDN博客
开源 java android app 开发(十一)调试、发布-CSDN博客
开源 java android app 开发(十二)封库.aar-CSDN博客
推荐链接:
开源C# .net mvc 开发(一)WEB搭建_c#部署web程序-CSDN博客
开源 C# .net mvc 开发(二)网站快速搭建_c#网站开发-CSDN博客
开源 C# .net mvc 开发(三)WEB内外网访问(VS发布、IIS配置网站、花生壳外网穿刺访问)_c# mvc 域名下不可訪問內網,內網下可以訪問域名-CSDN博客
开源 C# .net mvc 开发(四)工程结构、页面提交以及显示_c#工程结构-CSDN博客
开源 C# .net mvc 开发(五)常用代码快速开发_c# mvc开发-CSDN博客
本章主要内容:跨进程 Windows 窗口通信的功能,使用的是 WM_COPYDATA
消息。
目录:
1.功能描述
2.代码分析
3.所有源码
4.效果演示
一、功能描述
总体功能概述
这是一个典型的生产者-消费者模型:
程序1(发送端):包含一个按钮,点击时寻找特定窗口并发送消息
程序2(接收端):监听并处理收到的消息,显示内容
它们使用 Windows 的 WM_COPYDATA 消息机制进行进程间通信。
二、代码分析
1.发送端
FindWindow(NULL, L"acceptWnd"):通过窗口标题查找名为 "acceptWnd" 的窗口
返回窗口句柄 HWND,如果找不到返回 NULL
数据准备:
QByteArray ary = "test message!":创建要发送的数据
自动包含结尾的 null 字符
消息结构:
COPYDATASTRUCT 是 Windows 用于进程间数据传输的标准结构
dwData:用户自定义标识(这里使用 WM_APP)
lpData:指向数据的指针
cbData:数据长度(字节数)
消息发送:
SendMessage():同步发送消息,会阻塞直到接收方处理完成
WM_COPYDATA:特殊的 Windows 消息,用于进程间数据传输
Windows 会自动处理内存映射,确保接收进程能访问数据
2.接收端
消息转换:
nativeEvent 是 Qt 处理原生平台消息的入口
将通用的 void* message 转换为 Windows 的 MSG 结构
平台检查:
确认是 Windows 平台的原生消息
消息类型判断:
检查是否是 WM_COPYDATA 消息
数据提取:
msg->lParam 包含指向 COPYDATASTRUCT 的指针
使用 reinterpret_cast 进行类型转换
数据处理:
将接收到的数据转换为 QByteArray
使用消息框显示接收到的内容
三、所有源码
1.发送端mainwindow.h文件
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <qt_windows.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
2.发送端mianwindow.cpp文件
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
HWND accWnd =FindWindow(NULL,L"acceptWnd");
if(accWnd)
{
QByteArray ary = "test message!";
COPYDATASTRUCT copydata;
copydata.dwData = WM_APP;
copydata.lpData = ary.data();
copydata.cbData =ary.length();
SendMessage(accWnd,WM_COPYDATA,NULL,reinterpret_cast<LPARAM>(©data));
}
}
3.接收端mainwindow.h文件
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <qt_windows.h>
#include <QMessageBox>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
protected:
bool nativeEvent(const QByteArray &eventType, void *message, long *result);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
4.接收端mainwindow.cpp文件
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
MSG *msg = static_cast<MSG*>(message); //类型转换
if (eventType == "windows_generic_MSG") //windows平台
{
MSG* msg = reinterpret_cast<MSG*>(message); //
if(msg->message == WM_COPYDATA)//来自A进程的消息
{
COPYDATASTRUCT *mydata =reinterpret_cast<COPYDATASTRUCT*>(msg->lParam);
if(mydata)
{
QByteArray tsr = QByteArray(reinterpret_cast<char*>(mydata->lpData));
QMessageBox::information(NULL,"recvmag",QString("string:%1").arg(tsr.data()));
}
}
}
return QWidget::nativeEvent(eventType, message, result);//交给Qt处理
}
四、效果演示
将message_send 和message_recv都运行,按下发送按键,接收窗口收到消息。