【发布时间】:2026-01-16 10:10:01
【问题描述】:
我有一个用 c++ 开发的 win32 应用程序。该应用程序使用基本形状(矩形)在窗口上绘制一些东西。使用 InvalidateRect 每 20 毫秒(50 赫兹)重新绘制一次窗口。一切正常,但绘图闪烁。我怎样才能防止闪烁?在c#中我通常使用双缓冲组件(例如pictureBox),我怎么能在c++中使用win32摆脱这个?
【问题讨论】:
标签: c++ winapi drawing flicker
我有一个用 c++ 开发的 win32 应用程序。该应用程序使用基本形状(矩形)在窗口上绘制一些东西。使用 InvalidateRect 每 20 毫秒(50 赫兹)重新绘制一次窗口。一切正常,但绘图闪烁。我怎样才能防止闪烁?在c#中我通常使用双缓冲组件(例如pictureBox),我怎么能在c++中使用win32摆脱这个?
【问题讨论】:
标签: c++ winapi drawing flicker
您可以创建一个内存中的设备上下文,将这些形状绘制到其中(就像您绘制窗口的设备上下文一样),然后在窗口无效时从它blit 到窗口的设备上下文。
您还需要在抽签发生之前禁用背景清除(适当地处理 WM_ERASEBKGND 窗口消息)。
编辑:我偶然发现了一个非常详尽的tutorial GDI 中无闪烁绘图,它解释了在 Windows 中绘图的所有方面并附带示例。
【讨论】:
您也可以在 C++ 中使用双缓冲。
当您获得要绘制的 DC 时,您会创建一个屏幕外位图 (CreateCompatibleBitmap) 和一个内存 DC (CreateCompatibleDC)。把你所有的画都交给那个 DC。最后,从内存 DC 到实际 DC 进行 BitBlt。
为了提高性能,您可能希望缓存离屏位图和 DC,但请记住在窗口大小更改时重新创建它们。
【讨论】:
这是我发现的最棒的教程:
https://msdn.microsoft.com/en-us/library/ms969905.aspx
简而言之 - 是的,您必须实现双缓冲。它是通过创建内存中的 DC,然后使用该 DC 将您想要的所有内容绘制到内存中的位图来完成的,然后才将该位图提交给实际的 DC。
【讨论】: