DWM 组合切换导致客户区域丢失 Alpha
我这里有一个简单的 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”虽然能够解决这个问题,但也会产生其他不良副作用。
I have a simple Windows application here:
http://www.bengoodger.com/software/chrome/dwm/app.cc
My app provides a customized glass frame for when DWM compositing is active, and a fully custom frame when it is inactive or not available.
The "customized glass frame" consists of a enlarged title bar area, which is reported by my implementation of WM_
NCCALCSIZE to be part of the client area since I would like to render transparent controls into it. So that this "tall title bar area" portion of my window is transparent, I fill it with transparent black (BLACK_BRUSH in the simple example above) which causes it to be drawn as glass by the DWM.
When the system DWM is toggled, e.g. by using the Appearance Settings control panel to switch to Vista Basic or Windows Standard, or when an app that requires the system to disable DWM is launched, my app switches to fully custom rendering mode by handling WM_NCPAINT etc. When I switch back, I would expect the reverse, which mostly happens, except my "tall title bar area" is now solid black.
I've found I can work around this issue by getting the window's placement, hiding the window then setting the window's placement again in my WM_DWMCOMPOSITIONCHANGED handling, but this causes other horrible bugs (least of which is window z-order munging).
My question is - what am I doing wrong here? It seems like the window is being put into a bogus state somehow, and hiding/showing it corrects it. How can I prevent this from happening? Any guidance would be greatly appreciated.
Note: I have narrowed this down somewhat. When DWM glass is in effect, any part of the client area that is painted black that is rendered over the client area is rendered transparent. We noticed that when returning to Glass from non-Glass, the client area is rendered solid black instead of transparent. However when the window is maximized and then restored, the window returns to being transparent. When I subsequently drag size the window smaller, the top portion window remains transparent. When I drag it larger, the top portion of the window turns black again. It's as if the DWM is caching the pixels behind the window and sizing the window larger causes it not to be able to paint anything there because its cache isn't large enough. I can't seem to find any DWM function to reset this state. It seems that Maximize/Minimize then Restore or SetWindowPlacement are capable of tickling it though but have other undesirable side effects.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
http://www.codeproject.com/KB/dialog/rtaGlassEffectLib.aspx
http://www.codeproject.com/KB/dialog/rtaGlassEffectLib.aspx