避免在调整大小时移动其控件的对话框上闪烁
Posted
技术标签:
【中文标题】避免在调整大小时移动其控件的对话框上闪烁【英文标题】:Avoid Flickering on a dialog that moves its controls on resize 【发布时间】:2011-08-05 07:46:26 【问题描述】:我有一个弹出对话框(CDialog
),它处理WM_CTLCOLOR
消息为自己着色。它有一些使用 OwnerDraw 绘制自己的控件(如位图按钮)。它还有一个控件,可以显示一个占对话框 70% 大小的图像。
当用户重新调整对话框大小时,对话框中的某些控件应该重新定位(而不是重新调整大小)。 它还涉及到对话框内图像的大小调整。由于图像大小的调整使整个过程变慢,控件的单独重新定位会导致视觉效果闪烁。 p>
我需要摆脱这些。一种想法是将控件作为中间对话框的子级,该中间对话框是原始弹出对话框的子级。因此,当重新调整大小时,我只能重新定位对话框,而不是单独移动每个控件。 (重新定位只发生在一个方向(x 或 y),所以移动中间对话框就足够了。
由于涉及到一些编码工作,因此在此之前,我需要回答以下问题:
这行得通吗? 如果是,这种方法涉及的复杂性是什么? 有没有更好的办法?请帮忙!
【问题讨论】:
我对 mfc 没有任何经验,但闪烁通常表明存在线程安全问题。您的小部件不是线程安全的,因此您需要适当地处理它。有关我的意思的摇摆示例,请参阅***.com/questions/4524786/… 没有 Dhruv,MFC 不是 Swing。 Windows 闪烁几乎总是因为 WM_* 标志的某些组合设置不正确。就我而言,我需要在父窗口上启用 WM_CLIPCHILDREN。 【参考方案1】:简单的修复是:
最后创建慢速窗口,这样它就不会阻碍简单控件的绘制 打开 WS_EX_COMPOSITED 样式标志,以便 Windows 双缓冲整个窗口,包括其子窗口。谨防绘画文物 关闭 WS_CLIPCHILDREN 样式标志,这样这些漏洞就不会那么明显了。将背景设为白色也可以实现同样的效果 在 WM_ENTERSIZEMOVE 和 WM_EXITSIZEMOVE 之间保持慢速控件的绘制简单 使用较少的控件,无需在简单的字符串或图像上烧毁昂贵的窗口【讨论】:
【参考方案2】:它可能会起作用,但您应该尝试以前不会改变您的控制层次结构的解决方案,因为它会产生其他微妙的后果(焦点、标签顺序、消息通知等)。
尝试以下一项或全部:
使用 BeginDeferWindowPos/DeferWindowPos/EndDeferWindowPos 函数来移动子项。 在对话框中设置 WS_CLIPCHILDREN 样式标志。 在对话框中设置 WS_EX_LAYERED 扩展样式标志。【讨论】:
WS_EX_LAYERED 样式用于双缓冲。对吗? 是的,系统提供的支持合成的双缓冲区。 DeferWindowPos 的必填 Raymond Chen 链接:blogs.msdn.com/b/oldnewthing/archive/2005/07/06/436043.aspx 另外,DeferWindowPos 可能不起作用。我们需要在调整大小时移动 selected 控件,这个函数似乎依赖于窗口的左上角坐标,在调整大小时不会改变。 @Don Reba,感谢您的链接。因此,在重新调整大小时相应地更改 x 和 y 应该可以工作。对?我以前认为它是关于父窗口的 xy 的。谢谢!以上是关于避免在调整大小时移动其控件的对话框上闪烁的主要内容,如果未能解决你的问题,请参考以下文章