MFC:如何避免子控件更新时的闪烁?

3
我已经搜索了几天,但一直得到的是相同的答案,而不是我想要的(稍后会描述我不想要的内容)。
我想要的是:
假设有一个包含几个CStatic子控件的父对话框。 当焦点在对话框中时,父对话框使用黑色作为背景颜色;当焦点不在对话框中时,使用灰色作为背景颜色。 子静态控件只是显示文本,但其背景需要跟随父控件的背景颜色。
问题:
我可以让子控件始终跟踪父控件的颜色,但更新颜色的过程很慢,会导致闪烁。 当我使对话框获得焦点时,我可以看到对话框从灰色变成黑色,然后每个文本控件也从灰色变成黑色。 这很慢,因为它在嵌入式设备上运行。 双重缓冲不起作用,因为父控件和子控件都有自己的绘图例程,所以我认为无法共享相同的缓冲区。我读到了 WS_EX_COMPOSITE 可以在Vista上工作,但我的操作系统版本较低。
我不需要的是:
我已经了解了如何覆盖背景擦除例程(这就是我已经能够更新控件的原因)。 我知道如何使用CMemDC,但是正如所述,它在我的情况下无法工作。
有什么想法吗?我确定处理速度起了作用,但我强烈相信这只是一种我没有做对的技术或设置。我记得我的第一台PC是133MHz,但我不记得Windows 95在它们的父级失去焦点时逐个更新控件——它们几乎立即更新。当时我甚至没有一张好的显卡。
请帮忙。
附加内容: - 我尝试将控件的BkMode设置为TRANSPARENT,并甚至使用NULL_BRUSH。所有这些都与ON_WM_CTLCOLOR一起使用。我得到的只是一个有孔洞的对话框,在这些孔洞中是控件文本。换句话说,控件的背景不会被绘制(如NULL_BRUSH所预期),但该区域也未被对话框的绘图任务覆盖。 - 我正在考虑删除WS_CLIPCHILDREN,但我认为这将导致控件被绘制在上面,从而导致闪烁。

我对MFC一无所知,如果这不是一个相关的问题,请原谅我。但是,难道不能将子控件设置为具有透明背景吗? - Jamie Dixon
啊,是的,我也考虑过那个问题。我会更新我的初始帖子,以反映我遇到的问题。 - Ryuu
你使用的是哪个版本的MFC和Visual Studio? - ChrisBD
基本上,我没有问题使控件在必要时更新其背景颜色。问题在于更新序列(父->子1->子2->等)的速度和顺序会导致闪烁。我有一个解决方案,那就是简单地重写对话框的OnPaint,并使用DrawText。使用TRANSPARENT作为BkMode完美地解决了这个问题,但我想要一个涵盖子控件使用情况的解决方案。我不能每次绘制所有内容...那就没有使用MFC的意义了。 - Ryuu
3个回答

1

你试过调用SetRedraw()函数吗?对于子窗口,你可以调用SetRedraw(FALSE)来阻止它们在每次更改父窗口时自动更新,而当父窗口的编辑完成后,你可以最终调用SetRedraw(TRUE)来使子窗口重新启用更新,并在那个时候可能需要使它们无效化,以便只更新一次。


0

你尝试过覆盖 WM_CTLCOLOR 吗?请查看我对这篇帖子的回答

注意:您可以使用pDC->SetBkColor设置静态控件的背景颜色,并返回具有所需颜色的画刷。


嗨djeidot。是的,我用了所有这些,它可以改变背景颜色。但问题是如何避免闪烁,而不是如何改变颜色。在我的平台上,“父级先更新,然后单个子级稍后更新”的过程太慢了。 - Ryuu
WM_CTLCOLOR 的想法是避免使用 WM_PAINTWM_ERASEBKGND,因为它们很可能会导致闪烁。你应该知道,你也可以通过 WM_CTLCOLOR 改变对话框的背景颜色。 - djeidot

0

我以前曾通过覆盖对话框的擦除背景来完成。然后,您准备一个区域,遍历对话框中的所有子项并从该区域中剪辑出其边界,而不是调用默认函数。最后,用对话框背景颜色填充矩形。

基本上,这个想法是只擦除没有控件的地方。

这样做肯定可以,但我不确定是否有更好的方法。例如“裁剪子项”选项或我认为还有双缓冲的样式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接