Click here to Skip to main content
Click here to Skip to main content

Windows Vista Aero Glass in .NET Managed Win32 Applications

By , 18 Feb 2007
 

Screenshot - AeroGlassForms.jpg

Introduction

There are a number of articles regarding the use of the Vista Aero APIs from within a managed Win32 Forms application. However having searched around, it seems several are outdated due to changes implemented between early Vista betas and Vista's final release.

This article is a brief introduction into the use of the new Vista APIs for extending the Aero Glass area into a managed Win32 application.

Background

So what is Aero? Aero is the new graphics UI for Vista. If you're lucky enough to own a copy of Vista and meet the hardware requirements, you can enable Aero through the Windows colour schemes dialog. This enables the Aero scheme on all Windows and dialogs (including Win32 applications), and provides translucent borders and blur effects known as Aero Glass.

As well as being aesthetically pleasing, Aero Glass can be used to enhance a user interface by controlling the focus of specific elements on screen. Remember according the Vista design guidelines the Glass effect should be used judiciously. It may be cool to do, but Glass is really intended for small regions without text or UI in order to make the interface appear more lightweight and clean.

Extending Glass

By default when Aero is enabled, all Windows have a translucent Glass frame and title bar. Using the Windows APIs it's possible to extend this Glass effect further into the client area. They can also be used to create Glass panels inside the client area, but unfortunately in managed code this is not as easy as it should be, and there are some major limitations.

To display Glass within a Window you must first use the DwmExtendFrameIntoClientArea API to extend Glass into the client area. Once this is done, any area within this region that is painted black will appear as a Glass surface. If the area is not painted, any Glass regions not hidden by controls will just appear black at runtime (rather than Glass). In previous beta versions of Vista this step did not appear necessary, which is why a lot of the samples in circulation do not appear to work.

Due the fact that Windows uses the colour black to mask out the Glass regions, this has an undesired effect on any Windows Form controls within the Glass area, including any black text which will be lost.

To get around this, it's best to use the drawing APIs to manually create any text and graphical elements within the Glass area, which will then allow the use of a black brush on the Glass surface. See Pang Wu's article for more detailed tutorials on these techniques (link below).

The Code

To use the Vista APIs we use a number of PInvoke methods defined as follows:

[StructLayout(LayoutKind.Sequential)]
public struct MARGINS
{
    public int Left;
    public int Right;
    public int Top;
    public int Bottom;
}

[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern void DwmExtendFrameIntoClientArea
                (IntPtr hwnd, ref MARGINS margins);

[DllImport("dwmapi.dll", PreserveSig = false)]
public static extern bool DwmIsCompositionEnabled();

We can now use these methods to ensure Aero effects are enabled, and then call DwmExtendFrameIntoClientArea to extend the Glass effect into the client area as follows. This only needs to be done once, so we can use the Forms OnLoad method to set up the desired Glass region.

// defines how far we are extending the Glass margins
private MARGINS margins;

// uses PInvoke to setup the Glass area.
protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    if (DwmIsCompositionEnabled())
    {
        // Paint the glass effect.
        margins = new Win32.MARGINS();
        margins.Top = 20;
        margins.Left = 20;
        DwmExtendFrameIntoClientArea(this.Handle, ref margins);
    }
}

We now paint any areas we want to display as Glass with a black brush. This is best done by overriding the Form's OnPaintBackground method. There are several ways of doing this, to keep it simple we will first clear the background with a black brush to enable Glass in our defined region, and then repaint the non-Glass client area with it's original background colour.

protected override void OnPaintBackground(PaintEventArgs e)
{
    base.OnPaint(e);
    if (DwmIsCompositionEnabled())
    {
        // paint background black to enable include glass regions
        e.Graphics.Clear(Color.Black);
        // revert the non-glass rectangle back to it's original colour
        Rectangle clientArea = new Rectangle(
                margins.Left,
                margins.Top,
                this.ClientRectangle.Width - margins.Left - margins.Right,
                this.ClientRectangle.Height - margins.Top - margins.Bottom
            );
        Brush b = new SolidBrush(this.BackColor);
        e.Graphics.FillRectangle(b, clientArea);
    }
}

In Summary

That concludes the basics of extending Glass into your managed Win32 client area, however there's a lot more to Aero, and this article barely scrapes the surface. With further API calls it's possible to turn the Glass blur effects on/off, or even define blurred shapes within the Glass panels. Luckily there are some great articles about taking this further, which cover detailed tutorials on adding text and graphics to your Glass panels. See further reading below for links.

In the future I hope to add more to this article, and investigate possible solutions for handling the colour masking required by the Glass regions.

History

  • Initial release: Feb 2007

Further Reading

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

TheCodeKing
Architect
United Kingdom United Kingdom
Member
Mike Carlisle - Technical Architect with over 10 years experience in a wide range of technologies.
 
@TheCodeKing

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Questionthe win32membersystemerror12116 Jun '12 - 21:23 
I get an error in the code
 
 margins = new Win32.MARGINS();
 
My error is
 
Error   1   The type or namespace name 'Win32' could not be found (are you missing a using directive or an assembly reference?) Z:\areo\areo\Form1.cs   57  31  QuickLuuk1
 
whats wrong??
QuestionMARGINS definitionmembertheMadCoder1 Dec '11 - 5:34 
Outstanding.
 

One comment though
 
This is the definition of MARGINS
 

[StructLayout(LayoutKind.Sequential)]
public struct MARGINS
{
    public int cxLeftWidth;
    public int cxRightWidth;
    public int cyTopHeight;
    public int cyBottomHeight;
}

GeneralMy vote of 5membertheMadCoder1 Dec '11 - 5:31 
First working sample I found!!
GeneralGood Find!memberjp2code3 Jun '11 - 8:04 
I gave it the 4 Stars
 
...but I must say, I found this using the same Google search that pulled >> THIS <<[^] up, too, which looks like a duplicate. (???)

GeneralRe: Good Find!memberjp2code3 Jun '11 - 8:09 
My apologies! The linked post shows how to do this using WPF. This article is for Forms.

GeneralExtend the titlebar toomemberAETCoder15 May '11 - 8:27 
I was hoping you could drag the window by dragging on the aero areas but it seems this hasn't been done, can anyone do this?
GeneralClean the brush!memberVercas17 Dec '10 - 2:53 
Brushes have to be disposed. This decreases the quality of the article... :(
QuestionBad textmemberM62 11626 Aug '10 - 14:34 
The Visual C# doesn't accepts Win32. It says: 'The type or namespace name 'Win32' could not be found (are you missing a using directive or an assembly reference?)'. Can you help me?
 
Thanks,
Tom
GeneralRe: Bad textmemberM62 11626 Aug '10 - 14:37 
I'm using Visual C# 2010 Express Edition
AnswerRe: Bad textmemberscasbyte23 May '12 - 20:20 
Hi, look at the downloadable demo, he creates a class named Native where it is defined.
QuestionForm clear not glassmemberHayden Ball19 Apr '09 - 3:48 
Hi,
 
I have followed the instructions above but I get a form that is transparent not glass. Frown | :(
Any ideas?
 
HaydenHaddock
AnswerRe: Form clear not glassmemberTheCodeKing21 Apr '09 - 8:21 
Have you tried the demo application? Also are you running vista with aero enabled?
 

GeneralRe: Form clear not glassmemberHayden Ball4 May '09 - 6:39 
I have since fixed the problem - I was trying to use a boarder less form, it seems glass doesn't like that!
 
Thanks anyway Wink | ;-)
AnswerFix to transparent control textmemberBarry Alan Postma18 Mar '09 - 6:42 
In the Main() of your application,
change the text rendering to the GDI+ mode, by adding this line:
 
Application.SetCompatibleTextRenderingDefault(true);
 
Got it from here:
[MSDN magazine cc163435]
 

Good luck!
QuestionBad text in controlsmemberMember #109180718 Feb '07 - 23:26 
Hello, when I execute your demo application, if I drop a textbox or a label into the glass form, the control text appears with aero style (transparent) and it's very difficult to see the content of the control.
 
Is there any solution for this problem?
 
Thanks!
AnswerRe: Bad text in controlsmemberTheCodeKing18 Feb '07 - 23:45 
Hi there,
 
This is actually discussed in the article and is one of the limitations of using the effect. It's due to the fact that Windows uses the colour black as a mask for the Glass effect.
 
It means any controls placed in the area defined for the Glass region will not appear correctly, as any black within the control will be 'Glassed'. The solution is to manually draw text and images onto the Glass panel using the OnPaint .i.e. don't use controls within this area. Refer to the article by Pang Wu for details on this.
 
At some point I'm going to experient with the APIs some more to see if there's a way to allow controls within the Glass region, but so far I don't know of another solution.
 
Hope that helps,
 
Mike
 

GeneralRe: Bad text in controlsmemberRobert Rohde19 Feb '07 - 0:04 
Hi,
 
I haven't tested this but shouldn't it be possible to just set the ForeColor of the whole Form to e.g. Color.FromArgb(0, 0, 1)? Thus the texts wouldn't be "really black" but still "look black".
 
Robert
GeneralRe: Bad text in controlsmemberTheCodeKing19 Feb '07 - 8:53 
Unfortunately this doesn't work, as non-black colours still become translucent, with a tint of the original colour. Black is entirely translucent, and white appears entirely opaque. I'll update the article to make this clearer when I get a chance.
GeneralRe: Bad text in controlsmemberChris_McGrath2 Jul '07 - 20:35 
Any ideas how to work around the same problem for menuStrips?
AnswerRe: Bad text in controlsmemberJames_Zhang25 Dec '08 - 17:48 
You can use
 
      g.DrawString("Text Drawn :)", this.Font, new SolidBrush(Color.Blue), 10, 10);
 
in the form1.paint method Smile | :)
 
By the way great activebuttons article just what i was searching for.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 18 Feb 2007
Article Copyright 2007 by TheCodeKing
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid