调整主窗口大小时,静态控件会略微闪烁

时间:2013-12-03 22:02:30

标签: c++ winapi gdi+ gdi flicker

引言及相关资料:

我有一个复杂的绘画要在我的主窗口的WM_PAINT处理程序中实现。

我已经提交了一张图片来说明它:

enter image description here

主窗口有静态控件,而不是按钮,它们具有样式SS_NOTIFY

当用户点击它们时,程序中会发生某些操作。

下图显示了主窗口中静态控件的位置:

enter image description here

橙色面板上的地图是EMF文件,左上角和右上角是PNG个文件,其他图片是位图。

为了实现这个任务,我决定在WM_PAINT中绘制整个图片,并对图片上与之对应的图像放置不可见的静态控件。

因此,我只会在NULL_BRUSH处理程序中返回WM_CTLCOLORSTATIC,如下所示:

case WM_CTLCOLORSTATIC:
    return (LRESULT)( (HBRUSH)GetStockObject(NULL_BRUSH) );

我使用Windows XPMS Visual Studio C++ 2008 Express Edition处理pure Win32 API

一个注释:由于VS 的Express版本没有资源编辑器,因此使用 ResEdit 创建资源文件和资源标头:http://www.resedit.net/

问题:

当我调整窗口大小时,静态控件会略微闪烁。

我努力解决问题:

我处理了WM_ERASEBKGND(已退回(LRESULT)1),并且我已从我的窗口类中排除了样式CS_VREDRAWCS_HREDRAW - 因此不应该因为此而导致闪烁

我的窗口没有WS_CLIPCHILDREN样式。

编辑: 在回应下面的评论时,我解释了为什么我的窗口没有这个样式集:

问题是桌面图片的一部分可以看到静态控件的位置。

我已经为两个处理程序实现了双缓冲,以避免闪烁。

我使用了从此处下载的GDIView工具:http://www.nirsoft.net/utils/gdi_handles.html来追踪GDI leaks

每次调整窗口大小时,GDIView在区域列中显示+4,这意味着我会泄漏区域。

我无法弄清楚这是怎么可能的,因为我不使用与区域一起操作的API。

为了准确说明我所面对的问题,我制作了一个演示应用程序,并提供了全面的评论: http://www.filedropper.com/geotermistgrafika

我认为这是更有效的方式,然后发布代码,因为它会占用太多空间。

问题:

如何修改demo项目中的代码以消除闪烁?

我的方法是错误的,如果是的话,那是对的?

谢谢。 问候。

1 个答案:

答案 0 :(得分:5)

调整主窗口大小时,WM_SIZE处理程序会移动静态子窗口。

移动子窗口时,Windows会自动将子控件的客户区域从旧位置复制到新位置。

然后主窗口将在WM_PAINT处理程序中重新绘制。

换句话说,当调整窗口大小时,所有静态控件都会移动到新位置,然后重新绘制窗口的其余部分。缺乏同步表现为闪烁。

您可以通过将SWP_NOCOPYBITS标记传递给SetWindowPos来避免这种情况。