2

我在这里有一个简单的 Windows 应用程序:

http://www.bengoodger.com/software/chrome/dwm/app.cc

我的应用程序在 DWM 合成处于活动状态时提供了一个自定义的玻璃框架,并在它处于非活动状态或不可用时提供了一个完全自定义的框架。

“自定义玻璃框架”由一个放大的标题栏区域组成,我的 WM _NCCALCSIZE 实现将其报告为客户区域的一部分,因为我想在其中呈现透明控件。为了使我的窗口的这个“高标题栏区域”部分是透明的,我用透明的黑色填充它(在上面的简单示例中为 BLACK_BRUSH),这导致它被 DWM 绘制为玻璃。

当系统 DWM 被切换时,例如通过使用外观设置控制面板切换到 Vista Basic 或 Windows Standard,或者当启动需要系统禁用 DWM 的应用程序时,我的应用程序通过处理 WM_NCPAINT 等切换到完全自定义渲染模式. 当我切换回来时,我会期待相反的情况,这主要发生,除了我的“高标题栏区域”现在是纯黑色。

我发现我可以通过获取窗口的位置、隐藏窗口然后在我的 WM_DWMCOMPOSITIONCHANGED 处理中再次设置窗口的位置来解决这个问题,但这会导致其他可怕的错误(其中至少是窗口 z-order munging)。

我的问题是 - 我在这里做错了什么?似乎窗口以某种方式被置于虚假状态,并且隐藏/显示它可以纠正它。我怎样才能防止这种情况发生?任何指导将不胜感激。

注意:我已经缩小了一些范围。当 DWM 玻璃生效时,在客户区域上渲染的任何被涂成黑色的客户区域部分都将被渲染为透明。我们注意到,当从非 Glass 返回到 Glass 时,客户区域呈现为纯黑色而不是透明。但是,当窗口最大化然后恢复时,窗口将恢复为透明状态。当我随后将窗口缩小时,顶部窗口保持透明。当我将它拖得更大时,窗口的顶部再次变黑。就好像 DWM 正在缓存窗口后面的像素,并且将窗口调整得更大会导致它无法在那里绘制任何东西,因为它的缓存不够大。我似乎找不到任何 DWM 功能来重置此状态。

4

1 回答 1

2

http://www.codeproject.com/KB/dialog/rtaGlassEffectLib.aspx

您可能已经注意到,GlassEnabled 属性非常适合测试您的系统是否启用了此功能,然后开始使用我们的库并调用 ShowEffect() 函数来显示玻璃效果,现在假设用户已禁用/启用应用程序运行时的 Aero 主题!这可能会导致您的应用程序出现问题。

为了解决这个问题,库中添加了两个事件来跟踪应用程序运行时系统发生的变化,这两个事件是 GlassEffectEnabled 事件和 GlassEffectDisabled。

现在对于那些想知道东西是如何工作的人来说......我可以告诉我这些事件是通过监视从系统到窗口的消息来实现的,我们的应用程序正在寻找指示系统颜色已更改的 WM_SYSCOLORCHANGE 消息。因此,通过快速比较此消息前后 GlassEnabled 属性的状态,我们可以确定此功能是否已启用。

于 2009-12-09T15:15:56.280 回答