1

我有一个 WPF 窗口,可以在其SourceInitialized事件期间启用玻璃本身。这完美地工作。我将使用最简单的示例(只有一个窗口对象)来演示问题所在。

public partial class MainWindow : Window
{
    public bool lolz = false;
    public MainWindow()
    {
        InitializeComponent();
        this.SourceInitialized += (x, y) =>
            {
                AeroExtend(this);
            };
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        if (!lolz)
        {
            MainWindow mw = new MainWindow();
            mw.lolz = true;
            mw.ShowDialog();
        }
    }
}

这会创建两个MainWindows。当我在 Visual Studio 中调试它时,一切都按预期工作。 完美的!

当我在没有调试的情况下运行时,没有那么多。 不完美...

子窗口有一个奇怪的、错误应用的玻璃框架......但只有在没有 Visual Studio 调试的情况下直接运行它时。相同的代码运行了两次,但结果不同。当我创建第二个窗口时并不重要,我将它绑定到具有相同输出的按钮单击。

有任何想法吗?

编辑:这是我使用的代码的摘录AeroExtend

[DllImport("dwmapi.dll")]
private static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMargins);

[DllImport("dwmapi.dll", PreserveSig = false)]
private static extern bool DwmIsCompositionEnabled();

[StructLayout(LayoutKind.Sequential)]
private class MARGINS
    {
        public MARGINS(Thickness t)
        {
            cxLeftWidth = (int)t.Left;
            cxRightWidth = (int)t.Right;
            cyTopHeight = (int)t.Top;
            cyBottomHeight = (int)t.Bottom;
        }
        public int cxLeftWidth, cxRightWidth,
            cyTopHeight, cyBottomHeight;
}

...

static public bool AeroExtend(this Window window)
{
    if (Environment.OSVersion.Version.Major >= 6 && DwmIsCompositionEnabled())
    {
        IntPtr mainWindowPtr = new WindowInteropHelper(window).Handle;
        HwndSource mainWindowSrc = HwndSource.FromHwnd(mainWindowPtr);
        mainWindowSrc.CompositionTarget.BackgroundColor = Colors.Transparent;

        window.Background = System.Windows.Media.Brushes.Transparent;

        MARGINS margins = new MARGINS(new Thickness(-1));

        int result = DwmExtendFrameIntoClientArea(mainWindowSrc.Handle, ref margins);
        if (result < 0)
        {
            return false;
        }
         return true;
    }
    return false;
}
4

1 回答 1

3

问题是您将 MARGINS 定义为一个类。您会注意到,如果您尝试使用一组不同的边距值(例如,每条边缘 10 像素),它仍然会尝试填充整个区域。此外,正如我在前几天的评论中提到的那样,您会注意到即使在未以模态方式显示的原始窗口中,右下角也有一个工件。如果您只是将 MARGINS 从类更改为结构,则不会出现问题。例如

[StructLayout(LayoutKind.Sequential)]
private struct MARGINS

或者,您可以将 MARGINS 保留为一个类,但是您应该更改 DwmExtendFrameIntoClientArea 的定义方式。例如

[DllImport("dwmapi.dll")]
private static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, [MarshalAs(UnmanagedType.LPStruct)] MARGINS pMargins);
于 2012-10-16T12:27:40.063 回答