Glass is not rendered right
Asked Answered
S

2

9

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 );
        }
}
Sawfly answered 9/10, 2012 at 15:52 Comment(5)
How do you know what's rendered if it's not visible?Copilot
Unsure what you mean...are you saying that if you move the window past the edge of the screen and back again, the glass has disappeared in the section where the window intersected with the screen edge?Simonasimonds
P.S. I have looked at using glass many times in the past. Search for Daniel Moth and Glass in Google...He seems to be a guru with glass effects!!Simonasimonds
@activwerx, yes that is what I meanSawfly
Need to see some code. Also, is this WinForms or WPF?Sexagesimal
L
11

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();
}
Louque answered 16/10, 2012 at 19:1 Comment(1)
I was doing the same, but I still had some issues with resizing. Try it, and see?Rael
R
4

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)

Rael answered 16/10, 2012 at 19:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.