Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 );
        }
}
like image 647
Victor Avatar asked Oct 09 '12 15:10

Victor


2 Answers

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();
}
like image 134
LarsTech Avatar answered Nov 20 '22 14:11

LarsTech


The following call has to be in your OnPaint method

FillRectangle( new SolidBrush( Color.Black ), new Rectangle( 0, this.ClientSize.Height - 32, this.ClientSize.Width, 32 ) );

The rest only has to be done once. Instead of calling CreateGraphics() use the arguments to the OnPaint (e.Graphics)

like image 45
Alan Avatar answered Nov 20 '22 14:11

Alan