按引:Invalidate在消息队列中加入一条WM_PAINT消息,其无效区为整个客户区。而UpdateWindow直接发送一个WM_PAINT消息,其无效区范围就是消息队列中WM_PAINT消息(最多只有一条)的无效区。效果很明显,调用Invalidate之后,屏幕不一定马上更新,因为WM_PAINT消息不一定在队列头部,而调用UpdateWindow会使WM_PAINT消息马上执行的,绕过了消息队列。如果你调用Invalidate之后想马上更新屏幕,那就加上UpdateWindow()这条语句。

UpdateData():

当你使用了ClassWizard建立了控件和变量之间的联系后:当你修改了变量的值,而希望对话框控件更新显示,就应该在修改变量后调用UpdateData(FALSE);如果你希望知道用户在对话框中到底输入了什么,就应该在访问变量前调用UpdateData(TRUE),将控件的输入映射到变量中。

Invalidate():
     该函数的作用是使整个窗口客户区无效窗口的客户区无效意味着需要重绘。例如,如果一个被其它窗口遮住的窗口变成了前台窗口,那么原来被遮住的部分就是无效的,需要重绘。这时Windows会在应用程序的消息队列中放置WM_PAINT消息。MFC为窗口类提供了WM_PAINT的消息处理函数OnPaint,OnPaint负责重绘窗口。视图类有一些例外,在视图类的OnPaint函数中调用了OnDraw函数,实际的重绘工作由OnDraw来完成。参数bErase为TRUE时,重绘区域内的背景将被擦除,否则,背景将保持不变。

InvalidateRect():
    该函数的功能与Invalidate基本一样,不同的是,它是使指定的某个区域无效,需要输入一个区域,如果参数为NULL,则设置整个窗口为无效区。

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

UpdateWindow:如果有无效区,则马上sending a WM_PAINT message到窗口处理过程,不进消息队列进行排队等待,立即刷新窗口,否则,什么都不做。 
InvalidateRect:设置无效区,如果为NULL参数,则设置整个窗口为无效区。当应用程序的那个窗口的消息队列为空时,则sending a WM_PAINT message(即使更新区域为空).在sending a WM_PAINT message的所有InvalidateRect的更新区域会累加。

1:设置无效区 
InvalidateRect

2:立即刷新 
UpdateWindow()

如果不调用 InvalidateRect就调用 UpdateWindow,那么UpdateWindow什么都不做。 如果调用 InvalidateRect 后不调用UpdateWindow,则系统会自动在窗口消息队列为空的时候,系统自动发送一WM_PAINT消息。

调用UpdateWindow()时将会发送一个WM_PAINT消息,而应用程序在接收到WM_PAINT消息后,将自动地调用Invalidate()。所以,在程序代码中,不一定要出现Invalidate()!

UpdateWindow()就是立即发送WM_PAINT消息,updateWindow要求系统对区域进行立即重绘,其只对声明为无效的区域起作用,而Invalidate()是声明无效区域的方式之一。

Invalidate()表示客户区域无效,在下次WM_PAINT发生时重绘。而WM_PAINT是由系统进行维护的,每当CWnd的更新区域不为空,并且在应用程序的窗口消息队列中没有其它消息时,Windows就发送一条WM_PAINT消息

Invalidat最后也是调用InvalidatRect。

RedrawWindow 强制刷新,会调用WM_PAINT,但如果你强制刷新的部分不存在就不会调用WM_PAINT。若不带任何参数,则本窗口全部刷新。

*****************************************************************************************************************************************

看到有人在网上提出问题,他在Invalidate后面又写了绘图的函数但是没有执行,这是因为invalidate执行过以后就转到PAINT命令了,所以后面的都没有显示。

也终于想通我绘的图一直在闪啊闪,这是因为我在PAINT里面用到了Invalidate()函数,所以他不停的自嵌套,导致绘的图在不停的闪。

总之:Invalidate让客户区处于可以重画的状态,而UpdateWindow开始重画,但是它首先需判断客户区是否为空,不空则UpdateWindow不执行,为空才执行重画。

*********************************************************************************************************************************************

在刷新窗口时经常要调用重绘函数MFC提供了三个函数用于窗口重绘
     InvalidateRect(&Rect)
    Invalidate()
     UpdateWindow()
       当需要更新或者重绘窗口时,一般系统会发出两个消息WM_PAINT(通知客户区有变化)和WM_NCPAINT(通知非客户区有变化)WM_NVPAINT系统会自己搞定WM_PAINT消息对应的函数是OnPaint(),它是系统默认的接受WM_PAINT消息的函数,但我们一般在程序中做重绘时都在OnDraw函数中进行的,因为在视图类ONPAINT函数中调用了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处理函数中使用

OnDraw,一般是收到WM_PAINT消息时调用,所以应用程序一般通过Invalidate产生WM_PAINT消息来间接调用OnDraw。当窗体无效等情况下,window也会产生WM_PAINT消息,这时OnDraw 也被间接调用。 
OnUpdate 是CView提供的一个方法,一般当文档修改时调用,应用程序框架在CView::OnInitialUpdate 和CDocument::UpdateAllViews 的默认实现中都会调用 
OnUpdate,OnUpdate的默认实现是通过Invalidate产生WM_PAINT,这时OnDraw又被调用了。

OnDraw除了你和应用程序框架间接调用外,window还可能间接调用它。 
OnUpdate一般只有你的程序和应用程序框架会调用的。当然它的默认实现你可以改变的

**********************************************************************************************************************

OnInitUpdate是VIEW的初始化 
OnUpdate是文档多视时,响应其它视图的改变 
OnDraw和OnPaint都是绘图。OnPaint调用OnDraw,并且调用OnPrepareDC 
---------------------------------------------------------------

Invalidate() InvalidateRect() 与 UpdateWindow()的更多相关文章

  1. MFC中 Invalidate() , InvalidateRect() , UpdateWindow(), Redrawwindow() 区别

    1. void Invalidate( BOOL bErase = TRUE ); 该函数的作用是使整个窗口客户区无效.窗口的客户区无效意味着需要重绘,例如,如果一个被其它窗口遮住的窗口变成了前台窗口 ...

  2. UpdateData、Invalidate、InvalidateRect和UpdateWindow及RedrawWindow

    Invalidate 在消息队列中加入一条WM_PAINT消息,其无效区为整个客户区. 窗口的客户区无效意味着需要重绘.例如,如果一个被其它窗口遮住的窗口变成了前台窗口,那么原来被遮住的部分就是无效的 ...

  3. InvalidateRect和UpdateWindow

    The UpdateWindow function updates the client area of the specified window by sending a WM_PAINT mess ...

  4. InvalidateRect,invalidate,updatewindow(转)

    InvalidateRect(HWND) 使窗口无效 产生消息WM_PAINT; ValidateRect(HWND)使窗口有效 清除消息队列中的WM_PAINT消息 在编程的时候经常把UpdateD ...

  5. InvalidateRect只是增加重绘区域,在下次WM_PAINT的时候才生效

    emWIN里面的无效重绘和windows很类似. WM_InvalidateArea()和WM_InvalidateRect()只重绘指定的区域,其他区域不会重绘,这样避免了闪烁,重绘发生在下次WM_ ...

  6. InvalidateRect(转)

    ///===================该段是自己总结的一个小结================================= InvalidateRect()函数的作用是设置一个无效区域,并 ...

  7. MFC 刷新失效的Picture控件

    问题描述:如在摄像头显示时,关闭摄像头,此时Picture控件仍然显示最后一帧图像,需要刷新掉,还原Picture控件.或者重复显示两张不同大小的图片时,第二张背景有第一张图片残留. 解决方法1:(最 ...

  8. 重温吕鑫MFC教学视频(一)

    重温吕鑫MFC教学视频(一)1. picture控件的使用,可以显示icon和bitmap2. WM_Create窗口的创建3. 创建的销毁消息及区别WM_SYSCOMMAND WM_CLOSE WM ...

  9. MFC的定时器OnTimer

    本文总结来源出自鸡啄米,感谢鸡啄米.来源:http://www.jizhuomi.com/software/232.html 定时器简介 定时器,可以帮助开发者或者用户定时完成某项任务.在使用定时器时 ...

随机推荐

  1. 为什么重写equals还要重写hashcode

    参考回答: HashMap中,如果要比较key是否相等,要同时使用这两个函数!因为自定义的类的hashcode()方法继承于Object类,其hashcode码为默认的内存地址,这样即便有相同含义的两 ...

  2. jpql简单l查询

    JPQL全称Java Persistence Query Language package com.ytkj.entity; import javax.persistence.*; import ja ...

  3. 搭建RAID5(5块硬盘)过程并模拟一块磁盘损坏情况

    首先:在配置RAID5之前我们先来了解一下它.RAID5,RAID是指独立磁盘冗余阵列,是把相同的数据存储在多个硬盘的不同地方的方法.通过把数据放在多个硬盘上,输入输出操作能以平衡的方式交叠,改良性能 ...

  4. QT的一些小知识

    记录一下前段时间工作中用到的东西,包括开发工具和一些简单的技巧吧.也许对于大家来说耳熟能详了. 最开始学习QT记得是在Ubuntu12.04下用apt命令行的方式安装了QT4.8.4以及QT Crea ...

  5. 程序性能优化之APK大小优化(六)下篇

    阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680 本篇文章将继续从微信资源混淆AndResGuard原理来介绍AP ...

  6. 如何深入理解Java泛型

    一.泛型的作用与定义 1.1泛型的作用 使用泛型能写出更加灵活通用的代码泛型的设计主要参照了C++的模板,旨在能让人写出更加通用化,更加灵活的代码.模板/泛型代码,就好像做雕塑时的模板,有了模板,需要 ...

  7. python-request模块--安装

    Request是python中一个发送http请求的包, pip安装: pip install Requests (==版本号) 如果你没有安装pip那么需要先安装pip,pip是python中基本的 ...

  8. python面试题之docstring是什么?

    Docstring是一种文档字符串,用于解释构造的作用.我们在函数.类或方法中将它放在首位来描述其作用.我们用三个单引号或双引号来声明docstring. >>> def sayhi ...

  9. ArcGis基础——设置图层可选状态

    在ArcMap的图层列表上右键,可以设置“仅本图层可选”. 那么,如何设置回多个或者全部图层可选状态呢? 1.在ArcMap的菜单栏找到 自定义——自定义模式——选择——设置可选图层. 2.将“设置可 ...

  10. JS对象 屏幕分辨率的高和宽 window.screen 对象包含有关用户屏幕的信息。 1. screen.height 返回屏幕分辨率的高 2. screen.width 返回屏幕分辨率的宽

    屏幕分辨率的高和宽 window.screen 对象包含有关用户屏幕的信息. 1. screen.height 返回屏幕分辨率的高 2. screen.width 返回屏幕分辨率的宽 注意: 1.单位 ...