• MFC嵌入Qt窗口详细指导


    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    1. 添加类
    #pragma once
    #include 
    #include 
    
    #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);
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    #include "pch.h"
    
    #include 
    
    #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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    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查看器
  • 相关阅读:
    npm 和 maven 使用 Nexus3 私服 | 前后端一起学
    Tomcat Takeover
    Java之线程的详细解析一
    Fast semi-supervised learning with anchor graph for large
    免费一年VPS,digitalocean加上GitHub学生包
    警惕 “格机软件” 格式化手机全字库..不要轻易给不明觉厉的软件给root权限
    我的创作纪念日,成为创作者的第1024天。| ⑰【知识图谱·跨模态·自监督学习SSL】知识增强型推荐系统,跨模态对比学习方案 | 附:分享两款好用的WOS文献阅读插件
    汽车OTA技术门槛提升,具备软硬一体化能力的Tier1优势凸显
    解锁机器学习-梯度下降:从技术到实战的全面指南
    35 个 Spark 常用算子总结
  • 原文地址:https://blog.csdn.net/deping_chen/article/details/126724358