MFC嵌入Qt窗口详细指导

4 篇文章 0 订阅
1 篇文章 0 订阅
  1. 我已经写好了Qt窗口的查看DXF文件的类。想在MFC中使用
class Qt_DXF_API DxfTabWidget : public QTabWidget
{
	Q_OBJECT
public:
	DxfTabWidget(QWidget *parent = nullptr);
	~DxfTabWidget();
	void setDxf(const std::shared_ptr<DXF::DxfData> &dxfData);

private:
	void onCurrentChanged(int index);

	DxfTabWidgetPrivate* d_ptr;
};
  1. 使用qtwinmigrate来整合MFC和Qt两个系统,可以从网上下载源代码。
  2. 安装VS2017及其Qt插件。【已经有的跳过】
  3. 用VS2017打开qtwinmigrate的pro文件。
  4. 编译测试是否正确。同时会生成moc_qwinhost.cpp和moc_qwinwidget.cpp。
  5. 生成MFC对话框工程。
  6. 添加一个MFC扩展DLL工程。
  7. 把DxfTabWidget和Qt的相关lib、dll、h文件复制到3rd目录。
    在这里插入图片描述
    在这里插入图片描述
  8. 设置两个工程的include、lib目录,和引入的库。这两步比较繁琐,但是大部分程序员会做。
  9. 在dllmain加入下列代码
	if (dwReason == DLL_PROCESS_ATTACH)
	{
		TRACE0("QtDxfViewerLib.DLL 正在初始化!\n");
		// 扩展 DLL 一次性初始化
		if (!AfxInitExtensionModule(QtDxfViewerLibDLL, hInstance))
			return 0;
		new CDynLinkLibrary(QtDxfViewerLibDLL);
		ownApplication = QMfcApp::pluginInstance(hInstance);
	}
	else if (dwReason == DLL_PROCESS_DETACH)
	{
		TRACE0("QtDxfViewerLib.DLL 正在终止!\n");
		delete qApp;
		// 在调用析构函数之前终止该库
		AfxTermExtensionModule(QtDxfViewerLibDLL);
	}
  1. 添加类
#pragma once
#include <afxwin.h>
#include <memory>

#include "DxfData.h"
#include "qtdxfviewer_api.h"

class MFCDxfViewerPrivate;
class QT_DXF_ViEWER_API MFCDxfViewer :
	public CWnd
{
public:
	MFCDxfViewer();
	~MFCDxfViewer();

	BOOL CreateFromStatic(UINT   nID, CWnd*   pParent);
	void setDxf(const std::shared_ptr<DXF::DxfData> &dxfData);
	void setDxf(const char *dxfFileName, bool OnlyReadModelSpace);

	DECLARE_MESSAGE_MAP()
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

private:
	MFCDxfViewerPrivate* d_ptr = nullptr;
public:
	afx_msg void OnDestroy();
	afx_msg void OnSize(UINT nType, int cx, int cy);
};
#include "pch.h"

#include <QHBoxLayout>

#include "MFCDxfViewer.h"
#include "qtwinmigrate/qwinwidget.h"
#include "DxfViewer.h"
#include "DxfReader.h"

BEGIN_MESSAGE_MAP(MFCDxfViewer, CWnd)
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_WM_SIZE()
END_MESSAGE_MAP()

class MFCDxfViewerPrivate
{
public:
	QWinWidget* container = nullptr;
	DxfTabWidget* dxfViewer = nullptr;
	std::shared_ptr<DXF::DxfData> dxfData;
};

MFCDxfViewer::MFCDxfViewer()
	: d_ptr(new MFCDxfViewerPrivate)
{
}

MFCDxfViewer::~MFCDxfViewer()
{
	delete d_ptr;
	d_ptr = nullptr;
}

BOOL MFCDxfViewer::CreateFromStatic(UINT   nID, CWnd*   pParent)
{
	CStatic   wndStatic;
	if (!wndStatic.SubclassDlgItem(nID, pParent))
		return   FALSE;
	//   获取静态控制的矩形区域并转换为父窗口的客户区坐标 
	CRect   rc;
	wndStatic.GetWindowRect(&rc);
	pParent->ScreenToClient(&rc);
	wndStatic.DestroyWindow();
	return
		Create(NULL, //   类名 
			NULL, //   标题 
			(WS_CHILD | WS_VISIBLE),
			rc,
			pParent,
			nID,
			NULL);   //框架/文档 
}

void MFCDxfViewer::setDxf(const std::shared_ptr<DXF::DxfData>& dxfData)
{
	d_ptr->dxfData = dxfData;
	if (d_ptr->dxfViewer)
		d_ptr->dxfViewer->setDxf(dxfData);
}

void MFCDxfViewer::setDxf(const char * dxfFileName, bool OnlyReadModelSpace)
{
	std::shared_ptr<DXF::DxfData> dxfData = std::make_shared<DXF::DxfData>();
	DXF::DxfReader reader(*dxfData);
	bool success = reader.ReadDxf(dxfFileName, OnlyReadModelSpace);
	if (success)
	{
		setDxf(dxfData);
	}
}

int MFCDxfViewer::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	d_ptr->container = new QWinWidget(this);
	auto hbox = new QHBoxLayout(d_ptr->container);
	hbox->setMargin(0);
	hbox->setSpacing(0);
	d_ptr->dxfViewer = new DxfTabWidget(d_ptr->container);
	hbox->addWidget(d_ptr->dxfViewer);
	d_ptr->container->setLayout(hbox);
	d_ptr->container->show();

	return 0;
}


void MFCDxfViewer::OnDestroy()
{
	CWnd::OnDestroy();

	delete d_ptr->container;
}


void MFCDxfViewer::OnSize(UINT nType, int cx, int cy)
{
	CWnd::OnSize(nType, cx, cy);

	RECT r;
	GetClientRect(&r);
	d_ptr->container->setGeometry(r.left, r.top, r.right - r.left, r.bottom - r.top);
}
  1. 在MFC对话框程序中,像普通的自定义MFC控件一样使用就行了。
  2. 编译通过。Debug运行正常,Release运行出错。
    在这里插入图片描述
    复制Qt plugin,设置环境变量QT_QPA_PLATFORM_PLUGIN_PATH统统没用。需要使用windeployqt进行部署,像qt程序一样。
    在这里插入图片描述
    部署完成后Release目录如下:
    在这里插入图片描述
    运行windeployqt.exe之后,Release目录复制了红框中这些文件。
    结果如下:
    在这里插入图片描述
    源代码下载
    MFC嵌入Qt窗口DXF查看器
    可执行文件下载
    MFC嵌入Qt窗口DXF查看器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值