基于MFC 对话框的 PCL、VTK 、OPENCV岩体识别系统构建(2)

在上一篇文章当中,小编为大家展示了系统的界面,并附上了相关代码,这篇文章主要介绍小编的第一个功能模块—–文件模块。

但是在开始介绍文件模块时,需要对之前的界面设计做一个优化:1、我们需要界面在进行放大缩小变化时,,里面的控件以及控件内的对话框也能够随着主界面的变化自动调整为合适的大小。2、美化MFC程序界面。具体解决方案如下:

一、布局自动调整

1、首先在XXXDlg.h头文件中添加public成员变量及函数

POINT old;void ReSize();2、之后响应主对话框窗口的OnSize方法

afx_msg void OnSize(UINT nType, int cx, int cy);3、在OnInitDialog中添加代码来获取原始对话框的大小

CRect rect;GetClientRect(&rect);old.x = rect.right – rect.left;old.y = rect.bottom – rect.top;4、在WM_SIZE消息中添加代码

// TODO: Add your message handler code hereif (nType==SIZE_RESTORED||nType==SIZE_MAXIMIZED){ReSize();} 表示当最大化与还原窗口时调用ReSize方法

5、编写ReSize代码

float fsp[2];POINT Newp; //获取现在对话框的大小CRect recta;GetClientRect(&recta);//取客户区大小Newp.x=recta.right-recta.left;Newp.y=recta.bottom-recta.top;fsp[0]=(float)Newp.x/old.x;fsp[1]=(float)Newp.y/old.y;CRect Rect;int woc;CPoint OldTLPoint,TLPoint; //左上角CPoint OldBRPoint,BRPoint; //右下角HWND hwndChild=::GetWindow(m_hWnd,GW_CHILD); //列出所有控件while(hwndChild){woc=::GetDlgCtrlID(hwndChild);//取得IDGetDlgItem(woc)->GetWindowRect(Rect);ScreenToClient(Rect);OldTLPoint = Rect.TopLeft();TLPoint.x = long(OldTLPoint.x*fsp[0]);TLPoint.y = long(OldTLPoint.y*fsp[1]);OldBRPoint = Rect.BottomRight();BRPoint.x = long(OldBRPoint.x *fsp[0]);BRPoint.y = long(OldBRPoint.y *fsp[1]);Rect.SetRect(TLPoint,BRPoint);GetDlgItem(woc)->MoveWindow(Rect,TRUE);hwndChild=::GetWindow(hwndChild, GW_HWNDNEXT);}old=Newp; 这样,当主对话框发生变化的时候,里面的控件也会自动调整大小。

同样的,由于我们的主显示区域是控件里面添加了对话框,同时在对话框内部放置了2个控件,所以当我们对对话框生成类的时候同样需要添加上诉代码来完成子对话框内部控件的自动调整。

二、MFC界面美化

MFC制作的界面比较粗糙,相关的贴图设置也比较麻烦,这里小编使用开源的界面美化类库SkinMagic v2.4破解版,主要使用方法如下:

1、解压完成之后,选择里面的一个*.smf皮肤文件,将其拷贝到工程文件的res目录下,然后在程序中加载该资源。我们在资源目录里新建一类资源"SKINMAGIC",然后添加皮肤文件到其中,设置资源ID,如下图:

2、在工程文件XXX.cpp文件中的AfxEnableControlContainer()之后添加如下代码:

AfxEnableControlContainer();VERIFY(1 == InitSkinMagicLib(AfxGetInstanceHandle(), NULL, NULL, NULL)); VERIFY(1 == LoadSkinFromResource(AfxGetInstanceHandle(),(LPCTSTR)ID,"SKINMAGIC"));3、在XXXDlg.cpp文件中的OnInitDialog中添加如下代码:

SetWindowSkin(m_hWnd,"Dialog");VERIFY(1 == SetDialogSkin("Dialog"));4、最后在XXX.cpp文件中添加ExitInstance

ExitSkinMagicLib();return CWinApp::ExitInstance();这样,我们就可以使用类库中的皮肤了。完成之后的界面如下所示:

三、文件模块功能实现

本系统的文件打开功能主要有:打开(点云/图片),保存(点云/图片),另存为(点云/图片),关闭(显示区),退出系统

在正式编写代码前,我们需要进行相关类的设计工作,例如可以定义哪些抽象类,然后什么情况下需要进行派生,抽象类中定义哪些虚函数,数据的输入输出是否可以统一在一个类中进行等等。这里小编的设计肯定有所不足,还望大家给予指出。

在小编的设计中,文件的输入输出主要通过自定义类FileIO文件来实现,里面定义了如何进行读取和写入,如何保存,如何另存为等相关操作。

针对点云数据和图像数据,分别建立了对应的自定义类,里面封装了两者的相关操作。

对于可视化,自定义了一个VTK的基类,具体的显示类则派生自该类。

相关结构如下:

PCL: MyPCL类—>派生自自定义的PCLAbstract抽象类

OpenCV:MyCVImage类—–>派生自自定义的CVAbstract抽象类

文件读写:自定义FileIO类

封装数据结构:PCLPoints—->派生自MyPoint抽象类

VTK显示:VTKPCL类—–>派生自自定义VTKAbstract抽象类

一、点云数据文件打开

首先在PCLPoints中定义的点云数据结构如下:

派生自基类的部分:

//成员变量double m_x;double m_y;double m_z;派生类自定义的部分:

//成员变量;int m_id;int m_pid;因此,CFileIO::openPCLData如下:

/************************************************************************//* 打开txt的点云数据*//************************************************************************/CVTKPCL* CFileIO::openPCLData(){m_defaultFilePath = m_filePath;//记录下这个地址;ifstream inFile;inFile.open(m_filePath.c_str());if(!inFile.is_open()){AfxMessageBox("错误:文件打开失败",MB_OK);return NULL;}int i = 0;char t = 'a';while(!inFile.eof()){CPCLPoints pt;inFile>>pt.m_id>>t>>pt.m_pid>>t>>pt.m_x>>t>>pt.m_y>>t>>pt.m_z;pArray.push_back(pt);}i = pArray.size();CString s;s.Format("共载入%d个点,请问需要进行可视化显示吗?",pArray.size());if(IDYES == AfxMessageBox(s,MB_YESNOCANCEL)){vtkpclObject.showPCLPoints(pArray);}inFile.close();return &vtkpclObject;}这里首先在FileIO类中定义了用于保存点云文件路径的m_filePath以及m_defaultFilePath,并且定义了存储点云数据的vector:

vector<CPCLPoints>pArray;定义了将点云数据pArray用于vtk显示化的vtkpclObject对象,并对其所在类CVTKPCL定义了showPCLPoints方法:

从哪里跌倒就会从哪里爬起来,让我们一起努力吧

基于MFC 对话框的 PCL、VTK 、OPENCV岩体识别系统构建(2)

相关文章:

你感兴趣的文章:

标签云: