VC++ 5.0下实现多视图

发表于:2007-07-04来源:作者:点击数: 标签:
解放军测绘学院 符冉迪 余旭初 在应用程序的 开发 中,有些用户可能需要解决这样一个问题:对于某类型的一个文档需要用不同的视图显示并且处理,来实现对文档的多视图操作。笔者也曾经开发过此类型的应用程序。但笔者在参考了一些关于这方面的书籍以后,感觉
解放军测绘学院 符冉迪 余旭初

  在应用程序的开发中,有些用户可能需要解决这样一个问题:对于某类型的一个文档需要用不同的视图显示并且处理,来实现对文档的多视图操作。笔者也曾经开发过此类型的应用程序。但笔者在参考了一些关于这方面的书籍以后,感觉到关于一个文档创建多个视图的实现方法写的比较少,有些参考书虽然提到了,但是其中的内容不够具体,参照实现起来比较困难。这里,笔者介绍一种Visual C++ 5.0环境下一个文档创建多个视图的易于实现的方法,供读者参考(以三个视图为例)。

  下面是实现步骤:

  创建新项目

  运行Microsoft开发者工作室New选项,用MFC AppWizard(.exe)创建一个新的Project(项目),取名为Demo。

  笔者在这里创建的是基于多文档的(MDI)应用程序,所以在创建项目时,在MFCAppWizard Step1窗口中要设置Multiple documents选项。这样,项目Demo编译连接以后生成Demo.exe。运行的结果是:每次打开一个文档就会显示一个视图。如果要创建基于单文档的(SDI)应用程序,可以设置Single document选项。现在项目Demo中已经包含了下面几个类:

http://www.ltesting.net/uploads/2007/07/1_200707042008221.jpg (10997 字节)

  增加项目Demo中的类

  打开项目Demo,选择View菜单中的ClassWizard(类向导)的选项,用类向导对话框中的Addclass 下的New选项增加下面几个新类到项目中,分别是CFirstView、CSecondView、CFirstFrame和CSecondFrame。

  CFirstView、CSecondView的基础类笔者选择的是CView,CFirstFrame、CSecondFrame的基础类是CMDIChildWnd。这样项目Demo中就多了下面几个类:

http://www.ltesting.net/uploads/2007/07/1_200707042008222.jpg (9578 字节)

  编辑Demo.h文件

  需要建立三个文档模板,分别对应三个视图。因为文档模板提供了MFC用来将文档、视、框架结合在一起的框架结构。这里的文档模板是用于MDI应用程序的CMultiDocTemplate(用于SDI应用程序的是CSingleDocTemplate),因此要在类CDemoApp声明中增加三个公有型的成员变量:

  class CDemoApp:public CWinApp

  {

  public:

  CDemoApp();

  CMultiDocTemplate *pDocTemplate;

  CMultiDocTemplate *pFirstTemplate;

  CMultiDocTemplate *pSecondTemplate;

   ∥Overrides

  ....

  DECLARE_MESSAGE_MAP()

  };

  编辑Demo.cpp文件

  首先,在Demo.cpp的头部增加四条#include指令:

  #include “FirstFrame.h”

  #include “SecondFrame.h”

  #include “FirstView.h”

  #include “SecondView.h”

  然后,需要在应用程序的模板列表中增加两个文档模板。需要将新增的两个视图与文档CDemoDoc对应起来,同时新增的两个视图要分别使用新增的MDI子窗口CFirstFrame和CSecondFrame,在CDemoApp::

  InitInstance中作如下修改:

  pDocTemplate=newCMultiDocTemplate(

  IDR_DEMOTYPE,

  RUNTIME_CLASS(CDemoDoc),

  RUNTIME_CLASS(CChildFrame),

∥用户自定义MDI子窗口框架

  RUNTIME_CLASS(CDemoView));

  AddDocTemplate(pDocTemplate);

  pFirstTemplate=newCMultiDocTemplate(

  IDR_DEMOTYPE,

  RUNTIME_CLASS(CDemoDoc),

RUNTIME_CLASS(CFirstFrame),

∥用户自定义MDI子窗口框架

  RUNTIME_CLASS(CFirstView));

  AddDocTemplate(pFirstTemplate);

  pSecondTemplate=newCMultiDocTemplate(

  IDR_DEMOTYPE,

  RUNTIME_CLASS(CDemoDoc),

  RUNTIME_CLASS(CSecondFrame),

∥用户自定义MDI子窗口框架

  RUNTIME_CLASS(CSecondView));

  AddDocTemplate(pSecondTemplate);

  编辑类CFirstView和类CSecondView

  首先,加入下列成员变量:

  pubilc:

  CDemoDoc *GetDocument();

  到FirsView.h和SecondView.h。

  接着,对FirstView.cpp用如下修改:

  void CFirstView::OnDraw(CDC *oDC)

  {

  CDemoDoc *pDoc=GetDocument();

   ∥TODO:add draw code here

  }

  ....

  #ifdef _DEBUG

  .....

  CDemoDoc *CFirstView::GetDocunent()

  {

  ASSERT(m_pDocument→IsKindOf

(RUNTIME_CLASS(CDemoDoc)));

  return(CDenidDoc *)m_pDocument;

  }

  #endif ∥_DEBUG

  然后,加入下列代码到SecondView.cpp中:

  void CSecondView::OnDraw(CDC *pDC)

  {

  CDemoDoc *pDoc=GetDocument();

∥TODO:add draw code here

  }

  ...

  #ifdef _DEBUG

  ....

  CDemoDoc *CSecondView::GetDocument()

  {

  ASSERT(m_pDocument→IsKindOf(RUNTIME_CLASS(CDemoDoc)));

  return(CDemodDoc *)m_pDocument;

  }

  #endif ∥_DEBUG

  现在,在CFirstView.cpp,CSecondView.cpp的开头分别加入下面一条#include指令:

  #include “DemoDoc.h”

  编辑DemoDoc.h文件

  由于一个文档创建三个视图,即文档要使用三个MDI子窗口,因此首先要在类CDemoDoc的声明中增加三个公有型的成员变量:

  class CDemoDoc:public CDocument

  {

  ....

   ∥Attributes

  public:

  CChildFrame *pChildFrame;

  CFirstFrame *pFirstFrame;

  CSecondFrame *pSecondFrame;

   ∥Operations

  ....

  DECLARE_MESSAGE_MAP()

  };

  同时,在DemoDoc.h的头部增加三条#include 指令:

  #include “ChildFrm.h”

  #include “FirstFrame.h”

  #include “SecondFrame.h”


  编辑CDemoView::OnInitialUpdate

  应用程序打开一个现有的文档,为了打开另外新增的两个视,就需要调用文档模板的CreateFrame()成员。另外两个新增的文档模板将文档类型和两个新增的视类联系起来,因此,在OnInitialUpdate中增加下列代码:

  vokd CDemoView::OnInitialUpdate()

  {

  CView::OnInitialUpadate()

  ...

  CDemoDoc *pDoc=GetDocument();

  ASSERT_VALID(pDoc);

  CMainFrame *pAppFrame=(CMainFrame *)

AfxGetApp()→m_pMainWnd;

  ASSERT_KINDOF(CMainFrame,pAppFrame);

  pDoc→pChildFrame=(CChildFrame *)GetParentFrame();

  CMultiDocTemplat *pFirstTemplate=((CDemoApp *)AfxGetApp())→pFirstTemplate;

  ASSERT_VALID(pFirstTemplate);

  pDoc→pFirstFrame=(CFirstFrame *)pFirstTemplate→CreateNewFrame(pDoc,pAppFrame);

  pFirstTemplate→InitialUpdateFrame(pDoc→pFirstFrame,pDoc);

  CMultiDocTemplate *pSecondTemplate=((CDemoApp *)AfxGetApp())→pSecondTemplate;

  ASSERT_VALID(pSecondTemplate);

  pDoc→pSecondFrame=(CSecondFrame *)pSecondFrame→CreateNewFrame(pDoc,pAppFrame);

  pSecondTemplate→InitialUpdateFrame(pDoc→pSecondFrame,pDoc);

  }

  调用InitialUpdateFrame()函数,是对视图的窗口框架进行初始化。而后,在文件DemoView.cpp的开头,增加如下七条#include指令:

  #include “Windows.h”

  #include “Windowsx.h”

  #include “MainFrm.h”

  #include “FirstFrame.h”

  #include “SecondFrame.h”

  #include “FirstView.h”

  #include “SecondView.h”


  修改串资源

  由于有三个文档模板,为了防止工作框认为有多个文档类型,需要对IDR_DEMOTYPE的Caption(标题)进行修改。将“\n\Demo\nDemo\n\n\n\Demo.Document\nDemoDocument”

  改成

  “\n\Demo\n\n\n\n\Demo.Document\nDemoDocument”。

  经过上述几个步骤以后,就可以实现一个文档创建多个视图。最后的事情就是进行编译连接。对于上述的实现方法有兴趣的读者不防一试。  

原文转自:http://www.ltesting.net