2

我有一个使用 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

我正在尝试的解决方案是让CFrameWindowImpl派生类使用该WS_EX_COMPOSITED样式,并且它下面的所有窗口都使用该WS_EX_TRANSPARENT样式。不幸的是,这使得选项卡控件按钮显示为一个空的黑条,并且任何配置视图的控件根本不显示。

如果我删除WS_EX_COMPOSITEDandWS_EX_TRANSPARENT样式,表单会正确显示,但是CTabView在调整大小时,它下面的所有内容都会可怕地闪烁。

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

谢谢,保罗


编辑:让它工作。根据 Mark Ransom 的建议,我删除了所有WS_EX_TRANSPARENT样式。我WS_EX_COMPOSITED样式放在(包含在 中)。其他控件根据需要通过.CTabCtrlCTabViewWTL::CDoubleBufferImpl<>

4

3 回答 3

3

MSDN 中没有提到的是桌面窗口管理器 - 在 Windows Vista 和 7 上挂钩窗口绘制以执行获得航空玻璃效果所需的桌面合成的组件 - 没有实现 WS_EX_COMPOSITED。

这意味着您为使这种风格在 XP 上工作而付出的所有工作,注定在 Vista 或更高版本上变得无关紧要。

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

遗憾的是,结果是,在原生 API 应用程序中“消除”闪烁的唯一方法是尝试将其最小化:如果您没有重叠控件,WS_CLIPCHILDREN 和 WS_CLIPSIBLINGS 可以提供帮助 - 确保每个控件的区域只绘制一次。并确保主对话框不会在 WM_ERASEBKGND 中执行任何泛洪填充

于 2010-11-15T20:27:05.957 回答
3

窗口闪烁,因为它在绘制之前被擦除。要消除这种情况,您需要完全禁用窗口擦除并使用双缓冲 - 将窗口内容绘制到位图中,然后将位图复制到窗口。因为位图包含了包括背景在内的全部内容,所以不再需要擦除。

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

于 2010-11-15T20:07:09.483 回答
0

It is not, in my experience, possible to use double-buffering for anything that contains child controls (unless they all fully support WM_PRINT, which most do not).

于 2010-11-15T20:30:49.537 回答