WinAPI - 避免重绘窗口

时间:2011-09-21 14:47:32

标签: c++ windows winapi

我使用SetPixel() - 函数进入WinAPI窗口。

如果我缩放窗口或失去焦点(另一个窗口在顶部),我会丢失我在窗口中绘制的所有内容。

我刚用过

RECT rc;
GetClientRect(hwnd, &rc);
RedrawWindow(hwnd, &rc, NULL, RDW_NOERASE | RDW_NOFRAME | RDW_VALIDATE);

这有助于避免在移动窗口时重新绘制内容,但缩放和丢失焦点仍会删除内容。 有没有人知道我错过了什么?

5 个答案:

答案 0 :(得分:6)

将其绘制到缓冲区/位图,然后将其绘制到窗口。

答案 1 :(得分:3)

当需要重新绘制窗口时,将发送WM_PAINT消息。此时,您必须重绘所有窗口,或至少包含在剪切区域内的所有窗口。 Windows会进行一些缓冲和自动绘制,特别是它会重新绘制窗口的某些部分,这些窗口被其他窗口覆盖,然后被覆盖。一旦窗口被调整大小,或者(可能)无效,你就可以自己动手了。

正如@daniel建议的那样,如果绘画是一个密集的过程,并且您不想每次需要重新绘制时都这样做,请将您的内容渲染成位图(在这种情况下将是一个屏幕外缓冲区)并且根据需要将BitBlt(复制)到窗口中。

获取Charles Petzold的书“Programming Windows”的副本,以获取有关如何进行绘画的信息。如果您正在编写WinAPI应用程序但使用过SetPixel,我建议您阅读前几章的全部内容,以了解如何构建老式Windows程序。

答案 2 :(得分:2)

SetPixel很慢,你无法显着改善你的程序。创建内存中的位图并在窗口上绘制它。例如,您可以使用StretchDIBits函数执行此操作,该函数将整个内存区域绘制为窗口的位图,而不是SetPixel。

最重要的StretchDIBits参数是:

CONST VOID * lpBits - 内存数组(像素)。您需要将其填入内存而不是SetPixel调用。

CONST BITMAPINFO * lpBitsInfo - 必须描述位图结构的BITMAPINFO结构。例如,如果lpBits具有BGRW结构(每个像素4个字节),则BITMAPINFO必须描述真彩色位图。

答案 3 :(得分:1)

您需要将内容绘制到内存中,然后在收到WM_PAINT消息时将其绘制到窗口中。无法避免使用内存缓冲区,因为窗口设备上下文不会保存您绘制的内容。

答案 4 :(得分:0)

创建一个DIB曲面并改为绘制。然后在重绘窗口时重绘位图。

您正尝试在Windows中使用Windows之前的方式进行绘制。 ;)