【问题标题】:Static controls slightly flicker when main window is resized调整主窗口大小时,静态控件会轻微闪烁
【发布时间】: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 Editionpure 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。

为了准确说明我所面临的问题,我制作了一个演示应用程序,其中包含完整的 cmets: http://www.filedropper.com/geotermistgrafika

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

问题:

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

我的方法是不是错了,如果是,什么是正确的?

谢谢。 问候。

【问题讨论】:

  • 当您说您的窗口没有WS_CLIPCHILDREN 样式时,您并没有提供理由。为什么没有设置这个样式?
  • 如果我添加该样式,则部分桌面图片会显示在静态控件所在的位置。
  • 调整窗口大小时,是否移动或调整静态控件的大小?如果这样做,Windows 会自动移动静态控件的内容吗?这将解释闪烁。见WM_NCCALCSIZE。 (我会查看您的演示代码,但我不会为了查看它而注册一些随机网站。)
  • 我使用SetWindowPos API 来移动WM_SIZE 处理程序中的控件。至于下载,不需要注册,下载是免费的,在页面底部(我都检查过了)。如果您能看一下我的演示,我将不胜感激。谢谢你。问候。
  • 我也没有在随机网站上启用 Javascript,所以我还没有查看您的代码。无论如何,我已经在下面发布了一个解决方案。

标签: c++ winapi gdi+ gdi flicker


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 性能大大提升。尽管如此,当我从左到右调整窗口大小时会发生闪烁,当我从上到下调整大小时也会发生闪烁。如果我从右到左/从下到上调整大小,分别会发生以下效果:与窗口的其他部分相比,右/下边缘在重绘中似乎“落后”。 即使我移除静态控件也会出现这种效果。这是我唯一需要解决的问题,然后我才接受您的回答。目前,我已经投了赞成票。你能帮我解决我面临的剩余问题吗?谢谢你。问候。
  • 我已经回答了您关于静态控件的问题。这是一个新问题。无论如何,我似乎记得 Windows XP 在其主题支持中存在一个错误(当时是新的),这导致了您描述的调整窗口大小的问题。尝试在 VS Express 中创建默认的 win32 应用程序。我想你会发现它也有同样的问题,但它可以在其他版本的 Windows(更早或更晚)上正常工作。关闭主题也可能使问题消失。我没有 XP 副本可以自己尝试,而且我的记忆很模糊,所以自己尝试一下。
  • 好吧,我会听取您的建议,并在没有视觉样式的情况下尝试所有这些。此外,我将在 Windows 7 上对此进行测试。我将针对我目前面临的剩余问题提出一个新问题。再次感谢您所做的一切,我已经支持您的解决方案。最好的问候。
猜你喜欢
  • 1970-01-01
  • 2014-12-29
  • 2016-03-19
  • 2015-08-29
  • 2022-10-13
  • 2019-12-06
  • 2014-01-24
  • 2012-11-17
  • 2018-09-07
相关资源
最近更新 更多