- 我已经写好了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;
};
- 使用qtwinmigrate来整合MFC和Qt两个系统,可以从网上下载源代码。
- 安装VS2017及其Qt插件。【已经有的跳过】
- 用VS2017打开qtwinmigrate的pro文件。
- 编译测试是否正确。同时会生成moc_qwinhost.cpp和moc_qwinwidget.cpp。
- 生成MFC对话框工程。
- 添加一个MFC扩展DLL工程。
- 把DxfTabWidget和Qt的相关lib、dll、h文件复制到3rd目录。
- 设置两个工程的include、lib目录,和引入的库。这两步比较繁琐,但是大部分程序员会做。
- 在dllmain加入下列代码
if (dwReason == DLL_PROCESS_ATTACH)
{
TRACE0("QtDxfViewerLib.DLL 正在初始化!\n");
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);
}
- 添加类
#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
- 在MFC对话框程序中,像普通的自定义MFC控件一样使用就行了。
- 编译通过。Debug运行正常,Release运行出错。
复制Qt plugin,设置环境变量QT_QPA_PLATFORM_PLUGIN_PATH统统没用。需要使用windeployqt进行部署,像qt程序一样。
部署完成后Release目录如下:
运行windeployqt.exe之后,Release目录复制了红框中这些文件。
结果如下:
源代码下载
MFC嵌入Qt窗口DXF查看器
可执行文件下载
MFC嵌入Qt窗口DXF查看器