Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows Aero: What color to paint to make "glass" appear?

What color must i paint in the client area in order to make glass appear?

i've extended the frame of my form into the client area using:

DwmExtendFrameIntoClientArea(self.Handle, margins); 

i cannot find any official documentation from Microsoft on what color and/or alpha the DWM will look for to replace with glass. The documentation on DwmExtendFrameInClientArea doesn't even mention that a custom color is required. There's only hearsay and myth that a special color is even required.

The closest i can find is a topic on MSDN:

Custom Window Frame Using DWM

For the extended frames to be visible, the regions underlying each of the extended frame's sides must have pixel data that has an alpha value of 0.

Update: And a blog post:

Windows Vista for Developers – Part 3 – The Desktop Window Manager

It so happens that the bit pattern for RGB black (0x00000000) is the same as the bit pattern for 100% transparent ARGB so you can actually draw with “black” GDI brush and assuming you’ve instructed the DWM to blur the painted area, the result will be the desired glass effect.

If i take what they say literally (pixel data with an alpha value of zero), i construct a color with zero alpha, and paint that in the extended area:

Color fillColor = Color.FromArgb(0, 0, 0, 0); //(a, r, g, b) e.Graphics.FillRectangle(new SolidBrush(fillColor), e.ClipRectangle); 

but the glass effect does not appear:

alt text


If i ignore the quoted MSDN topic, and instead use fully opaque black (rather than a completely transparent black):

Color fillColor = Color.FromArgb(255, 0, 0, 0); //(a, r, g, b) e.Graphics.FillRectangle(new SolidBrush(fillColor), e.ClipRectangle); 

the glass effect does appear:

alt text

i am then lead to believe that opaque black is the pixel value that the DWM will look for to replace with glass.

But then how do i paint black items on the glass area?


i've tested painting a black rectangle on the glass area, with a circle next to it. Oddly enough, the rectangle doesn't appear, while the circle does appear; both are the same color:

Brush b = new SolidBrush(Color.FromArgb(255, 0, 0, 0)); e.Graphics.FillRectangle(b, 11, 11, 32, 32); e.Graphcis.FillEllipse(b, 43, 11, 32, 32); 

alt text

So what in the world is going on? What is the proper color to paint in the extended frame area to make glass appear?


Update 2

Using Adisak's suggestion to isolate exactly where the stupidness of Aero lives, here i draw a black rectangle inside the black circle:

alt text

Does FillEllipse not support drawing black circles?


Update 3

Pondidum wondered if calling Graphics.Clear with a transparent black color would make the glass visible:

e.Graphics.Clear(Color.FromArgb(0,0,0,0)); 

It does work, but you still can't draw opaque black items on the glass:

alt text


Update 4

Looking at Microsoft's Vista Bridge Library (managed wrappers around Vista functionality that won't be added to .NET), they only ever manage to get extended glass frame working on WPF forms, not WinForms.

See also

  • Aero: How to draw ClearType text on glass?
  • Aero: How to draw solid colors on glass?
like image 747
Ian Boyd Avatar asked Dec 08 '09 21:12

Ian Boyd


2 Answers

Color fillColor = Color.FromArgb(0, 0, 0, 0); //(a, r, g, b) e.Graphics.FillRectangle(new SolidBrush(fillColor), e.ClipRectangle); 

This is actually rather amusing. It means that you are drawing something completely transparent - so this changes absolutely nothing! :-)

Guess: if black (0,0,0) should mean "glass", how about drawing (1,1,1) to get (almost) black?

like image 139
Dan Byström Avatar answered Oct 14 '22 17:10

Dan Byström


One of the blog posts that you linked to above has a discussion about this. The native solution was to use SetLayeredWindowAttributes to switch the color key away from black.

like image 22
Aaron Klotz Avatar answered Oct 14 '22 15:10

Aaron Klotz