OnDraw()和OnPaint()的区别

问题:我在视图画的图象或者文字,当窗口改变后为什么不见了? OnDraw() OnPaint() 两个都是解决上面的问题,有什么不同?

答: OnDraw() OnPaint() 好象兄弟俩,因为它们的工作类似。
至于不见了的问题简单,因为当你的窗口改变后,会产生无效区域,这个无效的区域需要重画。一般 Windows 会发送两个消息 WM_PAINT (通知客户区 有变化)和 WM_NCPAINT (通知非客户区有变化)。非客户区的重画系统自己搞定了,而客户区的重画需要我们自己来完成。这就需要 OnDraw() OnPaint() 来重画窗口。

OnDraw()
OnPaint() 有什么区别呢?首先:我们先要明确 CView 类派生自 CWnd 类。而 OnPaint() CWnd 的类成员,同时负责响应 WM_PAINT 消息。 OnDraw() CVIEW 的成员函数,并且没有响应消息的功能。这就是为什么你用 VC 成的程序代码时,在视图类只有 OnDraw 没有 OnPaint 的原因。

其次,要想在屏幕上绘图或显示图形,首先需要建立设备环境 DC 。其实 DC 是一个数据结构,它包含输 出设备(不单指你 17 寸的纯屏显示器,还包括打印机之类的输出设备)的绘图属性的描述。 MFC 提供了 CPaintDC 类和 CWindwoDC 类来实时的响 应,而 CPaintDC 支持重画。

当视图变得无效时(包括大小的改变,移动,被遮盖等等), Windows WM_PAINT 消息发送给它。该视图的 OnPaint 处理函数通过创建 CPaintDC 类的 DC 对象来响应该消息并调用视图的 OnDraw 成员函数。通常我们不必编写重写的 OnPaint 处理成员函数。

///CView
默认的标准的重画函数
void  CView::OnPaint()
{
    CPaintDC dc(
this );
    OnPreparDC(
& dc);
    OnDraw(
& dc);  // 调用了OnDraw
}


既然 OnPaint 最后也要调用 OnDraw, 因此我们一般会在 OnDraw 函数中进行绘制。下面是一个典型的程序

/// 视图中的绘图代码首先检索指向文档的指针,然后通过DC进行绘图调用。
void  CMyView::OnDraw( CDC *  pDC )

CMyDoc
*  pDoc  =  GetDocument(); 
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() );
}

最后:现在大家明白这哥俩之间的关系了吧。因此我们一般用OnPaint维护窗口的客户区(例如我们的窗口客户区加一个背景图片),用OnDraw维护视图的客户区(例如我们通过鼠标在视图中画图)。当然你也可以不按照上面规律来,只要达到目的并且没有问题,怎么干都成。

补充:我们还可以利用Invalidate(),ValidateRgn(),ValidateRect()函数强制的重画窗口

你可能感兴趣的:(paint)