1.1.4  文档视图结构

由于使用Visual C++ 6.0开发的程序,绝大部分是文档视图结构,所以下面介绍文档视图结构的相关知识。

一个商场有许多数据,为了便于处理,将这些数据库存放到数据库中。不同的员工对数据的要求不同,售货员关心的是商品的价格,人事经理关心的是员工的业绩。MFC将前者(数据库中的数据)抽象成文档,后者(人机交互)抽象成视图。与视图有关还有框架和文档模板,下面分别介绍。

¡  文档的本质:文档是用来保存数据以及关于数据的处理的,当程序响应“FileOpen”或“FileNew”的时候都会打开一份文档。文档可以拥有多个视图。文档和视图的关系可以这样理解:文档是被视图观察的对象。

¡  视图本质:视图在Windows中就是一个窗口,也就是一个可视化的矩形区域。视图是用来表示文档的数据的。但是每个视图必需依附于一个框架(SDI中是MainFrameMDIChildFrame)。

¡  框架的本质:框架实际是也是一个Windows窗口。但是在框架上可以放置菜单、工具栏、状态栏等。而视图则放在框架的客户区。因此MFC中我们看到的窗口实际上FrameView共同作用的结果。

在某一时刻,程序中只有一个活动的文档、框架和视图,即当前的文档、框架、视图。应用程序类管理文档模板,文档模板管理框架、视图、文档。

一般而言,写代码时,文档类和视图类改得较多,框架类改得比较少,文档模板类几乎不会被修改。下面突出重点,讲一下文档和视图类的相关内容。

1.文档和视图的相互访问

文档与视图的关系是一对多关系。在MFC中,文档用CDocument类及其派生类处理,视图类由CView及其派生类处理。应用程序向导生成程序框架时,会自动为CXXView类生成GetDocument函数,可能通过此函数访问文档类。由于一个文档类对应多个视图类,可以遍历视图列表,代码如下:

#include "Ex010104View.h"

//...

void CEx010104Doc::VisiteViews()

{

         CEx010104View * pView = NULL ;

         for(POSITION pos = GetFirstViewPosition() ; NULL != pos ; )

         {

                  pView = (CEx010104View *)GetNextView(pos);

                   //对视图进行相应操作

         }

}

2.视图类的刷新

文档数据发生了变化,所有的视图必须作相应的更新,这时可以用CDocument类的UpdateAllView函数,其原型如下:

void UpdateAllViews( CView* pSender, LPARAM lHint = 0L, CObject* pHint = NULL );

¡  pSender:指向修改文档的视图的指针,为NULL表示刷新所有的视图。

¡  lHint:表示关于修改的信息。

¡  pHint:表示关于修改信息的CObject类指针。

此函数的实现如下:

void CDocument::UpdateAllViews(CView* pSender, LPARAM lHint, CObject* pHint)

         // walk through all views

{

         ASSERT(pSender == NULL || !m_viewList.IsEmpty());

                   // must have views if sent by one of them

 

         POSITION pos = GetFirstViewPosition();

         while (pos != NULL)

         {

                  CView* pView = GetNextView(pos);

                  ASSERT_VALID(pView);

                   if (pView != pSender)

                            pView->OnUpdate(pSender, lHint, pHint);

         }

}

从实现代码中可以看出,UpdateAllViews调用各视图的OnUpdateOnUpdate会调用Invalidate(TRUE)刷新视图。由于OnUpdate类是虚函数,所以会调用的是派生类的OnUpdate,可以根据需要,重写OnUpdate函数。

 

3CView类的OnInitialUpdate()函数

新建或打开文档时,此函数会被调用,CView类的OnInitialUpdate()函数除了调用OnUpdate()函数之外,不做其他任何事情。如果想对视图进行初始化,可以在CView的派生类的OnInitialUpdate()函数进行。

4CDocument类的DeleteContens()函数

当文档关闭时,应用程序框架会自动调用此函数。如果需要对文档进行清理操作,就可重写此函数。



回目录