【问题标题】:How to use double buffer in this case?在这种情况下如何使用双缓冲?
【发布时间】:2009-09-27 11:04:28
【问题描述】:

假设我有三个控件A,B,C。它们都继承自CDialog, A 是一个主对话框,A 包含 B,B 包含 C。 而且每次我用鼠标拖动C,B和C都会一起移动。

这是一张图片:http://img507.imageshack.us/img507/7039/31709956.jpg

我们知道这会导致 B 和 C 重新绘制自己。并且可能会导致闪烁。

我的问题是是否有一种方法可以对这两个对话框 B 和 C 进行双重缓冲?

我知道在 XP 和 vista 中,有一个属性 WS_EX_COMPOSITED 会有所帮助,但我不想使用它。

可能有人建议我使用 memDC,但我的问题是如何将 B 的 ondraw 和 C 的 ondraw 函数中的动作合并到缓冲区中?

希望有人知道我说了什么。

提前致谢!

【问题讨论】:

  • 当您说:对话框...您的意思是它们是单独的窗口吗? (所以 CDialog?)
  • 是的,所有的对话框都继承自CDialog~

标签: c++ visual-c++ mfc doublebuffered


【解决方案1】:

对闪烁有很大帮助的是重载erasebackground 方法。此方法用纯色填充整个背景。油漆比油漆上面的所有物品。通过删除erasebackground,绘画只会在已经存在的东西上绘画,从而消除闪烁。

【讨论】:

  • 但我的问题是如何将 B 的 ondraw 和 C 的 ondraw 函数中的动作合并到缓冲区中?假设当我拖动C时,B和C将被重绘,顺序是B先绘制然后C,它是在它们自己的ondraw函数中完成的,我想将它们双重缓冲成位图,然后将其绘制在上面A. 但我不知道该怎么做。
  • 我无法想象能够使用 1 个屏幕外位图重绘 2 个单独的窗口。为此,您需要对话框不是单独的窗口。
  • 嗨...我刚看到你的测试图片。对话框真的完全由您绘制吗(所以没有控件?)在这种情况下,为什么要完全使用 CDialog 而不是自己直接在主窗口上绘制它们,从而消除所有闪烁
  • 因为我将在子对话框 C 上添加一些事件处理程序,例如拖放
  • WS_EX_COMPOSITED ,该属性可以将它的所有子元素缓冲到缓冲区中,然后绘制它。但我不想用这个....
【解决方案2】:

CS_PARENTDC 会有所帮助。

【讨论】:

    【解决方案3】:

    我自己从来没有搞过双缓冲 Windows 的绘图调用,但我曾经在 Microsoft 论坛上遇到过关于它的讨论:http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/789a4116-d3b2-488e-801a-3f7bc1e4d33a/ 也许这可能对你有帮助。

    【讨论】:

      【解决方案4】:

      假设 B 和 C 是 A 的子级(对话框的常见情况),A 应该具有 WS_CLIPCHILDREN 样式集。如果 B 和 C 是 A 的兄弟姐妹,则设置 A 的 WS_CLIPSIBLINGS 位。

      【讨论】:

        【解决方案5】:

        主对话框 A 使用一个 MemDC,B 和 C 使用组合 MemDC。 现在当你拖动 C 时,你应该根据当前位置组合这 2 个 MemDC 通过使用 BitBlt 函数,最后你必须在对话框的实际 DC 上执行组合 memDC 的 bitblt。

        除此之外,您还必须覆盖 onerasebackground 方法,因此不会出现闪烁。

        【讨论】:

          猜你喜欢
          • 2015-10-12
          • 1970-01-01
          • 2022-01-23
          • 2015-11-30
          • 2017-05-16
          • 2012-10-06
          • 2011-05-18
          • 2019-11-29
          • 2022-01-23
          相关资源
          最近更新 更多