MFC中窗口重绘

摘自:http://blog.csdn.net/shuilan0066/article/details/5859057

在刷新窗口时经常要调用重绘函数

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的一个作用就是把该UpdateRegion置为空,这样如果不调用BeginPaint,窗口的Update Region就一直不为空,如前所述,系统就会一直发送WM_PAINT消息。
 
       BeginPaint和WM_ERASEBKGND消息也有关系。当窗口的Update Region被标志为需要擦除背景时,BeginPaint会发送WM_ERASEBKGND消息来重画背景,同时在其返回信息里有一个标志表明窗口背景是否被重画过。当我们用InvalidateRect和InvalidateRgn来把指定区域加到Update Region中时,可以设置该区域是否需要被擦除背景,这样下一个BeginPaint就知道是否需要WM_ERASEBKGND消息了。
      另外要注意的一点是,BeginPaint只能在WM_PAINT处理函数中使用。

【MFC】MFC中窗口重绘的更多相关文章

  1. MFC中窗口重绘

    搬家于CSDN 2015-05-14 MFC提供了三个函数用于窗口重绘 InvalidateRect(&Rect) Invalidate() UpdateWindow() 当需要更新或者重绘窗 ...

  2. MFC 窗口重绘问题

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

  3. uCGUI窗口重绘代码分析

    一.概述 µC/GUI的窗口重绘是学习者理解窗口工作原理和应用窗口操作的重点.µC/GUI的窗口重绘引入了回调机制,回调机制可以实现图形系统调用用户的代码,由于图形系统使用了剪切算法,使得屏幕重绘的效 ...

  4. WM_PAINT消息在窗口重绘的时候产生,那什么时候窗口会重绘(异步工作方式效率高、灵活性强,还有UpdateWindow和RedrawWindow帮忙)

    Q:wm_paint消息在窗口重绘的时候产生,那什么时候窗口会重绘?? A: 严格地说,只有当收到WM_PAINT消息后窗口会重绘 但是引起这个消息的事件有很多, 比如:1.首次创建 2.移动 3.改 ...

  5. MFC窗口重绘

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

  6. MFC 滑动条的重绘

    MFC自带的滑动条的样子是这样的. 比较难看,所以需要重绘下,重绘后的样子是这样的. 代码如下: CustomSliderCtr.h #pragma once // CCustomSliderCtr ...

  7. IOS中对图片进行重绘处理的方法总结

    一.CGImageRef是什么 CGImageRef是定义在QuartzCore框架中的一个结构体指针,用C语言编写.在CGImage.h文件中,我们可以看到下面的定义: ? 1 typedef st ...

  8. java中的重绘

    void java.awt.Container.validate()Validates this container and all of its subcomponents.这个函数更新容器及其全部 ...

  9. WinForm中的重绘 - 按钮等控件的背景渐变色重绘

    注:brush通过起止坐标来控制重绘范围及方向.比如从上到下渐变时,brush第二个Point参数是左下角坐标. private void PaintGradientBackground(Button ...

随机推荐

  1. cdoj1344卿学姐种美丽的花

    地址:http://acm.uestc.edu.cn/#/problem/show/1344 题目: 卿学姐种美丽的花 Time Limit: 8000/4000MS (Java/Others)    ...

  2. Keepalived 服务器状态监测

    keepalived简介: keepalived是一个类似于layer3, 4 & 5交换机制的软件,也就是我们平时说的第3层.第4层和第5层交换.Keepalived的作用是检测web服务器 ...

  3. 格式化字符串--format用法

    print("hello {leon}".format(leon="world!")) #format 是一个格式化字符穿的方法. print("he ...

  4. 理解 $nextTick 的作用

    有同学在看 Vue 官方文档时,对 API 文档中的 Vue.nextTick 和 vm.$nextTick 的作用不太理解. 其实如果看一下深入响应式原理 - vue.js中的有关内容,可能会有所理 ...

  5. 菜单Menu

    <Menu HorizontalAlignment="> <MenuItem Header="文件"> <MenuItem Header=& ...

  6. 2018-2019-2 20165114《网络对抗技术》Exp5 MSF基础应用

    Exp5 MSF基础应用 目录 一.实验目标 二.基础问题回答 三.实验过程记录 3.1主动攻击实践 ms08_067+generic/shell reverse_tcp ms17_010_etern ...

  7. python之模块导入和重载

    模块导入和重载 模块导入通过import语句实现,但是在同一次会话中只运行一次. 若想要再次运行文件,调用imp标准库中的reload函数: >>> from imp import ...

  8. QString类

    1.将QString所有字母大写 QString.toUpper() 2.将QString所有字母小写 QString.toLower() 3.获取字符串的字符数 QString.length() 4 ...

  9. 广度优先搜索 BFS算法

    广度优先搜索算法(Breadth-First-Search,BFS),又称作宽度优先搜索.BFS算法是从根节点开始,沿着树的宽度遍历树的节点.如果所有节点均被访问,则算法中止. 算法思想 1.首先将根 ...

  10. react native 中的ReadableMap和WritableMap的使用

    react native跟安卓原生交互的数据类型中,有两个比较陌生的类型,ReadableMap和WritableMap. ReadableMap和WritableMap,顾名思义,反正是map. W ...