DWM组合切换导致客户区丢失alpha

时间:2009-09-30 03:20:21

标签: gdi dwm nonclient

我在这里有一个简单的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顺序重叠)

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

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

1 个答案:

答案 0 :(得分:2)

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

  

你可能已经注意到了,   GlassEnabled酒店很棒   用于测试是否启用此功能   由您的系统,然后开始使用   我们的库并调用ShowEffect()   功能显示玻璃效果,现在   假设用户已禁用/启用   您的应用程序时的Aero主题   跑了!!这可能会导致   你的外表问题   应用

     

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

     

现在适合那些喜欢懂得如何的人   东西工作..我可以告诉这些   事件通过监测实施   来自系统的消息   我们的应用程序的窗口看起来   对于WM_SYSCOLORCHANGE消息   表示系统颜色有   被改变了。所以做一个快速   比较状态   GlassEnabled属性之前和之后   这条消息,我们可以决定是否   此功能是否已启用。