文档和视图

来源:互联网 发布:赛诺数据中国手机 编辑:程序博客网 时间:2024/06/06 09:20

文档与视图的关系可以是一对一或者一对多
UpdateAllViews()用来更新所有与文档相关的视图
文档模板的创建和维护是在CWinApp中的InitInstance()中实现的,例如单文档模板:

CSingleDocTemplate* pDocTemplate;
 pDocTemplate 
= new CSingleDocTemplate(
  IDR_MAINFRAME,
  RUNTIME_CLASS(CPlotDoc),
  RUNTIME_CLASS(CMainFrame),
  RUNTIME_CLASS(CPlotView));
 AddDocTemplate(pDocTemplate);

应用程序类:派生于CWinApp,总体程序管理,例如初始化程序和最后的程序清除工作,文档视图结构,程序的主窗口
文档类:派生于CDocument,数据的存储与读取
视图类:派生于CView,显示数据,交互输入,可以用GetDocument()获取文档指针,用于读取和操作文档中的数据,从而实现对文档数据的修改。CView是虚拟类,包含了纯虚函数,例如OnDraw(),所以它本身不能直接用于声明对象。
主框架类:单/多文档分别派生于CFrameWnd和CMDIFrameWnd,管理用户界面对象,例如菜单、工具条、状态栏、加速键表。调用OnActiveView()通知当前视图。

-----------------------------------------------------------------分割线-----------------------------------------------------------------

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

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

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

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

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

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调用各视图的OnUpdate,OnUpdate会调用Invalidate(TRUE)刷新视图。由于OnUpdate类是虚函数,所以会调用的是派生类的OnUpdate,可以根据需要,重写OnUpdate函数。

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

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

原创粉丝点击