OnPaint是WM_PAINT消息的消息处理函数,在OnPaint中调用OnDraw,一般来说,用户自己的绘图代码应放在OnDraw中。 

OnPaint()
是CWnd的类成员,负责响应WM_PAINT消息。OnDraw()是CVIEW的成员函数,没有响应消息的功能.当视图变得无效时(包括大小的改变,
移动,被遮盖等等),Windows发送WM_PAINT消息。该视图的OnPaint
处理函数通过创建CPaintDC类的DC对象来响应该消息并调用视图的OnDraw成员函数.OnPaint最后也要调用OnDraw,因此一般在
OnDraw函数中进行绘制。

The WM_PAINT message is sent when the UpdateWindow or RedrawWindow member function is called.

在OnPaint中,将调用BeginPaint,用来获得客户区的显示设备环境,并以此调用GDI函数执行绘图操作。在绘图操作完成后,将调用EndPaint以释放显示设备环境。而OnDraw在BeginPaint与EndPaint间被调用。

1) 在mfc结构里OnPaint是CWnd的成员函数. OnDraw是CView的成员函数. 
2) OnPaint()调用OnDraw(),OnPrint也会调用OnDraw(),所以OnDraw()是显示和打印的共同操作。

OnPaint
是WM_PAINT消息引发的重绘消息处理函数,在OnPaint中会调用OnDraw来进行绘图。OnPaint中首先构造一个CPaintDC类得实
例,然后一这个实例为参数来调用虚函数OnPrepareDC来进行一些绘制前的一些处理,比设置映射模式,最后调用OnDraw。而OnDraw和
OnPrepareDC不是消息处理函数。所以在不是因为重绘消息所引发的OnPaint导致OnDraw被调用时,比如在OnLButtonDown等
消息处理函数中绘图时,要先自己调用OnPrepareDC。 
至于CPaintDC和CClientDC根本是两回事情
CPaintDC是一个设备环境类,在OnPaint中作为参数传递给OnPrepareDC来作设备环境的设置。真正和CClientDC具有可比性的
是CWindowDC,他们一个是描述客户区域,一个是描述整个屏幕。 
如果是对CVIEW或从CVIEW类派生的窗口绘图时应该用OnDraw。

OnDraw()和OnPaint()有什么区别呢? 
首 先:我们先要明确CView类派生自CWnd类。而OnPaint()是CWnd的类成员,同时负责响应WM_PAINT消息。OnDraw()是
CVIEW的成员函数,并且没有响应消息的功能。这就是为什么你用VC成的程序代码时,在视图类只有OnDraw没有OnPaint的原因。而在基于对话
框的程序中,只有OnPaint。 
其次:我们在第《每天跟我学MFC》3的开始部分已经说到了。要想在屏幕上绘图或显示图形,首先需要建立设备
环境DC。其实DC是一个数据结构,它包含输出设备(不单指你17寸的纯屏显示器,还包括打印机之类的输出设备)的绘图属性的描述。MFC提供了
CPaintDC类和CWindwoDC类来实时的响应,而CPaintDC支持重画。当视图变得无效时(包括大小的改变,移动,被遮盖等
等),Windows 将 WM_PAINT 消息发送给它。该视图的OnPaint 处理函数通过创建 CPaintDC
类的DC对象来响应该消息并调用视图的 OnDraw 成员函数。通常我们不必编写重写的 OnPaint 处理成员函数。

  1. //CView默认的标准的重画函数
  2. void CView::OnPaint() //见VIEWCORE.CPP
  3. {
  4. CPaintDC dc(this);
  5. OnPrepareDC(&dc);
  6. OnDraw(&dc); //调用了OnDraw
  7. }
  8. ///CView默认的标准的OnPrint函数
  9. void CView::OnPrint(CDC* pDC, CPrintInfo*)
  10. {
  11. ASSERT_VALID(pDC);
  12. OnDraw(pDC); // Call Draw
  13. }

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

  1. //视图中的绘图代码首先检索指向文档的指针,然后通过DC进行绘图调用。
  2. void CMyView::OnDraw( CDC* pDC )
  3. {
  4. CMyDoc* pDoc = GetDocument();
  5. CString s = pDoc->GetData();
  6. GetClientRect( &rect ); // Returns a CString CRect rect;
  7. pDC->SetTextAlign( TA_BASELINE | TA_CENTER );
  8. pDC->TextOut( rect.right / 2, rect.bottom / 2, s, s.GetLength() );
  9. }

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

OnDraw中可以绘制用户区域。OnPaint中只是当窗口无效时重绘不会保留CClientDC绘制的内容。 

这两个函数有区别也有联系:

1、区别:OnDraw是一个纯虚函数,定义为virtual void OnDraw( CDC* pDC ) = 0; 而OnPaint是一个消息响应函数,它响应了WM_PANIT消息,也是是窗口重绘消息。 
2、
联系:我们一般在视类中作图的时候,往往不直接响应WM_PANIT消息,而是重载OnDraw纯虚函数,这是因为在CVIEW类中的WM_PANIT消

息响应函数中调用了OnDraw函数,如果在CMYVIEW类中响应了WM_PAINT消息,不显式地调用OnDraw函数的话,是不会在窗口重绘的时候
调用OnDraw函数的。

应用程序中几乎所有的绘图都在视图的 OnDraw 成员函数中发生,必须在视图类中重写该成员函数。(鼠标绘图是个特例,这在通过视图解释用户输入中讨论。)

OnDraw 重写: 
通过调用您提供的文档成员函数获取数据。 
通过调用框架传递给 OnDraw 的设备上下文对象的成员函数来显示数据。 
当 文档的数据以某种方式更改后,必须重绘视图以反映该更改。默认的 OnUpdate 实现使视图的整个工作区无效。当视图变得无效时,Windows
将 WM_PAINT 消息发送给它。该视图的 OnPaint 处理函数通过创建 CPaintDC 类的设备上下文对象来响应该消息并调用视图的
OnDraw 成员函数。

当没有添加WM_PAINT消息处理时,窗口重绘时,由OnDraw来进行消息响应...当添加
WM_PAINT消息处理时,窗口重绘时,WM_PAINT消息被投递,由OnPaint来进行消息响应.这时就不能隐式调用OnDraw了.必须显式调
用( CDC *pDC=GetDC(); OnDraw(pDC); ).. 
隐式调用:当由OnPaint来进行消息响应时,系统自动调用CView::OnDraw(&pDC).

想象一下,窗口显示的内容和打印的内容是差不多的,所以,一般情况下,统一由OnDraw来画。窗口前景需要刷新时,系统会会调用到OnPaint,而OnPaint一般情况下是对DC作一些初始化操作后,调用OnDraw()。

OnEraseBkGnd(),是窗口背景需要刷新时由系统调用的。明显的一个例子是设置窗口的背景颜色(你可以把这放在OnPaint中去做,但是会使产生闪烁的现象)。 
至于怎么界定背景和前景,那要具体问题具体分析了,一般情况下,你还是很容易区别的吧。

的确,OnPaint()用来响应WM_PAINT消息,视类的OnPaint()内部根据是打印还是屏幕绘制分别以不同的参数调用OnDraw()虚函数。所以在OnDraw()里你可以区别对待打印和屏幕绘制。 
其实,MFC在进行打印前后还做了很多工作,调用了很多虚函数,比如OnPreparePrint()等。

OnDraw和Opanit的区别的更多相关文章

  1. MFC中OnDraw()和OnPaint()的区别[转]

    问题 问题:我在视图画的图象或者文字,当窗口改变后为什么不见了?OnDraw()和OnPaint()两个都是解决上面的问题,有什么不同? OnDraw()和OnPaint()好象兄弟俩,因为它们的工作 ...

  2. [MFC]MFC中OnDraw与OnPaint的区别

    问题 问题:我在视图画的图象或者文字,当窗口改变后为什么不见了?OnDraw()和OnPaint()两个都是解决上面的问题,有什么不同? OnDraw()和OnPaint()好象兄弟俩,因为它们的工作 ...

  3. onAttachedToWindow () 和 onDetachedFromWindow () ; 以及更新视图的函数ondraw() 和dispatchdraw()的区别

    protected void onAttachedToWindow() This is called when the view is attached to a window. At this po ...

  4. VC++中关于控件重绘函数/消息 OnPaint,OnDraw,OnDrawItem,DrawItem的区别

    而OnPaint()是CWnd的类成员,同时负责响应WM_PAINT消息. OnDraw()是CVIEW的成员函数,并且没有响应消息的功能.这就是为什么你用VC成的程序代码时,在视图类只有OnDraw ...

  5. Onpaint和OnDraw的区别

    (一) OnPaint 和 OnDraw (1)OnPaint是WM_PAINT消息的消息处理函数,在OnPaint中调用OnDraw,一般来说,用户自己的绘图代码应放在OnDraw中. (2)OnP ...

  6. MFC中的Invalidate、OnDraw、OnPaint函数的作用

    MFC中的Invalidate.OnDraw.OnPaint函数的作用 CWnd::Invalidate voidInvalidate( BOOL bErase = TRUE ); 该函数的作用是使 ...

  7. 把OnDraw和OnPaint弄清楚(转贴)

    OnDraw()和OnPaint()兄弟 经常有朋友问雷神这样的问题:我在视图画的图象或者文字,当窗口改变后为什么不见了?OnDraw()和OnPaint()两个都是解决上面的问题,有什么不同? 雷神 ...

  8. MFC常见问题解惑

    MFC类的分类 1 Root: CObject : CObject2 Application Architecture Classes: CWinApp/CFrameWnd/... 3 Window, ...

  9. Win32/MFC的基本概念

    一.MFC的基本概念 单文档.多文档和对话框框架的区别 MFC中的类继承图的基本框架 CView类与CDocument的关系 Onpaint()和Ondraw()的关系 hdc-cdc区别联系 RUN ...

随机推荐

  1. ffmreg thinkphp 控制器 获取音频视频详细信息(获取时长)

    FFmpeg下载:http://ffmpeg.zeranoe.com/builds/ 下载并解压FFmpeg文件夹: 打开你想安装的任意磁盘,例如:d盘.新建一个名为“ffmpeg”的文件夹,将第二步 ...

  2. APSC4xSeries_Ver32.exe在win764位提示缺少DLL错误解决办法

    APSC4xSeries_Ver32.exe在win764位提示缺少DLL错误解决办法 从网上下载oatime_epson-me1清零软件,Stylus4xProgram_Ver32的 解决办法:还是 ...

  3. 大数据学习--day03(运算符、流程控制语句)

    运算符.流程控制语句 自增自减容易出错的地方: 扩展的赋值运算符  a+=b 等同于 a = a+b;  扩展的赋值运算符 隐含了一个类型的强制转换 & && 有何区别   & ...

  4. 5、GDB调试工具的使用

    GDB是GNU发布的一款功能强大的程序调试工具.GDB主要完成下面三个方面的功能: 1.启动被调试程序. 2.让被调试的程序在指定的位置停住. 3.当程序被停住时,可以检查程序状态(如变量值). #i ...

  5. 【NXP开发板应用—智能插排】4. PWM驱动

    [前言] 首先感谢深圳市米尔科技有限公司举办的这次活动并予以本人参加这次活动的机会,以往接触过嵌入式,但那都是皮毛,最多刷个系统之类的,可以说对于嵌入式系统开发这件事情是相当非常陌生的,这次活动为我提 ...

  6. 定义一个大数组时,出现错误,程序进入HardFault_Handler中断

    在原子的串口程序前加了几个数组定义,加了个对数组处理的函数,出现了HardFault_Handler的错误,不知道怎么解决!!! 因为局部变量是存放在栈区的,而全局变量在全局区(静态区),如果栈区较小 ...

  7. ruby配置镜像源

    1.打开电脑的cmd窗口,输入如下命令即可查看gem镜像: gem sources l 或是直接使用 gem sources 查询结果如下: C:\Users\Administrator>gem ...

  8. 【转】Odoo开发之:工作流 workflow

    在OpenERP中,工作流是管理一组“所做的事情”(与一些数据模型的记录关联)的人为现象.工作流提供了高级别的方式来组织记录要上做的事情. 具体地说,工作流是一个定向的路径,这里节点称为活动并且弧线称 ...

  9. 北京Uber优步司机奖励政策(4月1日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  10. 友晶Altera Cyclone V GX Starter Kit开发板使用ADC-第一篇

    1. 拿到板子在,做工很好,属于GX系列,GX应该是高速收发器 2. 去探究下GX是什么用途,大约有6个型号,这个板子是5CGXFX5,有77 LE逻辑单元,这个收发器不知道是什么?6个 3.125G ...