C 和 Windows GDI 中的双缓冲 *framework*

Posted

技术标签:

【中文标题】C 和 Windows GDI 中的双缓冲 *framework*【英文标题】:Double-buffering *framework* in C and Windows GDI 【发布时间】:2013-05-07 17:40:26 【问题描述】:

背景:我的客户有一个非常广泛的专有表单库,它在 C 中有效实现(实际上,它是一种专有的面向对象语言,基本上包装了 Windows 控件并与它们进行交互 SendMessage()SetStyle()等)

我要解决的问题:每当我在上述框架中实现的应用程序中拖动/调整***窗口(或拖动拆分器)时,都会出现大量闪烁。顶层窗口被重绘,并且它包含的任何控件都被重绘。

问题 1:有没有办法通过手术将双缓冲引入表单库。特别是,我想知道我是否可以使用标准的 Windows GDI 函数实现双缓冲。

对于示例,如果我可以使顶层窗口被双缓冲,这样顶层窗口的所有子窗口也被自动绘制成双缓冲。一个更好的选择是能够在任意窗口上引入双缓冲,并让它的所有子窗口都继承它。

最好的解决方案会以某种方式导致子控件的BeginPaint() 函数将句柄返回到屏幕外后台缓冲区的 DC,这样我就不必为每个单独的控件类编写特殊代码。

问题 2:有没有办法(例如一组标志)使通用 Windows 控件(EDIT、BUTTON 等)以双缓冲方式绘制自身?这将是一个比更通用的方法更糟糕的解决方案,后者只会无缝地为他们提供后台缓冲区以供他们使用,但它也可能是可以接受的。

非常感谢所有帮助。如果我可以为您澄清任何事情,请告诉我。

【问题讨论】:

【参考方案1】:

查看WS_EX_COMPOSITED,这是一种扩展的窗口样式,可以为窗口打开双缓冲。在控件的父级上设置此样式可能就足够了。

【讨论】:

我一定会调查的——这可能正是我需要的。谢谢! 非常感谢。 WS_EX_COMPOSITED 适用于子窗口。但我还必须对弹出窗口(样式为 WS_POPUP 的窗口)使用 WS_CLIPSIBLINGS|WS_CLIPCHILDREN 以避免闪烁。请注意,以上不是扩展样式,而是常规样式。【参考方案2】:

实际上,您可以使用执行 C# 的 C 来包装所有窗口绘图代码,这样就已经为您提供了双缓冲实现。

How to eliminate flicker in Windows.Forms custom control when scrolling?

【讨论】:

以上是关于C 和 Windows GDI 中的双缓冲 *framework*的主要内容,如果未能解决你的问题,请参考以下文章

从内存创建 Windows GDI 位图

C++ 中的 GDI+ 双缓冲

暂时禁用Java图形小程序中的双缓冲

applet 中的双缓冲是如何工作的?

c# GDI和winforms中的径向渐变画笔效果

消费者生产者模型中的双缓冲 OpenGL 对象