【发布时间】:2013-12-05 08:11:08
【问题描述】:
简介及相关资料:
我有一个复杂的绘画要在我的主窗口的WM_PAINT 处理程序中实现。
我已经提交了一张图片来说明它:
主窗口有静态控件,而不是按钮,样式为SS_NOTIFY。
当用户点击它们时,程序中会发生某些动作。
下图显示了主窗口中静态控件的位置:
橙色面板上的地图是EMF文件,左上和右上的标志是PNG文件,其他图片是位图。
为了完成这个任务,我决定在WM_PAINT中绘制整张图片,并在图片上对应的图片上放置不可见的静态控件。
因此,我只在WM_CTLCOLORSTATIC 处理程序中返回NULL_BRUSH,如下所示:
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。
为了准确说明我所面临的问题,我制作了一个演示应用程序,其中包含完整的 cmets: http://www.filedropper.com/geotermistgrafika
我认为这是更有效的方式,然后发布代码,因为它会占用太多空间。
问题:
如何修改演示项目中的代码以消除闪烁?
我的方法是不是错了,如果是,什么是正确的?
谢谢。 问候。
【问题讨论】:
-
当您说您的窗口没有
WS_CLIPCHILDREN样式时,您并没有提供理由。为什么没有设置这个样式? -
如果我添加该样式,则部分桌面图片会显示在静态控件所在的位置。
-
调整窗口大小时,是否移动或调整静态控件的大小?如果这样做,Windows 会自动移动静态控件的内容吗?这将解释闪烁。见WM_NCCALCSIZE。 (我会查看您的演示代码,但我不会为了查看它而注册一些随机网站。)
-
我使用
SetWindowPosAPI 来移动WM_SIZE处理程序中的控件。至于下载,不需要注册,下载是免费的,在页面底部(我都检查过了)。如果您能看一下我的演示,我将不胜感激。谢谢你。问候。 -
我也没有在随机网站上启用 Javascript,所以我还没有查看您的代码。无论如何,我已经在下面发布了一个解决方案。
标签: c++ winapi gdi+ gdi flicker