【问题标题】:Why validating/invalidating the area is used?为什么使用验证/无效区域?
【发布时间】:2015-09-08 01:08:18
【问题描述】:

当窗口的一部分需要重新绘制时,该区域被标记为无效,当我重新绘制该区域时(在WM_PAINT事件处理程序中),我应该将该区域标记为有效。

但我不明白需要将该区域标记为无效然后再对其进行验证,我的意思是为什么不直接执行以下操作:当需要重新绘制区域时,只需发送 WM_PAINT 消息(不将该区域标记为无效),然后重新绘制该区域(不将其标记为有效)。

【问题讨论】:

标签: c winapi


【解决方案1】:

想象一下有人在栅栏上扔球。当球击中栅栏时,你会重新粉刷栅栏吗?不,当且仅当自上次重新粉刷后有球击中围栏时,您才重新粉刷围栏。

您建议任何时候将一个区域标记为无效,而是应向应用程序发送WM_PAINT 消息。这样做的最大问题是,如果同一区域多次失效,则会导致发送许多 WM_PAINT 消息,并且无法知道其中许多消息已被处理。因此,在您最需要高性能的时候(因为您在绘图方面落后),您必须一遍又一遍地重复相同的绘图操作。这没有意义。

【讨论】:

  • 所以第一次某个区域需要重绘时,将其标记为无效,然后如果同一区域需要重绘,windows会检查是否无效,如果是, Windows 什么都不做。并且当该区域被重绘并标记为有效,并且该区域需要再次重绘时,它再次被标记为无效。因此,与其发送例如数百条WM_PAINT 消息,不如只发送一条。这是正确的吗?
  • @Tony 非常接近。 Windows 实际上会检查应用程序的消息队列何时为空。
  • 您是在谈论 Windows 何时发送WM_PAINT 消息吗? (即消息队列为空时)
  • @Tony 没错。如果区域失效时队列为空,则立即发送消息。否则,将延迟到队列为空。
  • 您的答案缺少两个关键细节:WM_PAINT 是一条低优先级消息,对InvalidateRect/InvalidateRgn 的多次调用被合并到一个更新区域中。
【解决方案2】:

将一个区域标记为INVALID 让Windows 知道它需要更新。这是为了允许对屏幕进行部分绘制,而不是每次都完全更新绘制区域。

最好只使大多数静态程序中的更改区域无效以减少绘制开销。

在绘制完成后验证它们让窗口知道该区域已被刷新并且不需要再次重绘。

当您有以下类型的窗口时,这将是一个有用的示例:

滚动列表框或勾选复选框时,最好只使窗口的该区域无效以进行重绘,而不是在每次需要更新列表框或复选框以显示新滚动时重绘整个窗口位置或复选标记。

【讨论】:

    猜你喜欢
    • 2012-03-26
    • 2019-11-21
    • 1970-01-01
    • 2013-08-11
    • 1970-01-01
    • 2012-06-28
    • 1970-01-01
    • 2017-08-28
    • 2021-02-02
    相关资源
    最近更新 更多