原文网址:http://www.cnblogs.com/x8023z/archive/2008/12/09/mfc33.html

在刷新窗口时经常要调用重绘函数
MFC提供了三个函数用于窗口重绘
InvalidateRect(&Rect)
Invalidate()
UpdateWindow()
当需要更新或者重绘窗口时,一般系统会发出两个消息WM_PAINT(通知客户区有变化)和WM_NCPAINT(通知非客户区有变化)
--WM_NVPAINT系统会自己搞定
--WM_PAINT消息对应的函数是OnPaint(),它是系统默认的接受WM_PAINT消息的函数,但我们一般在程序中做重绘时都在OnDraw函数中进行的,因为在ONPAIN函数中调用了ONDRAW函数。
///CView默认的标准的重画函数
void CView::OnPaint()
{
   CPaintDC dc(this);
    OnPreparDC(&dc);
    OnDraw(&dc); //调用了OnDraw
}

上面讲到
InvalidateRect(&Rect)
Invalidate()两个函数形式和功能差不多,但Invalidate是使得整个窗口无效,形成无效矩形,而InvalidateRect(&Rect)是使得指定的区域无效。
Invalidate()申明无效,等待WM_PAINT消息以便重绘,队列中无其他消息时系统会自动发送
UpdateWindow()会立即发送WM_PAINT,不过在它发送前,先调用GetUpdateRect(hWnd,NULL,TRUE)看有无可绘制区域,如果没有则不发送消息RedrawWindow()RedrawWindow()则是具有Invalidate()和UpdateWindow()的双特性。声明窗口的状态为无效,并立即更新窗口,立即调用WM_PAINT消息处理。
 
      系统为什么不在调用Invalidate时发送WM_PAINT消息呢?又为什么非要等应用消息队列为空时才发送WM_PAINT消息呢?这是因为系统把在窗口中的绘制操作当作一种低优先级的操作,于是尽可能地推后做。不过这样也有利于提高绘制的效率:两个WM_PAINT消息之间通过InvalidateRect和InvaliateRgn使之失效的区域就会被累加起来,然后在一个WM_PAINT消息中一次得到 更新,不仅能避免多次重复地更新同一区域,也优化了应用的更新操作。像这种通过InvalidateRect和InvalidateRgn来使窗口区域无效,依赖于系统。在合适的时机发送WM_PAINT消息的机 制实际上是一种异步工作方式,也就是说,在无效化窗口区域和发送WM_PAINT消息之间是有延迟的;有时候这种延迟并不是我们希望的,这时我们当然可以在无效化窗口区域后利用SendMessage 发送一条WM_PAINT消息来强制立即重画,但不如使用Windows GDI为我们提供的更方便和强大的函数:UpdateWindow和RedrawWindow。UpdateWindow会检查窗口的Update Region,当其不为空时才发送WM_PAINT消息;RedrawWindow则给我们更多的控制:是否重画非客户区和背景,是否总是发送WM_PAINT消息而不管Update Region是否为空等。
BeginPaint和WM_PAINT消息紧密相关。试一试在WM_PAINT处理函数中不写BeginPaint会怎样?程序会像进入了一个死循环一样达到惊人的CPU占用率,你会发现程序总在处理一个接 一个的WM_PAINT消息。这是因为在通常情况下,当应用收到WM_PAINT消息时,窗口的Update Region都是非空的(如果为空就不需要发送WM_PAINT消息了),BeginPaint的一个作用就是把该Update Region置为空,这样如果不调用BeginPaint,窗口的Update Region就一直不为空,如前所述,系统就会一直发送WM_PAINT消息。
BeginPaint和WM_ERASEBKGND消息也有关系。当窗口的Update Region被标志为需要擦除背景时,BeginPaint会发送WM_ERASEBKGND消息来重画背景,同时在其返回信息里有一个标志表明窗口背景是否被重画过。当我们用InvalidateRect和InvalidateRgn来把指定区域加到Update Region中时,可以设置该区域是否需要被擦除背景,这样下一个BeginPaint就知道是否需要发送WM_ERASEBKGND消息了。
 
另外要注意的一点是,BeginPaint只能在WM_PAINT处理函数中使用。
 
以下是Invalidate函数的作用::
void Invalidate( BOOL bErase = TRUE ); 
该函数的作用是使整个窗口客户区无效。窗口的客户区无效意味着需要重绘,例如,如果一个被其它窗口遮住的窗口变成了前台窗口,那么原来被遮住的部分就是无效的,需要重绘。这时Windows会在应用程序的消息队列中放置WM_PAINT消息。MFC为窗口类提供了WM_PAINT的消息处理函数OnPaint,OnPaint负责重绘窗口。视图类有一些例外,在视图类的OnPaint函数中调用了OnDraw函数,实际的重绘工作由OnDraw来完成。参数bErase为TRUE时,重绘区域内的背景将被擦除,否则,背景将保持不变。

和 UpdateWindow( )区别在于:UpdateWindow( )的作用是使窗口立即重绘。调用Invalidate等函数后窗口不会立即重绘,这是由于WM_PAINT消息的优先级很低,它需要等消息队列中的其它消息发送完后才能被处理。调用UpdateWindow函数可使WM_PAINT被直接发送到目标窗口,从而导致窗口立即重绘.

希望对有需要的人有用。。。。仅供参考!!有不对之处,请给位在评论中指出!谢谢。。。。

【转】VC的MFC中重绘函数的使用总结(整理)的更多相关文章

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

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

  2. MFC重绘函数:InvalidateRect(), Invalidate()和UpdateWindow()

    1. 重绘消息 当需要更新或者重绘窗口时,一般系统会发出两个消息WM_PAINT(通知客户区有变化)和WM_NCPAINT(通知非客户区有变化) WM_NCPAINT系统会自己搞定 WM_PAINT消 ...

  3. 【VS开发】MFC中调用C函数模块的解决方案

    [VS开发]MFC中调用C函数模块的解决方案 标签(空格分隔): [VS开发] 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:最近调试基于MFC的程序 ...

  4. 在WPF窗体中重绘

    原文:在WPF窗体中重绘   写这篇主要是为了验证任何元素自身都具备绘图功能. 在默认Window中重写OnRender方法 protected override void OnRender(Draw ...

  5. 上传图片时,使用GDI+中重绘方式将CMYK图片转为RGB图片

    原文:上传图片时,使用GDI+中重绘方式将CMYK图片转为RGB图片 我们知道,如果网站上传图片时,如果用户上传的是CMYK图片,那么在网站上将是无法显示的,通常的现象是出现一个红叉.下面使用将Ima ...

  6. MFC窗口重绘

    Invalidate()与 UpdateAllViews()有什么分别 Invalidate()是让程序重画窗口. UpdateAllViews()是在DOC/VIEW结构中, 当一个视图的数据改变后 ...

  7. MFC 窗口重绘问题

    在客户区画直线等图形时, 发现当其最小化或者其他窗口遮挡时,出现窗口重绘,而将原来绘制的图形删除,上网上搜索知道,绘制图形的代码必须放置在Ondraw函数中,才能避免重绘时图形消失(因为一直在响应WM ...

  8. vc++图像保存,重绘

    新建mfc应用程序,单文档 增加绘图 分别增加命令响应 添加成员变量UINIT 图形可以运行,如何保存呢?(一个集合类,CPtArt) 用一个类的对象来保存一个图形的三个要素 所以插入一个新的类(通常 ...

  9. VC、MFC中设置控件的背景色、标题、字体颜色、字体要注意的地方[转]

    在MFC中设置控件的背景色.字体.字体颜色.标题等属性主要是利用OnCtlColor函数来实现. 如: HBRUSH CAlarm::OnCtlColor(CDC* pDC, CWnd* pWnd, ...

随机推荐

  1. Gym 100187A-Potion of Immortality

    题意:有n个药瓶,里面有一个有毒,然后每次拿兔子去试吃k瓶并且只能是k瓶,如果兔子死了就知道那瓶是毒药了,现在问你最少兔子要试吃几次. 分析:这题卡了好久,其实很简单.先考虑肯定要吃n/k次,那么剩下 ...

  2. IE8下网页中的视频会遮挡住顶层DIV的解决办法

    在IE8浏览器下,发现网页中的视频会遮挡住本来固定在最顶层的DIV.即便使用z-index也无法解决.但是其他浏览器是正常的. 解决的办法很简单,就是在调用flash视频播放器的时候,加上一个参数“o ...

  3. java web 中的转发和重定向

    假设应用程序的 contextPath 为 /ctx,在 http://localhost:8080/ctx/a/b 资源中,我们转发和重定向到 http://localhost:8080/ctx/x ...

  4. github上建站和使用markdown写文章

    积累了那么久,终于成功搭建了github上的个人网站.虽然方法有点巧妙.不是还是建成了 同时学会用markdown写基本的文章.感觉还可以.附带我的github上的静态页面网站的网址:http://z ...

  5. CI框架篇之模型篇--初识(1)

    模型 模型是专门用来和数据库打交道的PHP类.例如,假设你想用CodeIgniter来做一个Blog. 你可以写一个模型类,里面包含插入.更新.删除Blog数据的方法. 下面的例子将向你展示一个普通的 ...

  6. 多线程与Socket编程

    一.死锁 定义: 指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁 ...

  7. CALayer 认识

    一篇很好的讲述calayer的博客 http://www.cnblogs.com/kenshincui/p/3972100.html

  8. Object-C内存管理基础

    如果你通过手工alloc的方式分配内存实例化创建一个对象,之后你需要release这个对象,同理你也不能手工释放(release)一个能自动释放(autoreleased)的对象,因为这个样子会使你的 ...

  9. Photon引擎开发实战(1)——Photon 简介

    Photon简介 Photon是一套使用广泛的socket server引擎,服务端底层C++编写,客户端C#编写,跨多平台,收费,效率可观的一款引擎.实用上前有九城游戏(原魔兽世界代理),现在笔者发 ...

  10. gem install 出现Errno::ECONNRESET: Connection reset by peer - SSL_connect (https://ruby.taobao.org

    这几天在ubuntu14.04.1 64位上安装rails的时候,由于大天朝的原因,更换了淘宝源,然后执行 gem install rails 这个时候,总是会提示 Errno::ECONNRESET ...