Search code examples
c#winformsaeroaero-glass

Glass is not rendered right


I made a form and extended the glass in it like in the image below. But when I move the window so not all of it is visible on screen, the glass rendering is wrong after I move it back: enter image description here

How can I handle this so the window is rendered correctly?

This is my code:

[DllImport( "dwmapi.dll" )]
private static extern void DwmExtendFrameIntoClientArea( IntPtr hWnd, ref Margins mg );

[DllImport( "dwmapi.dll" )]
private static extern void DwmIsCompositionEnabled( out bool enabled );

public struct Margins{
    public int Left;
    public int Right;
    public int Top;
    public int Bottom;
}

private void Form1_Shown( object sender, EventArgs e ) {
    this.CreateGraphics().FillRectangle( new SolidBrush( Color.Black ), new Rectangle( 0, this.ClientSize.Height - 32, this.ClientSize.Width, 32 ) );
    bool isGlassEnabled = false;
    Margins margin;
    margin.Top = 0;
    margin.Left = 0;
    margin.Bottom = 32;
    margin.Right = 0;
        DwmIsCompositionEnabled( out isGlassEnabled );

    if (isGlassEnabled) {

            DwmExtendFrameIntoClientArea( this.Handle, ref margin );
        }
}

Solution

  • I think the CreateGraphics is causing you some grief here.

    Try overriding the OnPaint method and use the Graphic object from the PaintEventArgs instead:

    protected override void OnShown(EventArgs e) {
      base.OnShown(e);
    
      bool isGlassEnabled = false;
      Margins margin;
      margin.Top = 0;
      margin.Left = 0;
      margin.Bottom = 32;
      margin.Right = 0;
      DwmIsCompositionEnabled(out isGlassEnabled);
    
      if (isGlassEnabled) {
        DwmExtendFrameIntoClientArea(this.Handle, ref margin);
      }
    }
    
    protected override void OnPaint(PaintEventArgs e) {
      base.OnPaint(e);
    
      e.Graphics.FillRectangle(Pens.Black, 
           new Rectangle(0, this.ClientSize.Height - 32, this.ClientSize.Width, 32));
    }
    

    If resizing the form, either add this to the constructor:

    public Form1() {
      InitializeComponent();
      this.ResizeRedraw = true;
    }
    

    or override the Resize event:

    protected override void OnResize(EventArgs e) {
      base.OnResize(e);
      this.Invalidate();
    }