loading ...
loading...

2008-07-17 | MFC应用程序中的文档/视图结构学习

分享

文档/视图(Document/View)结构是MFC应用程序中最基本的结构,它适用于大多数Windows应用程序,且可以完成大部分功能,是MFC应用程序的核心。文档/视图结构将数据的管理与显示分离开,这给程序的开发带来很大的方便,它实际上是Microsoft为程序员提供的一些类,以方便文件和窗口的创建、显示、销毁、保存等操作。

一、Document 与 View 概述

在MFC文档/视图结构中,有关数据处理的工作可以分为数据管理和显示两部分。文档用于管理和维护数据,而视图用来显示和编辑数据。MFC正是通过其文档类和视图类提供了大量有关数据处理的方法。

文档的概念在MFC应用程序中的适用范围很广泛,一般来说,文档是能够逻辑地组合一系列数据,包括文本、图形、图像和表格数据。一个文档代表了用户存储或打开的一个文件单位。其主要作用就是把对数据的处理从对用户界面的处理和中分离出来,集中处理数据,同时提供了一个与其它类交互的借口。

视图是文档在屏幕上的一个影射,用户通过视图看到文档,也通过视图改变文档。视图充当了文档与用户之间的媒介物。而应用程序通过视图向应用程序显示文档中的数据,并将用户的输入解释为对文档的操作。一个视图总是与一个文档对象相关联,用户通过与文档类相关联的视图与文档进行交互。当用户打开一个文档时,应用程序就会创建一个与之相关联的视图。
视图负责显示和修改数据,但它不负责存储。一个视图是一个没有边框的窗口,它位于主框架窗口中的客户区。也就是说,视图是文档对外显示的窗口,但它并不能完全独立,必须依存在一个框架窗口内。下图说明了文档、视图、框架窗口之间的关系。 
 
另外,需要指出的是,一个视图只能拥有一个文档,但一个文档可以同时拥有多个视图,并且,一个文档在程序中可以支持不同类型的视图。

二、Document 与 View之间的相互作用

由于文档/视图结构将数据的管理与显示分隔开来,这就产生了一个新的问题 :文档更改后如何与视图保持同步,即文档与视图之间的交互。事实上,文档/视图结构的交互主要是通过3个成员函数来完成的。

1.CView类的GetDocument()成员函数
我们知道,一个视图对象只有一个与之关联的文档对象。在CView类中,提供了成员函数GetDocument(),用来得到与视图关联的文档。函数原型如下:
CMyDoc* CMyView::GetDocument()
{
    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc)))
    return (CMyDoc*)m_pDocument;
}
这样就可以在CView类的派生类中调用GetDocument()成员函数来得到当前文档对象的指针。

2.CDocument类的UpdateAllViews()成员函数
文档类提供了UpdateAllViews()函数,可以完成如下功能:当由于某种原因文档的内容发生了变化,那么将通知所有的视图以便能够对所显示的数据进行更新。函数原型声明如下:
void UpdateAllViews(CView* pSender, LPARAM lHint=0L, CObject* pHint=NULL);
如果在文档派生类的成员函数中调用UpdateAllViews()函数,其第一个参数就为NULL,表示所有与当前文档相关联的文档都要重新绘制;如果在视图派生类的成员函数中通过当前文档的指针调用UpdateAllViews(),则其第一个参数就设置为当前视图,如下形式: GetDocument()->UpdateAllViews(this);

3.CView类的OnUpdate()成员函数
OnUpdate()是一个虚函数,当应用程序调用了UpdateAllViews函数时,应用程序框架就会相应的调用所有视图的OnUpdate()函数,当然我们也可以直接在派生类中调用它。通常视图派生类的OnUpdate()函数访问文档,读取数据,对视图的数据成员进行更新。另外,还可以利用OnUpdate()函数使视图的某部分无效,触发视图的OnDraw()函数,利用文档数据来重绘窗口。OnUpdate()函数的原型如下:
void CView::OnUpdate(CView* pSender, LPARAM /*lHint*/, CObject* /*pHint*/)
{
      ASSERT(pSender!=this);
      UNUSED(pSender);
      Invalidate(TRUE);
}
从上面的代码中可以看到,CView::OnUpdate()函数是通过Invalidate()刷新真个客户区,也可以在自己的CWnd派生类中直接调用CView::Invalidate()函数。

分享 分享 |  评论 (0) |  阅读 (?)  |  固定链接 |  类别 (术业有专攻) |  发表于 10:09  | 最后修改于 2008-07-17 10:33
搜狐博客温馨提示:搜狐博客官方不会要求参加活动的各位博友缴纳任何的手续费用。请勿轻信留言、评论中的中奖信息,更不要拨打陌生电话及向陌生帐户汇款,谨防受骗!识别更多网络骗术,请 点击查看详情
您还未登录,只能匿名发表评论。或者您可以 登录 后发表。
 
  *中国人爱国心,搜狗输入法爱国主题皮肤下载>>
表  情:
加载中...
回复通知: 同时用小纸条通知对方该回复