基于VTK的MFC应用程序开发(1)
基于VTK的MFC应用程序开发(1)
目录(?)[+]
提到MFC一般都不陌生,大部分在校学生使用最多的应该就是它了。但是相对于Qt平台来说,MFC的机制比较复杂。当使用MFC平台进行VTK程序开发时,许多人可能没有头绪。这里结合一个实例讲一下如何在MFC平台下进行VTK程序开发。
这里在MFC下实现一个基于VTK的单文档图像显示程序。通过这个程序,主要演示两个方面:一是怎样使用CMake将MFC程序与VTK结合;二是怎样在MFC程序中调用VTK类实现具体的功能。这个也是基于MFC和VTK进行软件开发的基础,搭好这个框架后,以后的工作就是垒砖了,相信通过前面的学习,垒砖已经小菜一碟了。
在开始代码之前,这里提一下,相信许多人在网上查询这方面的资料的时候,有许多资料会讲到通过MFC中的开发环境(如Visual Studio 2008)设置VTK的包含路径和lib库路径等。但是这样配置对于一般用户来说比较复杂,每次开发新的工程时候,都要查找和设置这些库,既费时费力,又不利于程序的移植(例如换到另外一台机器,如果VTK编译路径不一致的话就会找不到库)。因此这里还是推荐大家使用CMake来管理程序。仅仅几行脚本代码就可以实现VTK库的配置,而且便于程序移植。
现在开始一步步实现VTK和MFC的程序开发。首先建立一个单文档的MFC工程,工程名字为vtkSDI。这里与基于Qt的VTK程序开发稍微有点不同。先建立工程的目的是我们需要把由MFC自动生成的类加入到CMakeLists.txt中,方便管理。MFC单文档工程的建立比较简单,过程不再演示。工程文件如下所示,主要的类为CvtkSDIApp,CMainFrame,CvtkSDIDoc,CvtkSDIView和CAboutDlg五个。由于我们使用CMake来配置和生成工程,因此将工程目录下的工程文件删除,主要是.ncb,.sln,.vcproj,.user文件。
图1 MFC单文档工程的建立时所包含的文件
下面编写CMakeLists.txt文件,将工程文件写入到CMakeLists.txt中并连接VTK动态库。VTK根据功能不同划分了多个不同的模块,每个模块都是一个库。因此在编写CMakeLists.txt文件的时候,可以根据需要添加相应的模块。
- #----------------------------------------------------------------------------------
- cmake_minimum_required( VERSION 2.8 )
- project( vtkSDI )
- #----------------------------------------------------------------------------------
- # 查找并包含VTK工具包
- find_package( VTK )
- if (VTK_FOUND)
- include (${VTK_USE_FILE})
- else (VTK_FOUND)
- message (FATAL_ERROR "Cannot build without VTK. Please set VTK_DIR")
- endif( VTK_FOUND )
- #----------------------------------------------------------------------------------
- # 这里添加本工程的文件
- # 主要分为两部分:
- # 一是新建的单文档程序中的非工程文件
- # 二是用户后续添加的类文件
- SET( PROJECT_SRCS
- MainFrm.h
- MainFrm.cpp
- stdafx.h
- stdafx.cpp
- vtkSDI.h
- vtkSDI.cpp
- vtkSDIDoc.h
- vtkSDIDoc.cpp
- vtkSDIView.h
- vtkSDIView.cpp
- targetver.h
- Resource.h
- vtkSDI.rc
- res/vtkSDI.rc2
- res/vtkSDI.ico
- res/vtkSDIDoc.ico
- res/Toolbar.bmp
- res/Toolbar256.bmp
- )
- #----------------------------------------------------------------------------------
- # 设置工程包含的vtk模块,这里根据需要加载对应的模块
- include("${VTK_DIR}/GUISupport/MFC/VTKMFCSettings.cmake")
- set( VTK_LIBS ${vtk_libraries}
- vtkMFC
- vtkIO
- vtkRendering
- vtkGraphics
- vtkHybrid
- vtkFiltering
- vtkCommon
- vtkImaging
- )
- #----------------------------------------------------------------------------------
- ADD_EXECUTABLE( vtkSDI WIN32 ${PROJECT_SRCS} )
- TARGET_LINK_LIBRARIES ( vtkSDI ${VTK_LIBS} )
- <span style="font-size:14px;"> </span>
需要注意的是在倒数第二行中需要加入WIN32,否则生成的工程在编译时会出现错误。第二个需要注意的是,由于工程是基于MFC的,需要连接vtkMFC库。完成CMakeLists.txt文件后,利用CMake设置相应的代码路径(存放工程源代码)和工程路径(存在生成的工程和文件),配置、生成当前工程,得到工程文件vtkSDI.sln。
打开vtkSDI.sln并编译,编译后如无语法和链接错误,则可得到一个可运行的空工程。注意运行时可能会提示找不到dll文件错误,解决方法已在VTK与Qt整合的示例章节中说明,这里不再赘述。到此为止,基于MFC单文档工程的VTK编程框架已经搭建,接下来需要做的在该框架下调用VTK实现相应的功能。下面以图像的读取和显示为例进行说明。
首先为vtkSDI工程添加一个菜单项,通过该菜单项加载图像。打开工程的资源视图Resource View,双击Menu中IDR_MAINFRAME菜单,右键单击FILE菜单下的Open项,为该项添加一个事件Add Event Handler,弹出如下窗口:
图2 添加MFC事件响应向导
这里我们将该菜单的函数响应到CvtkSDIDoc文档类中,消息类型选择为COMMAND,点击Add and Edit按钮,完成消息的响应。该函数的作用是当用户选择该菜单时,弹出图像文件选择对话框,并将用户选择的图像文件加载。为此,我们需要为该类定义一个图像数据对象接收读入的图像数据。在CvtkSDIDoc头文件中添加如下代码,定义一个图像数据的智能指针:
vtkSmartPointer<vtkImageData> m_pImageData;
注意不要忘了添加头文件。在CvtkSDIDoc构造函数中对m_pImageData进行初始化,代码如下:
m_pImageData =vtkSmartPointer<vtkImageData>::New();
m_pImageData =NULL;
然后在菜单响应函数OnFileOpen中,添加读取图像的代码。这里以jpg格式的图像为例进行说。VTK中读取jpg图像的类为vtkJPEGReader,代码如下:
- void CvtkSDIDoc::OnFileOpen()
- {
- // TODO: Add your command handler code here
- CString FilePathName;
- CFileDialog dlg( TRUE, NULL, NULL,
- OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
- (LPCTSTR)_TEXT("JPG Files (*.jpg)|*.jpg|All Files (*.*)|*.*||"),
- NULL );
- if(dlg.DoModal()==IDOK)
- {
- FilePathName=dlg.GetPathName();
- vtkSmartPointer<vtkJPEGReader> reader = vtkSmartPointer<vtkJPEGReader>::New();
- reader->SetFileName(FilePathName.GetBuffer(0));
- reader->Update();
- m_pImageData = reader->GetOutput();
- }
- else
- {
- return;
- }
- }
下面在CvtkSDIView类中实现图像的显示功能。这里我们使用VTK中的类vtkImageViewer2。该类提供了强大的图像显示功能,可以接受vtkImageData输入,通过设置交互对象vtkRenderWindowInteractor实现用户交互,如窗宽窗位调节,图像放缩等。这里首先在CvtkSDIView头文件中定义vtkImageViewer2对象和窗口交互对象vtkRenderWindowInteractor。
vtkSmartPointer<vtkImageViewer2> m_pImageViewer;
vtkSmartPointer<vtkRenderWindowInteractor>m_pRenderWindowInteractor;
然后重载CvtkSDIView类的OnCreate()函数,在该函数中对定义的对象进行初始化,将MFC窗口句柄设置vtkImageViewer2的父窗口ID,以及设置vtkImageViewer2对象与vtkRenderWindowInteractor对象关联:
- int CvtkSDIView::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
- if (CView::OnCreate(lpCreateStruct) == -1)
- return -1;
- // TODO: Add your specialized creation code here
- m_pImageViewer = vtkSmartPointer<vtkImageViewer2>::New();
- m_pImageViewer->SetParentId(GetSafeHwnd());
- m_pRenderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
- m_pImageViewer->SetupInteractor(m_pRenderWindowInteractor);
- m_pRenderWindowInteractor->Start();
- return 0;
- }
为了使图像能够居中显示,需要每次在窗口大小改变时,设置m_pImageViewer的大小。这里重载CvtkSDIView类的函数OnSize(),当每次响应该函数时,将当前窗口的客户区域大小设置为m_pImageViewer的大小。
- void CvtkSDIView::OnSize(UINT nType, int cx, int cy)
- {
- CView::OnSize(nType, cx, cy);
- // TODO: Add your message handler code here
- CRect rect;
- GetClientRect(rect);
- m_pImageViewer->SetSize(rect.Width(), rect.Height());
- }
最后在OnDraw函数中实现图像渲染。在该函数中,将文档类中读入的图像数据设置vtkImageViewer2的输入,然后调用m_pImageViewer的Render函数开始渲染图像,并监听外部消息实现交互功能。
- void CvtkSDIView::OnDraw(CDC* /*pDC*/)
- {
- CvtkSDIDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- if (!pDoc)
- return;
- // TODO: add draw code for native data here
- m_pImageViewer->SetInput(pDoc->m_pImageData);
- m_pImageViewer->Render();
- }
编译链接后即可执行程序,运行结果如下所示。另外还可以测试交互功能,如按住鼠标右键拖动鼠标或者滑动滚轮,实现图像的放缩功能;按住鼠标左键,拖动鼠标即可实现图像窗宽窗位的调节。
图3 程序运行结果
从程序来看没有编译错误,而且正确显示图像。OK,关闭程序,这时意外出现了,在VS输出窗口中出现许多内存溢出,如下图所示:
图4 MFC&VTK程序内存溢出
这样的内存溢出是因为VTK的DLL先于MFC的DLL加载。因此在CMakeLists.txt中加入下面代码对VTK的DLL进行延迟加载,代码如下:
- VTK_MFC_ADD_DELAYLOAD_FLAGS(CMAKE_EXE_LINKER_FLAGS
- vtkMFC.dll
- vtkIO.dll
- vtkRendering.dll
- vtkGraphics.dll
- vtkHybrid.dll
- vtkFiltering.dll
- vtkCommon.dll
- vtkImaging.dll
- )
添加如上代码后,重新编译工程(rebuild),运行然后关闭工程,观察VS输出窗口中的输出信息,没有内存溢出错误,正常退出。
==========欢迎转载,转载时请保留该声明信息==========
版权归@东灵工作室所有,更多信息请访问东灵工作室
教程系列导航:http://blog.csdn.net/www_doling_net/article/details/8763686
================================================
基于VTK的MFC应用程序开发(1)相关推荐
- 基于VTK的MFC应用程序开发(3)
基于VTK的MFC应用程序开发(3) 分类: VTK应用示例 2013-05-17 13:37 3307人阅读 评论(23) 收藏 举报 目录(?)[+] 之前介绍了基于VTK的单文档应用程序开发,并 ...
- 基于VTK的MFC应用程序开发(2)
基于VTK的MFC应用程序开发(2) 分类: VTK应用示例 2013-03-29 13:03 6647人阅读 评论(18) 收藏 举报 MFCVTK图像重采样 目录(?)[+] 现在基于VTK的MF ...
- 基于VTK的Qt应用程序开发
分类: VTK应用示例 2013-03-13 15:51 6622人阅读 评论(25) 收藏 举报 VTKQtCMake 目录(?)[+] VTK附带的程序示例中大多是基于控制台的,作为可视化开发工具 ...
- 《基于Windows 7特性的程序开发系列》视频分享
前一阵录制了<基于Windows 7特性的程序开发系列>视频课程,主要针对WinForm.WPF 开发具有Windows 7 特性的程序.现已发布到MSDN Webcast 欢迎大家拍砖. ...
- 小程序 | 基于WAMP的新闻网小程序开发(体验全栈式开发微信小程序)
之前学习微信小程序开发,主要是基于JS.WXML.WXSS的前端开发,对于后端技术不精的我也是使用了微信开发者工具中的云开发功能,但是今天突发奇想,特别想体验一下全栈式开发微信小程序,学习了一下基于W ...
- 基于matlab的GPS单点定位程序开发(初学者)
基于matlab的GPS单点定位程序开发 开发初衷 本人是测绘专业的学生,在初学GPS时遇到了很多代码问题,因此希望这篇文章能够帮助广大的测绘和导航专业的学子 代码开始 开发的第一部分是:文件读取,文 ...
- 基于VTK的PACS系统的开发 心路历程2
中文操作手册-简介部分 翻译不易,且看且珍惜! 前言: 欢迎使用可视化工具包(VTK)的用户指南,VTK是一个开源的.面向对象的软件系统,用于计算机图形学.可视化. 和图像处理.虽然它大而复杂,一旦你 ...
- 基于ssm框架—微信小程序开发的会议管理系统
本系统是基于ssm架构(Spring+SpringMVC+MyBatis)开发的后台管理会议系统,系统以Java作为编程语言,采用Mysql数据库作为后台数据库.它是基于Browser/Server结 ...
- 基于VFW的视频应用程序开发
关 键 字: 视频捕获:SDK:VFW:AVI:MCI 当前,在Windows 平台下开发视频应用程序一般采用两种方式:一种是基于视频采集卡所附带的二次软件开发包SDK(Software deve ...
最新文章
- WebStrom如何设置字体?
- linux静默删除文件夹,Linux常用命令10 - unzip
- 如何进入embl的ebi网站fasta3服务器,The EMBL-EBI bioinformatics web and programmatic tools framework...
- 了解JavaScript中的循环缺点和迭代协议
- 北京大学计算机学院周磊,马秀莉-北京大学信息科学技术学院
- 谷歌浏览器:解决Chrome浏览器添加扩展程序报错无法从该网站添加应用、扩展程序和用户脚本
- html怎么设置自动音乐播放器,运用js教你轻松制作html音乐播放器
- 在angular的自定义回调中操作$scope
- 双线性对在密码学中的应用(下)
- Scrapy爬取当当网畅销图书保存csv格式!最详细的教程!
- memory hierachy
- PV-RCNN:Point-based与Voexl-based共同成就的高性能3D目标检测网络
- 麻将判断胡牌 java_麻将基本胡的算法——Java
- Reactjs开发基础
- 日记侠:你对微信关键词是如何理解的?
- css(六)--css高级技巧
- android下面res目录
- 006基于近似熵、递归量化分析和卷积神经网络的癫痫发作自动检测-2019
- 图灵机Turing Machine
- 常用软件官网下载地址