Windows Aero Glass 背景在休眠后损坏。我该如何解决这个问题?

Posted

技术标签:

【中文标题】Windows Aero Glass 背景在休眠后损坏。我该如何解决这个问题?【英文标题】:Windows Aero Glass background is broken after hibernate. How can I solve this? 【发布时间】:2011-02-13 15:40:11 【问题描述】:

我正在用 C# .net 3.5 wpf 开发一个程序。它必须在 windows xp、windows vista 和 windows 7 上工作。在较新的操作系统上,我想在 Aero Glass 中创建背景。所以这只是一个特殊的设计。休眠后、挂起或将窗口设计更改为基本设计并返回航空后,所有添加的玻璃都显示为全黑。

我通过 GlassHelper 类显示 Glass(可以通过 Google 找到)。

实际上,我看到了解决此问题的 3 种方法。第一个是,是的,要解决它。但我在某处读到,这是 Windows 托管代码中的一个错误,所以我没有办法解决它。如果我错了,请纠正我。

所以我有了每次关闭窗口的想法,它被最小化并完全重建,下次使用时。

效果很好。休眠后窗口仍然显示为黑色,但我不必退出应用程序,我仍然可以将其最小化并再次最大化。

现在我想办法了:

1) 我每次关闭窗口,电脑都会挂起、休眠或更改设计。当它被保存时,我再次打开它。但是我该如何处理呢?

2) 我接受,该窗口将显示为黑色,直到有人将其最小化。 (不是我最喜欢的)但后来我遇到了一个新问题:任务栏中的按钮。 (不是托盘图标)。我需要它永久显示。在winxp上,最小化时我需要它来打开窗口。特别是在win7上我需要它,因为我想使用Superbar的一些新优势! (悬停预览不会是窗口,而是静态图片。)

谢谢大家帮助我!

【问题讨论】:

这是您开发系统上其他程序的问题,还是只是您正在构建的程序? 这只是我正在构建的程序。 【参考方案1】:

尝试处理 WM_NCCALCSIZE 消息并将客户区 (NCCALCSIZE_PARAMS.rgrc0) 减少一个像素。我是认真的。我发现此解决方案已在 Google Chrome 中使用,并且对我也很有效。

【讨论】:

好的,虽然我会尝试这个解决方案...谢谢,有点,因为现在是半夜我明天会这样做! 查看src.chromium.org/svn/branches/329/src/views/window/… 并搜索“gfx::Insets WindowWin::GetClientAreaInsets” 嘿,到目前为止我已经尝试过你的,因为它看起来更聪明,但我无法解决我的问题。我的程序不再是黑色背景,而是在非航空主题上冻结,在新主题上再次完全透明,我只能看到边框。【参考方案2】:

好的,谢谢大家!但我想我找到了自己的解决方案!

我处理消息:WM_DWMCOMPOSITIONCHANGED (0x031E) & WM_THEMECHANGED (0x031A)

在捕获其中一条消息时,我只需根据 DwmIsCompositionEnabled() 重新分配玻璃或新背景。

其实我有类似下面的东西:

const int WM_THEMECHANGED = 0x031A;
const int WM_DWMCOMPOSITIONCHANGED = 0x031E;

private static void ApplyTheme(IntPtr hwnd)

    if (DwmIsCompositionEnabled())
    
        HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor = Colors.Transparent;
        MARGINS margins = new MARGINS(new Thickness(-1));
        DwmExtendFrameIntoClientArea(hwnd, ref margins);
    
    else
    
        HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor = SystemColors.ActiveCaptionBrush.Color;
    


private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)

    if (msg == WM_THEMECHANGED)
    
        ApplyTheme(hwnd);
    
    if (msg == WM_DWMCOMPOSITIONCHANGED)
    
        ApplyTheme(hwnd);
    
    return IntPtr.Zero;

我明白了。

我挂了。

HwndSource.FromHwnd(hwnd).AddHook(new HwndSourceHook(WndProc));

我将 WPF 窗口背景设为透明,因为稍后在 WndProc 函数中我将只能访问我的 hwnd 背景 (Win32)。

window.Background = Brushes.Transparent;

现在我只需要第一次指定样式:

ApplyTheme(hwnd);

就是这样!在我禁用或启用 aero、在不同的 aero 或非 aero 样式之间切换或休眠后,它非常适合我(Win 64 Home Premium),所以这正是我想要的。谢谢你的好主意!

【讨论】:

【参考方案3】:

您可能想看看WPF Shell Integration Library。 我记得由于 Windows 7 中的桌面窗口管理器中的错误,该库也存在类似问题。该库有可用的源代码,因此您可以查看它们是如何处理它的。

【讨论】:

谢谢,我去看看! 好的。带有外壳的测试应用程序因旧的 Windows 主题而变黑。但不同的是,当您切换回气动时,它会完全恢复其旧外观。想想,这将是一个很好的交易。我将尝试在我自己的应用程序中使用它。谢谢!

以上是关于Windows Aero Glass 背景在休眠后损坏。我该如何解决这个问题?的主要内容,如果未能解决你的问题,请参考以下文章

适用于所有 Win32 程序员的在 Windows Aero Glass(DWM、GDI、GDI+)上绘图的文档和 API 示例

如何在应用Column标题的背景后添加排序箭头

VB 2013:在无边界表单上启用 Aero

解决Windows 7中“使用Aero Peek预览桌面”变灰色的方法

处理 Windows 7 Aero 主题上的卸载表单[重复]

如何强制 Aero 绘制无边框窗口,就好像它处于活动状态一样,即使它不是?