在视图中绘制
应用程序中几乎所有的绘制都发生在视图的 OnDraw
成员函数中,必须在你的视图类中替代该函数。 (有一个例外情况,就是鼠标绘制,这在通过视图解释用户输入中进行了介绍。)你的 OnDraw
替代会:
通过调用所提供的文档成员函数来获取数据。
通过调用框架传递给
OnDraw
的设备上下文对象的成员函数来显示数据。
当文档的数据以某种方式发生更改时,必须重新绘制视图以反映更改。 通常,当用户通过文档上的视图进行更改时,会发生这种情况。 在这种情况下,视图会调用文档的 UpdateAllViews 成员函数,以通知同一文档上的所有视图自行更新。 UpdateAllViews
调用每个视图的 OnUpdate 成员函数。 OnUpdate
的默认实现使视图的整个工作区失效。 可以重写它以仅使映射到文档修改部分的工作区的区域失效。
类 CDocument
的 UpdateAllViews
成员函数和类 CView
的 OnUpdate
成员函数允许传递描述文档已修改部分的信息。 通过此“提示”机制,可以限制视图必须重新绘制的区域。 OnUpdate
采用两个“提示”自变量。 第一个是 lHint,类型为 LPARAM,允许传递所需的任何数据,第二个是 pHint,类型为 CObject
*,允许传递指向派生自 CObject
的任何对象的指针。
当视图变得无效时,Windows 会发送 WM_PAINT 消息。 视图的 OnPaint 处理程序函数通过创建类 CPaintDC 的设备上下文对象并调用视图的 OnDraw
成员函数来响应该消息。 通常不必编写替代的 OnPaint
处理程序函数。
设备上下文是一个 Windows 数据结构,其中包含有关设备(如显示器或打印机)绘制属性的信息。 所有绘制调用都通过设备上下文对象进行。 对于在屏幕上绘制,会向 OnDraw
传递一个 CPaintDC
对象。 对于在打印机上绘制,会向它传递一个为当前打印机设置的 CDC 对象。
用于在视图中绘制的代码首先检索指向文档的指针,然后通过设备上下文进行绘制调用。 下面这个简单的 OnDraw
示例说明了该过程:
void CMyView::OnDraw(CDC* pDC)
{
CMyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
CString s = pDoc->GetData(); // Returns a CString
CRect rect;
GetClientRect(&rect);
pDC->SetTextAlign(TA_BASELINE | TA_CENTER);
pDC->TextOut(rect.right / 2, rect.bottom / 2, s, s.GetLength());
}
在此示例中,你将 GetData
函数定义为派生文档类的成员。
该示例打印从文档中获取的任何字符串,在视图中居中。 如果 OnDraw
调用是用于屏幕绘制的,则传入 pDC 的 CDC
的对象是 CPaintDC
,其构造函数已调用 BeginPaint
。 对绘制函数的调用是通过设备上下文指针进行的。 有关设备上下文和绘制调用的信息,请参阅“MFC 引用”中的类 CDC 和使用窗口对象。
有关如何编写 OnDraw
的更多示例,请参阅 MFC 示例。