onpaint onprint ondraw区别

转载 2012年03月23日 14:12:08

对于窗口程序,一般有个特点:窗口大部分的区域保持不变,只有不分区域需要重新绘制。如果将整个窗口全部刷新的画,就做了许多不必要的工作,因而,MFC采用了一套基于无效区的处理机制。在分析无效区处理之前,我们要明白一个现实,现在的机器还不够牛,如果够牛的话,我们干脆将整个窗口不断的重新绘制好了。事实上即使够牛也不行,对于一个单线程程序,通过一个while循环不断的刷新窗口,程序也无法相应其他消息(除非使用多线程),看来使用无效区的处理机制还是有其必然性的。
    VC程序是基于消息机制的,你所做的任何操作,比如点击鼠标,拖动窗口,首先进入系统的消息队列。这里的系统消息队列包括多个程序的消息,系统再将消息发送给相应的程序。既然是队列,这就有一个先进先出的问题,屏幕上的无效区更新消息出现的频率就会特别高。比如当左上角更新的消息还没有处理,右下角更新的消息已经过来了。为了避免多次处理WM_PAINT消息,系统就将这些窗口更新消息合并到一条,只是将无效区范围变成包括这两次更新无效区范围在内的矩形区域。这样就减少了WM_PAINT消息的处理次数,提高了效率。

    那么,在OnPaint消息处理函数中,又是怎样实现更新无效区的呢?首先,要明白MFC中所有绘图操作都是基于设备描述表(Device Context,简称DC)的,具体信息可参看任何一本VC教材。DC中包含了绘图设备的各种信息,对于屏幕绘图,其实就是有一块内存(显存),专门用来存放要显示到屏幕上的信息,显示器以85HZ的频率(我以前的显示器)将其内容刷新的屏幕上。这里就到了关键点,显示器的刷新是将显存中的内容完全更新到显示器上,不存在无效区处理的问题,那么,无效区的处理一定发生在DC的绘图处理上。事实确实如此,当程序调用OnPaint消息时,首先将无效区范围传递给DC,DC在进行绘图操作时,就只更新无效区范围内的信息,其他地方的不管,这就提高了效率。

    现在你明白OnPaint的处理是怎么一回事了吧?这里还想说一下Invalidate和UpdateWindow的区别。Invalidate在消息队列中加入一条WM_PAINT消息,其无效区为整个客户区。而UpdateWindow直接发送一个WM_PAINT消息,其无效区范围就是消息队列中WM_PAINT消息(最多只有一条)的无效区。效果很明显,调用Invalidate之后,屏幕不一定马上更新,因为WM_PAINT消息不一定在队列头部,而调用UpdateWindow会使WM_PAINT消息马上执行的,绕过了消息队列。如果你调用Invalidate之后想马上更新屏幕,那就加上UpdateWindow()这条语句。
 


OnPaint()与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()。

MFC——Onpaint和OnDraw的区别

OnPaint是WM_PAINT消息的消息处理函数,在OnPaint中调用 OnDraw,一般来说,用户自己的绘图代码应放在OnDraw中。 OnPaint()是CWnd的类成员,负责响应WM_...
  • perfectguyipeng
  • perfectguyipeng
  • 2017年12月08日 09:17
  • 57

Onpaint和OnDraw的区别[转]

OnPaint是WM_PAINT消息的消息处理函数,在OnPaint中调用OnDraw,一般来说,用户自己的绘图代码应放在OnDraw中。 OnPaint()是CWnd的类成员,负责响应WM_PAI...
  • FlowShell
  • FlowShell
  • 2015年02月10日 15:35
  • 513

OnDraw与OnPaint有什么区别?

学习中遇到一个问题, 学习中遇到一个问题,OnDraw与OnPaint有什么区别?上网搜索了一下,又查了一下MSDN和MFC的一些源文件,现整理如下。 OnPaint是WM_PAINT消息的消...
  • zafzap1
  • zafzap1
  • 2013年04月23日 18:15
  • 223

C++ OnDraw()和OnPaint() 之间有什么关系

OnDraw()和OnPaint()好象兄弟俩,因为它们的工作类似。 至于不见了的问题简单,因为当你的窗口改变后,会产生无效区域,这个无效的区域需要重画。一般Windows回发送两个消息WM_PAI...
  • oket007
  • oket007
  • 2014年02月07日 14:01
  • 1003

OnDraw与OnPaint有什么区别?

OnDraw与OnPaint有什么区别?(转) OnPaint是WM_PAINT消息的消息处理函数,在OnPaint中调用OnDraw,一般来说,用户自己的绘图代码应放在OnDraw中。 ...
  • cosmoslife
  • cosmoslife
  • 2013年03月23日 11:02
  • 364

MFC中的OnDraw和OnPaint的对比

学习中遇到一个问题,OnDraw与OnPaint有什么区别?上网搜索了一下,又查了一下MSDN和MFC的一些源文件,现整理如下。 OnPaint是WM_PAINT消息的消息处理函数,在OnPai...
  • cai_huan_123
  • cai_huan_123
  • 2013年12月30日 09:19
  • 649

把OnDraw和OnPaint弄清楚(转贴)

以下为转贴: OnDraw()和OnPaint()兄弟 经常有朋友问雷神这样的问题: 我在视图画的图象或者文字,当窗口改变后为什么不见了? OnDraw()和OnPaint()两个都是...
  • qq920020796
  • qq920020796
  • 2015年11月06日 15:06
  • 205

MFC中的OnDraw和OnPaint的对比

学习中遇到一个问题,OnDraw与OnPaint有什么区别?上网搜索了一下,又查了一下MSDN和MFC的一些源文件,现整理如下。 OnPaint是WM_PAINT消息的消息处理函数,在OnPai...
  • yu_gi_oh
  • yu_gi_oh
  • 2013年04月09日 22:16
  • 549

MFC中的OnDraw和OnPaint的对比

学习中遇到一个问题,OnDraw与OnPaint有什么区别?上网搜索了一下,又查了一下MSDN和MFC的一些源文件,现整理如下。 OnPaint是WM_PAINT消息的消息处理函数,在OnPai...
  • u012377333
  • u012377333
  • 2014年11月04日 19:16
  • 787

OnDraw函数和OnPaint函数

OnDraw()和OnPaint()兄弟 经常有朋友问这样的问题: 我在视图画的图象或者文字,当窗口改变后为什么不见了? OnDraw()和OnPaint()两个都是解决上面的问题,有什么不同? ...
  • honghui91
  • honghui91
  • 2014年07月28日 11:26
  • 418
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:onpaint onprint ondraw区别
举报原因:
原因补充:

(最多只允许输入30个字)