OnPaint 与OnDraw的区别

首先我们要知道,OnPaint()是CWnd的类成员函数,负责响应WM_PAINT消息。
       其次,在单文档应用程序中,CVIEW派生自CWnd。在对话框应用程序中,CDialog也派生自CWnd。也就是说CVIEW和Dialog都继承了OnPaint函数(当然进行了重写)。(这里要清除一个误区:我们在单文档应用程序里VIEW类只看到了OnDraw函数,而在对话框应用程序里只看到了OnPaint函数,就以为OnDraw是单文档才有,OnPaint 是对话框才有的。这是不正确的,单文档里也有OnPaint 函数,不过是继承的CWnd的。)
      那么再说OnDraw (),它其实是CVIEW自己的成员函数(与基于对话框的应用程序没多大关系),并没有没有响应消息的功能,所以光有它是不行的。当视图变得无效时(包括大小的改变,移动,被遮盖等等),Windows发送WM_PAINT消息,该视图的OnPaint 处理函数通过创建CPaintDC类(该类专门用于响应WM_PAINT消息,一般就用在OnPaint函数中)的一个对象来响应该消息并调用视图的OnDraw函数。下面是CVIEW类的OnPaint函数。
///CView默认的标准的重画函数
void CView::OnPaint() //见VIEWCORE.CPP
{
CPaintDC dc(this);
OnPrepareDC(&dc);
OnDraw(&dc);   //调用了OnDraw
}
       我们可以看出,单文档应用程序绘图时还是调用了OnPaint函数,因为只有它才能响应WM_PAINT消息,只是它最后调用了OnDraw函数而已。所以我们要处理的代码放在OnDraw函数中即可。即对CVIEW或从CVIEW类派生的窗口绘图时应该用OnDraw。


       而在对话框应用程序中,由于没有OnDraw函数,所以重绘消息处理都放在了OnPaint()函数中(当然需要自己重写)。

那为什么CVIEW要多一个OnDraw函数呢?也直接用OnPaint不就行了吗?
      我们必须要明白:
      1.OnPaint函数是一个消息响应函数,OnDraw函数是CVIEW自己的一个纯虚函数,不能响应消息。两者这是两者本质不同之处。
      2.OnPaint只对屏幕输出有效,而OnDraw对屏幕和打印机都有效,两者适用范围不同。这也是为什么单文档程序里有打印功能而           对话框应用程序没有。
      3.OnDraw()在初始化时触发,它用来处理第一次绘制(DC); OnPaint()在每次视图被激活时触发,重新绘制(刷新)。
总结:
       说白了,OnPaint函数是视图和对话框应用程序都有的,而OnDraw函数是视图多出来的。以上均是个人愚见,如有错误,请指出,不胜感激。

你可能感兴趣的:(C++/MFC)