CView是视图程序设计中使用率最高的
窗口对象,它是用户的主要操作界面。因为它通常以某种形式表示文档数据,所以称之为视图。一个视图对象只关联一个文档对象;一个文档对象可以关联多个视图,每个视图对象以不同形式表示文档数据。
基本介绍
从文档类中将文档中的数据取出后显示给用户;接受用户对文档中数据的编辑和修改;将修改的结果反馈给文档类,由文档类将修改后的内容保存到磁盘文件中。
文档负责了数据真正在永久介质中的存储和读取工作,视图呈现只是将文档中的数据以某种形式向用户呈现,因此一个文档可对应多个视图。
Invalidate(TRUE)将整个窗口设置为需要重绘的无效区域,它会产生
WM_PAINT消息,这样
OnDraw将被调用。
假如文档中的数据发生了变化,必须通知所有链接到该文档的视图,这时候文档类的UpdateAllView函数需要被调用。
然而,除了打印和打印预览外,视图类显示得很简单。
关联对象
前面已经提到,视图需要表示文档数据,所以文档对象与视图对象必须建立关联。这样,当文档数据发生变化时,它可以及时通知视图;当视图需要显示不同的文档数据时,它可以从文档对象中提取。
在文档/视图框架程序中,文档对象总是在视图之前建立,而在视图的
WM_CREATE消息处理函数中,建立了它与文档对象的关联。代码如下:
同时,视图类定义了成员函数GetDocument( ),返回文档对象的指针。代码如下:
视图总是在文档对象之前销毁,在视图的
析构函数中,与文档对象解除关联。代码如下:
视图绘制
窗口的绘制工作总是在
WM_PAINT消息处理中进行的,当窗口需要绘制时,它会收到系统发来的WM_PAINT消息。在绘制过程中,首先要准备显示设备句柄,最后要释放句柄。众所周知,在视图窗口中绘制,无需
重载WM_PAINT消息处理函数
OnPaint( ),因为有一个更加友好的绘制新口:
OnDraw( )。该函数的
实参是一个已经准备好的显示设备,最后无需释放。其实,这一切还是WM_PAINT消息处理函数OnPaint( )为我们准备的,代码如下:
OnPrepareDC( )是一个
虚拟函数,它总是在OnDraw( )之前执行,可以
重载它,设置绘图模式。因为
OnDraw( )每次执行,都使用不同的
CPaintDC对象,所以本次绘图模式的状态不能保留到下一次。
OnDraw( )在视图
基类CView中定义为
纯虚函数。例如:
所以CView是
抽象基类,不能实例化,而
派生类必须重载OnDraw( )。
虚函数
OnUpdate
当文档数据发生变化时,文档对象调用
CDocument::UpdateAllView( )通知所有视图,作为响应,视图的OnUpdate( )成员被调用。所以,
重载的OnUpdate( )应该能够根据需要,将文档数据的变化反映在视图中。CView::OnUpdate( )只是简单地使客户区无效,导致客户区重画。例如:
OnInitialUpdate( )
在初始创建、调用
OnCreate( )之后,或者在File/New、File/Open命令后被框架调用。
基类CView::
OnInitialUpdate( )只是简单地调用OnUpdate( ),可以
重载它完成初始化工作。但注意,它可能被多次调用。
每当主框架窗口的客户区尺寸发生变化或
控制条的位置发生变化,需要重新排列客户区时,调用该函数,根据视图客户区尺寸计算视图窗口的尺寸。
我们知道,排列主窗口客户区是由
CFrameWnd::RecalcLayout( )完成的。显然,视图的CalcWindowRect( )函数也是由它触发调用的。主窗口的客户区尺寸减掉所有控制占用的部分,剩下的区域分给视图,这部分区域作为
实参传入
CalcWindowRect( )。在CalcWindowRect( )函数内,需要计算视图窗口的尺寸。代码如下:
PostNcDestroy
在视图窗口关闭时最后调用的成员函数,它与
CFrameWnd::PostNcDestroy完成相同的功能,即删除视图对象。代码如下:
这样,可以不必关心视图的释放工作,即使它在堆中构造。
OnCmdMsg
在讨论
CFrameWnd::OnCmdMsg( )时已经了解过该函数,下面只给出它的代码:
OnActivateView
当视图被激活为活动视图,或由活动转为非活动时,调用该函数通知视图。
基类的实现只是设置该视图为焦点。代码如下:
派生类
MFC提供了丰富的CView
派生类,各种不同的派生类实现了对不同种类控件的支持,以为用户提供多元化的显示界面。