我有一个复杂的绘画要在我的主窗口的WM_PAINT
处理程序中实现。
我已经提交了一张图片来说明它:
主窗口有静态控件,而不是按钮,它们具有样式SS_NOTIFY
。
当用户点击它们时,程序中会发生某些操作。
下图显示了主窗口中静态控件的位置:
橙色面板上的地图是EMF
文件,左上角和右上角是PNG
个文件,其他图片是位图。
为了实现这个任务,我决定在WM_PAINT
中绘制整个图片,并对图片上与之对应的图像放置不可见的静态控件。
因此,我只会在NULL_BRUSH
处理程序中返回WM_CTLCOLORSTATIC
,如下所示:
case WM_CTLCOLORSTATIC:
return (LRESULT)( (HBRUSH)GetStockObject(NULL_BRUSH) );
我使用Windows XP
和MS Visual Studio C++ 2008 Express Edition
处理pure Win32 API
。
一个注释:由于VS 的Express版本没有资源编辑器,因此使用 ResEdit 创建资源文件和资源标头:http://www.resedit.net/。
当我调整窗口大小时,静态控件会略微闪烁。
我处理了WM_ERASEBKGND
(已退回(LRESULT)1
),并且我已从我的窗口类中排除了样式CS_VREDRAW
和CS_HREDRAW
- 因此不应该因为此而导致闪烁
我的窗口没有WS_CLIPCHILDREN
样式。
编辑: 在回应下面的评论时,我解释了为什么我的窗口没有这个样式集:
问题是桌面图片的一部分可以看到静态控件的位置。
我已经为两个处理程序实现了双缓冲,以避免闪烁。
我使用了从此处下载的GDIView
工具:http://www.nirsoft.net/utils/gdi_handles.html来追踪GDI leaks
。
每次调整窗口大小时,GDIView
在区域列中显示+4,这意味着我会泄漏区域。
我无法弄清楚这是怎么可能的,因为我不使用与区域一起操作的API。
为了准确说明我所面对的问题,我制作了一个演示应用程序,并提供了全面的评论: http://www.filedropper.com/geotermistgrafika
我认为这是更有效的方式,然后发布代码,因为它会占用太多空间。
如何修改demo项目中的代码以消除闪烁?
我的方法是错误的,如果是的话,那是对的?
谢谢。 问候。
答案 0 :(得分:5)
调整主窗口大小时,WM_SIZE
处理程序会移动静态子窗口。
移动子窗口时,Windows会自动将子控件的客户区域从旧位置复制到新位置。
然后主窗口将在WM_PAINT
处理程序中重新绘制。
换句话说,当调整窗口大小时,所有静态控件都会移动到新位置,然后重新绘制窗口的其余部分。缺乏同步表现为闪烁。
您可以通过将SWP_NOCOPYBITS
标记传递给SetWindowPos
来避免这种情况。