使用WS_EX_COMPOSITED的无闪烁选项卡控件

我有一个使用WTL 8.1开发的Windows XP SP3的VS2008 C ++应用程序。 我的应用程序包含在调整应用程序边框时闪烁的选项卡控件。

我的窗口层次结构如下所示:

CFrameWindowImpl CMainFrm |-CSplitterWindow Splitter |-CTabView Configuration Tabs | |-CDialogImpl Configuration View 1 | |-CDialogImpl Configuration View 2 | |-CDialogImpl Configuration View 3 |-CDialogImpl Control View 

我正在尝试的解决scheme是使CFrameWindowImpl派生类使用WS_EX_COMPOSITED样式,其下的所有窗口使用WS_EX_TRANSPARENT样式。 不幸的是,这使得选项卡控制button显示为一个空的黑色条,任何configuration视图的控件都根本不显示。

如果我删除了WS_EX_COMPOSITEDWS_EX_TRANSPARENT样式,表单显示正确,但CTabView和它下面的所有东西在resize时会闪烁。

我需要改变什么来消除闪烁并正确地绘制控件?

谢谢,PaulH


编辑:得到它的工作。 我根据Mark Ransom的build议删除了所有WS_EX_TRANSPARENT样式。 我只把WS_EX_COMPOSITED样式放在CTabCtrl (包含在CTabView )。 其他控件根据需要通过WTL::CDoubleBufferImpl<>获得双缓冲。

一个窗口闪烁,因为它被绘制之前被擦除。 为了消除这种情况,你需要完全禁止擦除窗口,并使用双缓冲 – 将窗口内容绘制成位图,然后将位图复制到窗口。 由于位图包含了包括背景在内的全部内容,因此无需再擦除。

它看起来像WS_EX_COMPOSITED将自动处理双缓冲,但你仍然可能需要使用空背景画笔和/或处理WM_ERASEBKGND消息。

在MSDN中没有提到的是,桌面窗口管理器(Window Window Manager)是在Windows Vista和7上挂接窗口绘画以执行获得空气玻璃效果所必需的桌面组合的组件,但不实现WS_EX_COMPOSITED。

这意味着所有的工作,你把这种风格的工作在XP上,注定要在Vista或更高版本上变得无用。

WS_EX_COMPOSITED的另一个问题 – 以及为什么它是一个可选的样式,而不是XP上的默认值:双缓冲仅拾取在父窗口的BeginPaint / EndPaint块中执行的绘制。 许多甚至是标准的控件都在WM_PAINT处理程序之外进行绘画,结果后缓冲区只能被部分地绘制。

不幸的是,结果是,消除本机API应用程序中闪烁的唯一方法是尽量减少闪烁:如果不具有重叠控件,WS_CLIPCHILDREN和WS_CLIPSIBLINGS可以帮助确保每个控件的区域只被绘制一次。 并确保主对话框在WM_ERASEBKGND中不执行任何洪水填充

根据我的经验,对于包含子控件的任何东西都可以使用双缓冲(除非它们全部支持WM_PRINT,而大多数则不支持)。