Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
289 views
in Technique[技术] by (71.8m points)

gdi+ - 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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
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?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...