zoukankan      html  css  js  c++  java
  • WM_Paint 消息详解

    1. 系统何时发送WM_PAINT消息?
       系统会在多个不同的时机发送 WM_PAINT 消息:当第一次创建一个窗口时,当改变窗口的大小时,当把窗口从另一个

    窗口背后移出时,当最大化或最小化窗口时,等等,这些动作都是由 系统管理的,应用只是被动地接收该消息,在消息处理函数中进行绘制操作;大多数的时候应用也需要能够主动引发窗口中的绘制操作,比如当窗口显示的数据改变 的时候,这一般是通过 InvalidateRect 和 InvalidateRgn 函数来完成的。


        InvalidateRect 和 InvalidateRgn把指定的区域加到窗口的 Update Region 中,当应用的消息队列没有其他

    消息时,如果窗口的 Update Region 不为空时,系统就会自动产生 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 是否为空等。

    --------------------------------------------------------------------------------


    2. BeginPaint
       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 处理函数中使用。


    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/sdn_009/archive/2008/11/13/3292133.aspx

  • 相关阅读:
    AcWing 1027. 方格取数 dp
    AcWing 1014. 登山 dp
    acwing 482. 合唱队形 dp
    LeetCode 1463. 摘樱桃II dp
    LeetCode 100. 相同的树 树的遍历
    LeetCode 336. 回文对 哈希
    LeetCode 815. 公交路线 最短路 哈希
    算法问题实战策略 DARPA大挑战 二分
    算法问题实战策略 LUNCHBOX 贪心
    AcWing 1100. 抓住那头牛 BFS
  • 原文地址:https://www.cnblogs.com/chengxin1982/p/1542660.html
Copyright © 2011-2022 走看看