Question

I have a WPF window that enables glass on itself during its SourceInitialized event. This works perfectly. I'll use the simplest example possible (just one window object) to demonstrate where the issue is.

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();
        }
    }
}

This creates two MainWindows. When I debug this in Visual Studio everything works as expected. Perfect!

When I run without debugging, not so much. Not perfect...

The child window has an odd, incorrectly applied glass frame... but only when running it directly without Visual Studio debugging. Same code ran twice but with different results. It doesn't matter when I create the second window, I've tied it to a button click with the same output.

Any ideas?

EDIT: Here is an excerpt of the code I'm using for 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;
}
Was it helpful?

Solution

The problem is that you have MARGINS defined as a class. You'll notice that if you tried using a different set of values for the margin (e.g. 10 pixels on each edge) that it will still try to fill the entire area. Also as I mentioned in my comment the other day, you will notice that you have an artifact in the lower right corner even in the original window that wasn't shown modally. If you simply change the MARGINS from a class to a struct then the problem does not occur. e.g.

[StructLayout(LayoutKind.Sequential)]
private struct MARGINS

Alternatively you could leave MARGINS a class but then you should change the way the DwmExtendFrameIntoClientArea is defined. e.g.

[DllImport("dwmapi.dll")]
private static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, [MarshalAs(UnmanagedType.LPStruct)] MARGINS pMargins);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top