制作自己的MFC MDI OPENCV程序框架

22 篇文章 0 订阅
 

制作自己的MFC MDI OPENCV程序框架

分类: MFC MDI OPENCV CScrollView 学习 框架   1051人阅读  评论(1)  收藏  举报

PS:我记录下这个过程,既是一个学习过程,也想分享给大家。因为是尝试,所以可能中途可能有错误。我尽量记录下来。而且我制作中尽量做到每一步都可以运行,方便测试。简单地说,我想要用VC6.0和Open CV 1.0进行数字图像处理的学习,并且写出自己完整程序来。如果直接使用open cv,看起来不太直观、不专业。《在MFC中使用OpenCV》应该是最好的学习资料和例程,可是我既不熟悉VC,也不熟悉open cv,入门难度比较大,这里把我的学习和分析的过程、经验以及结果分享给大家,希望对大家有帮助。

一、环境

1、VC6.0

2、OPENCV 1.0

3、改编自《在MFC中使用OpenCV》,来源于:

http://wiki.opencv.org.cn/index.php/%E5%9C%A8MFC%E4%B8%AD%E4%BD%BF%E7%94%A8OpenCV

4、VC2010 OPENCV2.4.9环境下面建立过程基本一样,只有少许变化。(VC2013下面如果使用2010这个工程,首先它会自动升级,然后编译失败,需要下载一个

Multibyte MFC Library for Visual Studio 2013,连接为)

关于vc2013直接建立工程,因为工程是默认的unicode,所以如果不设置成多字节模式,会有一个比较严重的问题:opencv的很多对文件操作的函数不是unicode的,而LPCTSTR到const char *这样的转换非常麻烦(当然可以用WideCharToMultiByte这样的函数来完成),所以,如果使用vc2013的话,还是应该不使用unicode,其他部分和vc2010是一样的。   

注意:这个原始程序估计是因为修改了类名,但是消息映射的某些东东没有改,最后导致类向导中处理某些类时失败!本人已经修复了此错误。

附件中将提供:《在MFC中使用OpenCV》原始程序及文档、VC6.0 OPENCV1.0版本、VC2010 OPENCV2.4.9版本3样东东,预计将放在CSDN下载频道中。可是本博客不知为何会处于审核状态,等解禁后就上传。

二、参考资料

1、《在MFC中使用OpenCV.doc》,上述文章和程序的作品。这些东东最后都提供给大家,可能需要大家仔细研究。

2、《MFC多文档中opencv处理图像打开、保存》,来源于:

http://blog.csdn.net/abcjennifer/article/details/7313711

这个MM的BLOG不错啊,大家可以认真研究一下。

 

三、新建MFC .EXE工程MyCV(这个工程特意取了一个新的名字,和原程序不一样!),MDI,注意向导的最后一步我们的视图类CMyCVView的基类应该选择CScrollView,因为我们做图象处理不希望显示时进行缩放,需要原样显示,所以滚动条是必须的。

 

四、加入OpenCV及DirectShow相关的东东

1、给工程加入opencv的几个库

cxcore.lib cv.lib ml.lib cvaux.libhighgui.lib cvcam.lib

2、将CameraDS.h、CameraDS.cpp、对应头文件以及目录DirectShow复制到你的项目中

3、Additional include directories

Project->Settings->Settings for:(All configurations)->C/C++->Category(Preprocessor)

->Additional include directories设置为../DirectShow/Include

4、Additional library directories

Project->Settings->Settings for:(Allconfigurations)->Link->Category(Input)

->Additional library directories设置为 ../DirectShow/Lib

PS:2、3、4三点在CameraDSA.cpp中有说明,注意上面绿色部分和目录结构有关!

4、tools->option中的lib file把例程的lib文件夹前置到最顶头

    例程中包含了strmiid.lib含有这些外部符号,windows系统SDK也包含了strmiid.lib,需要优先使用directshow中的,否则编译过不了。参见:

http://blog.csdn.net/makenothing/article/details/8750703

5、将Processing.cpp和Processing.h复制到你的项目中

    本程序设计的思路是这样的:图形处理本身使用opencv,而显示结果则使用windows自己的方式。由于二者存储格式不同,所以需要进行一些转换。另一种实现MFC的方法是采用CvvImage类,我们这里不采用它。

模块中增加了4个函数,即CtreateMapInfo、imageType、imageClone与imageReplace。CtreateMapInfo函数用于建立工作位图workImg的位图信息m_lpBmi,其特点是可以为单通道位图设置两种调色板,即黑白灰阶调色板与VGA默认调色板。因为在OpenCV中二值图像显示为灰阶图像,imageType函数可从单通道位图中识别出二值位图。ImageClone与imageReplace函数使用OpenCV函数实现位图的复制,自动释放老的指针所指向的存储单元以防止内存泄漏,同时返回的m_dibFlag标志可以用于激发刷新工作位图workImg的位图信息m_lpBmi。imageReplace与ImageClone相似,但不建立新位图,只用输入位图替换输出位图。

 这四个函数及其他常规图像处理放在两个文件中:Processing.h和Processing.cpp,拷贝并加工程中。编译有17个错误,经检查,这两个文件没有包含opencv的头文件(顺便说一下,前面建立工程后就应该引用cxcore.lib cv.lib ml.lib cvaux.lib highgui.lib cvcam.lib这几个库文件,赶紧加上)。经查,是在stdafx.h中include的:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include "MyCV.h"                          //  窗口管理  
  2.   
  3. #include "cv.h"                             //  OpenCV 文件头  
  4. #include "highgui.h"  
  5.    
  6. #include "CameraDS.h"                       //  DirectShow(基于OpenCV)  
  7. #include "CVDSCap.h"                        //  视频采集接口  
  8.   
  9. #include "Processing.h"                     //  附加辅助函数  
  10.   
  11. #endif   
  12.   
  13. //{{AFX_INSERT_LOCATION}}  
  14. // Microsoft Visual C++ will insert additional declarations immediately before the previous line.  
  15.     
  16. // !defined(AFX_STDAFX_H__1836CF0C_3704_4215_8745_F068486288D6__INCLUDED_)  

 

五、修改IDD_ABOUTBOX对话框,加上自己的版权信息。修改String Table中的IDR_MAINFRAME和AFX_IDS_APP_TITLE的Caption为:“OpenCV MFC MDI图像处理程序框架”,把应用程序的名称改为我们需要的。

 

六、修改CMainFrame::OnCreate,注释掉工具条(mainfrm.cpp文件中),因为我们需要对菜单等进行大动作,如果保留工具条的话太复杂了,有很多工作要做,只留菜单要简单得多。

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)  
  2. {  
  3.     if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)  
  4.         return -1;  
  5.   
  6. //去掉工具条  
  7. /*   
  8.     if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP 
  9.         | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || 
  10.         !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) 
  11.     { 
  12.         TRACE0("Failed to create toolbar\n"); 
  13.         return -1;      // fail to create 
  14.     } 
  15.  
  16.     if (!m_wndStatusBar.Create(this) || 
  17.         !m_wndStatusBar.SetIndicators(indicators, 
  18.           sizeof(indicators)/sizeof(UINT))) 
  19.     { 
  20.         TRACE0("Failed to create status bar\n"); 
  21.         return -1;      // fail to create 
  22.     } 
  23.  
  24.     // TODO: Delete these three lines if you don't want the toolbar to 
  25.     //  be dockable 
  26.     m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); 
  27.     EnableDocking(CBRS_ALIGN_ANY); 
  28.     DockControlBar(&m_wndToolBar); 
  29. */  
  30.     return 0;  
  31. }  

七、修改菜单

1、主菜单IDR_MAINFRAME

先删除“查看”菜单

“文件”菜单中,删除“新建”、“打印设置”菜单(同时为了美观删除多余的separator),只留下“打开”、“最近文件”、“退出”三个菜单

2、子菜单IDR_MYCVTYPE(为了简单起见,我们认为所有的图象都是一种类型),所以只有这一个!

“编辑”、“查看”都删掉,只保留“文件”、“窗口”、“帮助”三个菜单

“窗口”:只保留“层叠”、“平铺”两个,其余删掉。(PS:我感觉可以全部保留,留待后面验证,到时不行再删掉。结论是:其他两个没有什么用,删掉)

“文件”:

(1)“新建”删掉

(2)“打开”ID_FILE_OPEN,改成“打开图象”

(3)新建一个“恢复图象”,ID_REFRESH

(4)在下面插入一个separator

(5)“关闭”ID_FILE_CLOSE,改成“关闭当前窗口”

(6)新建一个“保存当前位图”,ID_CONSERVATION_IMAGE

(7)删除“保存”、“另存为”、separator、“打印”、“打印预览”、“打印设置”

(8)“退出”前面插入一个“恢复原始图象”,ID_COLOR_IMAGE_REFRESH

(9)“退出”前面插入一个“当前画面存盘”,ID_FILE_SAVE_AS

(10)“退出”前面插入一个separator

(11)暂时到这,后面加入具体功能时再来加入其他菜单

八、“软件锁”

   本演示程序中有许多功能需要打开OpenCV设置的窗口,如果不关闭这些窗口就执行其他功能会造成程序故障。为了避免产生这种情况,特在使用这种窗口的程序中加设“软件锁”,即在相应功能的执行程序中设置参数m_ImageType的值为-3。而在需要锁住功能的使能函数OnUpdateXXX()中用条件(m_ImageType!=-3)来限制。因此,当程序执行过程中菜单无法使用时,必定是有所开的窗口忘了关闭,请先关闭这些窗口,然后再运行所需功能或退出演示程序。

    具体是在MyCVView.h中CMyCVView类的定义中进行修改:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #ifdef _DEBUG  
  2.     virtual void AssertValid() const;  
  3.     virtual void Dump(CDumpContext& dc) const;  
  4. #endif  
  5.   
  6. protected:  
  7.     IplImage* saveImg;  
  8.     IplImage* workImg;  
  9.    
  10.     LPBITMAPINFO m_lpBmi;  
  11.    
  12.     int     m_CaptFlag;  
  13.     int     m_dibFlag;  
  14.     int     m_SaveFlag;  
  15.     int     m_ImageType;  
  16.    
  17. // Generated message map functions  

相应的构造函数也要初始化它们

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. CFile fCapture;  
  2. CFileException eCapture;  
  3. char pbuf[20];  
  4. int  captSetFlag=0;  
  5.   
  6. CMyCVView::CMyCVView()  
  7. {  
  8.     // TODO: add construction code here  
  9.     saveImg    = NULL;  
  10.     workImg    = NULL;  
  11.     
  12.     m_lpBmi    = 0;  
  13.   
  14.     m_CaptFlag = 0;  
  15.     m_dibFlag  = 0;  
  16.     m_ImageType= 0;  
  17.     
  18.     CSize sizeTotal;  
  19.     sizeTotal.cx = sizeTotal.cy = 100;  
  20.     SetScrollSizes(MM_TEXT, sizeTotal);  
  21.   
  22.     if(fCapture.Open( "CaptSetup.txt", CFile::modeRead, &eCapture ) )  
  23.     {  
  24.         fCapture.Read( pbuf, 20 );          //  取出分辨率设置数据  
  25.         sscanf(pbuf,"%d  %d",&frameSetW,&frameSetH);  
  26.         fCapture.Close();  
  27.     }  
  28.   
  29. }  


CMyCVDoc类的定义中:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. class CMyCVDoc : public CDocument  
  2. {  
  3. protected// create from serialization only  
  4.     CMyCVDoc();  
  5.     DECLARE_DYNCREATE(CMyCVDoc)  
  6.   
  7. // Attributes  
  8. public:  
  9.     IplImage*   pImg;  
  10.     int         m_Display;  

相应的构造函数

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. CMyCVDoc::CMyCVDoc()  
  2. {  
  3.     // TODO: add one-time construction code here  
  4.     pImg=NULL;  
  5.     m_Display=-1;  
  6.   
  7. }  

好了,现在可以打开图象文件了,但是没有绘制图象,这说明还有一些工作没有做。

 

 

九、现在需要打开图像

用类向导给文档生成打开的函数(CMyCVDoc::OnOpenDocument)


[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. BOOL CMyCVDoc::OnOpenDocument(LPCTSTR lpszPathName)   
  2. {  
  3.     if (!CDocument::OnOpenDocument(lpszPathName))  
  4.         return FALSE;  
  5.       
  6.     // TODO: Add your specialized creation code here  
  7.     BOOL bool;  
  8.   
  9.     Load(&pImg,lpszPathName);  
  10.     if (pImg!=NULL) bool=true;  
  11.     else bool=false;  
  12.     return(bool);  
  13. }  

然后这里需要成员函数Load,干脆同时加入Save函数

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. BOOL CMyCVDoc::Load(IplImage** pp,LPCTSTR csFileName)  
  2. {  
  3.     IplImage* pImg=NULL;  
  4.   
  5.     pImg = cvLoadImage(csFileName,-1);      //  读图像文件(DSCV)  
  6.     if (!pImg) return(false);  
  7.     cvFlip(pImg);                           //  与 DIB 像素结构一致  
  8.     if (*pp) {  
  9.         cvReleaseImage(pp);  
  10.     }  
  11.     (*pp)=pImg;  
  12.     m_Display=0;  
  13.     return(true);  
  14. }  
  15.   
  16.   
  17. BOOL CMyCVDoc::Save(LPCTSTR csFileName,IplImage* pImg)  
  18. {  
  19.     int   bl;  
  20.   
  21.     cvFlip(pImg);                           //  恢复原 OpenCV 位图结构  
  22.     bl=cvSaveImage(csFileName,pImg);        //  图像存盘  
  23.     return(bl);  
  24. }  

类中声明如下:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. class CMyCVDoc : public CDocument  
  2. {  
  3. protected// create from serialization only  
  4.     CMyCVDoc();  
  5.     DECLARE_DYNCREATE(CMyCVDoc)  
  6.     BOOL Load(IplImage** pImg,LPCTSTR pszFilename);  
  7.     BOOL Save(LPCTSTR pszFilename,IplImage* pImg);  
  8.   
  9. // Attributes  
  10. public:  
  11.     IplImage*   pImg;  
  12.     int         m_Display;  

还有这个需要通过类向导给打开菜单加上

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void CMyCVView::OnUpdateFileOpen(CCmdUI* pCmdUI)   
  2. {  
  3.     // TODO: Add your command update UI handler code here  
  4.     pCmdUI->Enable(m_ImageType!=-3);  
  5.       
  6. }  

十、CMyCVView类的OnDraw函数

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /  
  2. // CMyCVView drawing  
  3.   
  4. void CMyCVView::OnDraw(CDC* pDC)  
  5. {  
  6.     CMyCVDoc* pDoc = GetDocument();  
  7.     ASSERT_VALID(pDoc);  
  8.     // TODO: add draw code for native data here  
  9.   
  10.     if (pDoc->pImg!=NULL)    {               //  有磁盘输入图像  
  11.         if (pDoc->m_Display==0) {           //  尚未显示  
  12.             imageClone(pDoc->pImg,&saveImg);         //  复制到备份位图  
  13.             m_dibFlag=imageClone(saveImg,&workImg);  //  复制到工作位图  
  14.   
  15.             m_ImageType=imageType(workImg);  
  16.             m_SaveFlag=m_ImageType;  
  17.             pDoc->m_Display=1;  
  18.         }  
  19.     }  
  20.    
  21.     if (m_dibFlag) {                        //  DIB 结构改变  
  22.         if (m_lpBmi)  
  23.             free(m_lpBmi);  
  24.         m_lpBmi=CtreateMapInfo(workImg,m_dibFlag);  
  25.         m_dibFlag=0;  
  26.   
  27.         CSize  sizeTotal;  
  28.         sizeTotal = CSize(workImg->width,workImg->height);  
  29.         SetScrollSizes(MM_TEXT,sizeTotal);  //  设置滚动条  
  30.     }  
  31.   
  32.   
  33.       
  34. //下面这一段如果没有加入摄像头相关的会编译不过的,所以这里还是把它加进来     
  35.   
  36.     char *pBits;  
  37.     if (m_CaptFlag==1) pBits=m_Frame->imageData;  
  38.     else if (workImg)  pBits=workImg->imageData;  
  39.   
  40.     if (workImg) {                          //  刷新窗口画面  
  41.         StretchDIBits(pDC->m_hDC,  
  42.                 0,0,workImg->width,workImg->height,  
  43.                 0,0,workImg->width,workImg->height,  
  44.                 pBits,m_lpBmi,DIB_RGB_COLORS,SRCCOPY);  
  45.     }  
  46.   
  47. }  

好了,现在可以打开并显示图象了

 

十一、当前画面存盘

利用类向导,对菜单“当前画面存盘”(ID_FILE_SAVE_AS)生成处理程序


[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void CMyCVView::OnFileSaveAs()   
  2. {  
  3.     // TODO: Add your command handler code here  
  4.     CString csBMP="BMP Files(*.BMP)|*.BMP|";  
  5.     CString csJPG="JPEG Files(*.JPG)|*.JPG|";  
  6.     CString csTIF="TIF Files(*.TIF)|*.TIF|";  
  7.     CString csPNG="PNG Files(*.PNG)|*.PNG|";  
  8.     CString csDIB="DIB Files(*.DIB)|*.DIB|";  
  9.     CString csPBM="PBM Files(*.PBM)|*.PBM|";  
  10.     CString csPGM="PGM Files(*.PGM)|*.PGM|";  
  11.     CString csPPM="PPM Files(*.PPM)|*.PPM|";  
  12.     CString csSR ="SR  Files(*.SR) |*.SR|";  
  13.     CString csRAS="RAS Files(*.RAS)|*.RAS||";  
  14.   
  15.     CString csFilter=csBMP+csJPG+csTIF+csPNG+csDIB  
  16.                      +csPBM+csPGM+csPPM+csSR+csRAS;  
  17.   
  18.     CString name[]={"","bmp","jpg","tif","png","dib",  
  19.                        "pbm","pgm","ppm","sr""ras",""};  
  20.   
  21.     CString strFileName;  
  22.     CString strExtension;  
  23.    
  24.     CFileDialog FileDlg(false,NULL,NULL,OFN_HIDEREADONLY,csFilter);  
  25.                                             //  文件存盘对话框  
  26.     if (FileDlg.DoModal()==IDOK ) {         //  选择了文件名  
  27.         strFileName = FileDlg.m_ofn.lpstrFile;  
  28.         if (FileDlg.m_ofn.nFileExtension == 0) {  //  无文件后缀  
  29.             strExtension = name[FileDlg.m_ofn.nFilterIndex];  
  30.             strFileName = strFileName + '.' + strExtension;  
  31.                                             //  加文件后缀  
  32.         }  
  33.   
  34.         CMyCVDoc* pDoc = GetDocument();  
  35.         ASSERT_VALID(pDoc);  
  36.   
  37.         pDoc->Save(strFileName,workImg);   //  当前画面存盘  
  38.     }  
  39.       
  40. }  

以及

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void CMyCVView::OnUpdateFileSaveAs(CCmdUI* pCmdUI)   
  2. {  
  3.     // TODO: Add your command update UI handler code here  
  4.     pCmdUI->Enable((m_CaptFlag!=1)&&(m_ImageType!=-3));  
  5. }  

十二、恢复图象

利用类向导,对菜单“恢复图象”(ID_REFRESH)生成处理程序

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void CMyCVView::OnRefresh()   
  2. {  
  3.     // TODO: Add your command handler code here  
  4.     m_dibFlag=imageClone(saveImg,&workImg);  
  5.     m_ImageType=m_SaveFlag;  
  6.     Invalidate();  
  7. }  

以及

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void CMyCVView::OnUpdateRefresh(CCmdUI* pCmdUI)   
  2. {  
  3.     // TODO: Add your command update UI handler code here  
  4.     pCmdUI->Enable((m_CaptFlag!=1)&&(m_ImageType!=-3));  
  5. }  

十三、保存当前位图

利用类向导,对菜单“保存当前位图”(ID_CONSERVATION_IMAGE)生成处理程序

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void CMyCVView::OnConservationImage()   
  2. {  
  3.     // TODO: Add your command handler code here  
  4.     imageClone(workImg,&saveImg);  
  5.     m_SaveFlag=m_ImageType;  
  6. }  


以及

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void CMyCVView::OnUpdateConservationImage(CCmdUI* pCmdUI)   
  2. {  
  3.     // TODO: Add your command update UI handler code here  
  4.    pCmdUI->Enable((m_CaptFlag!=1)&&(m_ImageType!=-3));  
  5. }  

十四、恢复原始图像

利用类向导,对菜单“恢复原始图像”(ID_COLOR_IMAGE_REFRESH)生成处理程序

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void CMyCVView::OnColorImageRefresh()   
  2. {  
  3.     // TODO: Add your command handler code here  
  4.     CMyCVDoc* pDoc = GetDocument();  
  5.     ASSERT_VALID(pDoc);  
  6.     pDoc->m_Display=0;  
  7.     Invalidate();  
  8.       
  9. }  

以及

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void CMyCVView::OnUpdateColorImageRefresh(CCmdUI* pCmdUI)   
  2. {  
  3.     // TODO: Add your command update UI handler code here  
  4.     pCmdUI->Enable((m_CaptFlag!=1)&&(m_ImageType!=-3));  
  5. }  


到此为止,框架基本完成,下面就是要加入一个真正的图象处理来验证我们的成果了。

 

十五、菜单建立

先建立菜单“点处理”

再新建菜单项“彩色变灰阶”,ID_COLOR_TO_GRAY

 

十六、建立彩色变灰阶的代码

利用类向导,对菜单“彩色变灰阶”(ID_COLOR_TO_GRAY)生成处理程序

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void CMyCVView::OnColorToGray()             //  图像彩色变灰阶   
  2. {  
  3.     // TODO: Add your command handler code here  
  4.     IplImage* pImage;  
  5.     IplImage* pImg8u = NULL;  
  6.    
  7.     pImage = workImg;                       //  待处理图像换名  
  8.   
  9.     //  建立辅助位图  
  10.     pImg8u = cvCreateImage(cvGetSize(pImage),IPL_DEPTH_8U,1);  
  11.   
  12.     cvCvtColor(pImage,pImg8u,CV_BGR2GRAY);  //  彩色变灰阶  
  13.   
  14.     m_dibFlag=imageReplace(pImg8u,&workImg);  //  输出处理结果  
  15.    
  16.     imageClone(workImg,&saveImg);           //  保存当前位图  
  17.        
  18.     m_SaveFlag=m_ImageType=1;               //  设置灰阶位图标志  
  19.     Invalidate();  
  20.   
  21. }  

以及

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void CMyCVView::OnUpdateColorToGray(CCmdUI* pCmdUI)   
  2. {  
  3.     // TODO: Add your command update UI handler code here  
  4.     pCmdUI->Enable((m_CaptFlag==0)&&(m_ImageType>1));  
  5.       
  6. }  

现在,我们可以打开一个图象,点“彩色变灰阶”可以看到确实灰阶成功了,到此程序基本完成。

 

十七、让 MDI 程序 在刚启动时 不打开新文档 

在*App::InitInstance()中的(我们的程序是BOOLCMyCVApp::InitInstance())

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. CCommandLineInfo   cmdInfo;  
  2. ParseCommandLine(cmdInfo);   

后面加一句

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. cmdInfo.m_nShellCommand=CCommandLineInfo::FileNothing;  

这个算是对原始程序的一个小改进吧。

 

十八、程序打开时就立刻最大化

因为我们做图象,自然是全屏显示的好,不希望经常去拉滚动条

BOOL CMyCVApp::InitInstance()进行如下修改:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //把下面这句注释了,参数改成SW_SHOWMAXIMIZED  
  2. //以实现启动时自动最大化  
  3. //pMainFrame->ShowWindow(m_nCmdShow);  
  4. m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);     
  5. pMainFrame->UpdateWindow();  

子窗口默认最大化显示:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs)  
  2. {  
  3.     // TODO: Modify the Window class or styles here by modifying  
  4.     //  the CREATESTRUCT cs  
  5.     cs.style=WS_CHILD|WS_VISIBLE|WS_OVERLAPPEDWINDOW|WS_MAXIMIZE|FWS_ADDTOTITLE;  
  6.   
  7.     if( !CMDIChildWnd::PreCreateWindow(cs) )  
  8.         return FALSE;  
  9.   
  10.     return TRUE;  
  11. }  


这个也算是对原始程序的一个小改进吧。


代码下载 点击打开链接

版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值