绘图不闪烁

问题描述 投票:0回答:4

我有一个用 C++ 开发的 win32 应用程序。该应用程序使用基本形状(矩形)在窗口上绘制一些内容。使用 InvalidateRect 每 20 毫秒 (50hz) 重新绘制一次窗口。一切正常,但绘图闪烁。如何防止闪烁?在c#中,我通常使用双缓冲组件(例如pictureBox),我如何在使用win32的c++中摆脱它?

c++ winapi drawing flicker
4个回答
7
投票

您可以创建一个内存中的设备上下文,将这些形状绘制到其中(就像绘制窗口的设备上下文一样),然后在窗口失效时从它传输到窗口的设备上下文。

您还需要在绘制发生之前禁用背景清除(适当处理 WM_ERASEBKGND 窗口消息)。

编辑:我偶然发现了一个关于 GDI 中无闪烁绘图的相当详尽的教程,它解释了在 Windows 中绘图的各个方面并附带了示例。


5
投票

您也可以轻松地在 Win32 中实现双缓冲。假设您正在使用其设备上下文直接在窗口上进行绘画,请改为执行以下操作:

创建一个“内存”设备上下文并在该设备上下文上进行所有绘图,然后在适当的时候使用

BitBlt()
函数将窗口的无效部分复制到实际设备上下文中

这里有一个相当不错(尽管水平较高)的概述。


3
投票
您也可以在 C++ 中使用双缓冲。

当您获得要绘制的 DC 时,您将创建一个离屏位图 (CreateCompatibleBitmap) 和一个内存 DC (CreateCompatibleDC)。在那个 DC 上完成所有的绘画。最后,从内存 DC 到实际 DC 进行 BitBlt。

为了性能,您可能想要缓存离屏位图和 DC,但请记住在窗口大小更改时重新创建它们。


2
投票
这是我发现的最好的教程:

https://msdn.microsoft.com/en-us/library/ms969905.aspx

简而言之 - 是的,你必须实现双缓冲。这是通过创建内存 DC,然后使用该 DC 将您想要的所有内容绘制到内存位图,然后将此位图提交到实际 DC 来完成的。

© www.soinside.com 2019 - 2024. All rights reserved.