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 out-dated 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.

Aero Glass Forms

Aero Glass Forms


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 PInvoke methods defined as follows.

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 step 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)
    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)
    if (DwmIsCompositionEnabled())
        // paint background black to enable include glass regions
        // revert the non-glass rectangle back to it's original colour
        Rectangle clientArea = new Rectangle(
                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.

Further Reading