当前位置: 代码迷 >> 综合 >> OnPaint()与OnDraw的区别
  详细解决方案

OnPaint()与OnDraw的区别

热度:30   发布时间:2023-12-14 03:58:55.0
OnPaint()与OnDraw的区别:

OnPaint()是当视类窗口需要在屏幕上输出时被调用,负责完成窗口的屏幕输出显示工作;OnPrint()是当打印一页时被调用,负责完成向某页打印纸上打印。这两个函数的缺省实现中包含了对OnDraw(CDC *pDC)的调用

OnDraw是CView类的一个虚成员函数,每当视窗需要被重新绘制时,系统都要调用OnDraw函数,当用户改变了窗口尺寸,或当窗口恢复了先前被覆盖的部分或当应用程序改变了窗口数据时,窗口都需要被重新绘制。通过重载此函数,用户程序随OnDraw一起调用,确保图形在窗口的显示。

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

其次:
我们在第《每天跟我学MFC》3的开始部分已经说到了。要想在屏幕上绘图或显示图形,首先需要建立设备环境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函数中进行绘制。

OnPaint是CWnd的成员函数,而OnDraw则是CView的虚函数。由于我没有重定义OnPaint函数,所以默认执行CView::OnPaint()函数,当执行到OnDraw(&dc);时,由于它是虚函数,所以实际执行CView::OnDraw函数,

1、Invalidate()和InvalidateRect()其实是触发对onPaint()函数的调用,  
OnPaint()函数调用OnDraw()函数,  
OnDraw函数还需要同时支持打印机输出。OnPaint()函数和OnPrint()函数都要调用OnDraw(),于是同样的绘图代码既可以用于屏幕输出,也可以用于打印机输出  
在编程中,一般重载OnDraw()就可以了。如果定义了OnPaint()函数,并且在OnDraw()里面有要显示的内容,那么需要显示的调用OnDraw(),即OnDraw(&dc)。

2、OnDraw()是被OnPaint()调用的虚函数,在CView中定义为纯虚函数,因此必须被重载,其设备上下文由OnPaint()提供。  
OnPaint()是响应消息WM_PAINT的响应函数,默认实现中在,先调用BeginPaint(),最后调用EndPaint。  
建议编程时使用OnDraw。

3、CView封装了两个函数,OnPaint()与OnPrint(),分别对应WM_PAINT与WM_PRINT。MFC为了提供更标准简易的编程接口,所以又提供了OnDraw()这个函数。OnDraw()将被OnPaint()或OnPrint()调用,根据二者分别传进来的不同DC(Paint DC或Print DC),从而完成屏幕绘制或打印工作,而不需再为两种情况分别写代码。当然,如果你只关心屏幕绘制工作,而不关心打印问题,那你完全可以直接重载OnPaint()完成绘制,而不使用OnDraw()。


参考资料: http://hi.baidu.com/%D0%C4%CA%CD%D5%AB/blog/item/d0e69dd4442c4ecb51da4b02.html