Windows Vista Aero Pt. 1 - Adding Glass to a Windows Forms Application
In a brief departure from my usual ramblings about Windows Presentation Foundation, I wanted to write a couple of technical posts about using new Windows Vista shell features from managed code. To start off, I thought I'd talk about how to add glass to an existing WinForms applications.
Firstly, what do I mean by adding glass? As most people know, Windows Vista includes a new Aero theme; one aspect of that theme is the translucent borders that are supplied by the Desktop Window Manager. There's a lot of subtle sophistication in the way window frames are drawn - a drop shadow from the window, glow effects over the maximize / minimize / close buttons, a reflective texture on the window frame itself - so it's far more than just painting with a 50% opacity gray brush.
On suitably equipped machines, every window gets a glass frame (even Command Prompt!). But some applications extend that glass frame into the client area of the window for aesthetic reasons; for example, Internet Explorer extends glass into the address bar, and Windows Media Player uses glass for the playback controls. Your application can also take advantage of the API behind this to extend glass into its own client area. This isn't free - there's quite a hefty tax involved in rendering glass, so it's something to use sparingly rather than as the background for your whole window. Nevertheless, it's a great way to make your application feel like an integral part of the operating system on which it runs.
In this first part, I'll show you how to add glass to a Windows Forms application; in future entries, I'll cover some other related areas such as drawing text onto glass, using glass in a WPF application, and creating blur effects.
The single API call that does most of the dirty-work is the following one:
[DllImport("dwmapi.dll")]
public static extern int DwmExtendFrameIntoClientArea(
IntPtr hWnd,
ref MARGINS pMarInset
);
This call takes two parameters - a window handle and a MARGINS struct that contains information on how much extra the DWM should extend the frame on the top, left, right and bottom sides of the screen. Here's the declaration for MARGINS:
[StructLayout(LayoutKind.Sequential)]
public struct MARGINS
{
public int cxLeftWidth;
public int cxRightWidth;
public int cyTopHeight;
public int cyBottomHeight;
}
The one big challenge with glass is getting alpha-blending to work correctly. Without using alpha-blending, then the content that you place on the glass will overwrite the glass itself and make it invisible. This is a problem in GDI, since it has no awareness of an alpha channel, but it's a little easier with GDI+. In your Windows Forms application, you simply need to set the TransparencyKey property to a color that you won't use elsewhere in the application (I use Gainsboro, for reasons that will become apparent later). Then you can create one or more panels that are docked to the margins of your form and set the background color for the panel to the transparency key. Now when you call DwmExtendFrameIntoClientArea, the glass will show within its margins wherever you've set something of the appropriate transparency key.
Here's an example of using the above API call (from a Form_Load event)
MARGINS margins = new MARGINS();
margins.cxLeftWidth = 0;
margins.cxRightWidth = 0;
margins.cyTopHeight = 45;
margins.cyBottomHeight = 0;
IntPtr hWnd = this.Handle;
int result = DwmExtendFrameIntoClientArea(hWnd, ref margins);
So long as you've created the panel appropriately, you should now see glass in your application. You can now draw buttons, labels or other controls onto the surface and so long as you set their background color to be transparent, you'll see them integrating well with glass. Here's an example screenshot that puts it all together:
There's just one caveat, which is that the text smoothing doesn't work out quite right. Since it uses the panel background to determine the color it should smooth against, you'll hit problems if you pick a garish color for the transparency key such as Fuchsia - you'll see that the text renders with a horrid pink glow. That's because we've cheated a little bit with the text rendering. So long as you set the transparency color to something that's close to a typical glass color, this effect is barely noticeable (you can just see a little white fringing around the title text above, if you look really closely). That's why we chose Gainsboro as our color earlier. Fortunately, there's a better way to do it - if a little more convoluted. Win32 actually provides a useful API for this situation called DrawThemeTextEx that renders the text correctly on glass and also provides an appropriate back-glow that helps distinguish the text when it's over a complex background. Next time I cover this topic, we'll look at that API as well as discussing how you can detect whether the DWM is present and enabled or not (which is important if you want your application to run downlevel).
Download the sample application and source code (requires Windows Vista to execute).
Comments
Anonymous
April 18, 2006
Tim Sneath has a great write-up on what it takes to give you app some Glass. It's surprisingly simple....Anonymous
April 18, 2006
Is is possible to host the command window (cmd) in a totally transparent window? Thus the text/scrollbar appears on glass? That would look soooooo cool!Anonymous
April 19, 2006
Thanks Tim, that's a very useful post. There's been surprisingly little information available relating to the DWM... I'm very interested in finding out more. I'd like to know more about what's possible. I'd also very much like to see some information about how to add glass to a WPF application.Anonymous
April 19, 2006
Here's how to do it.  (Requires Windows Vista and some willingness to fiddle with how your app...Anonymous
April 20, 2006
Hi Tim, is this specific to any version. On my install of Vista 5308 the text is transparent and the background is white.Anonymous
April 22, 2006
Will I be able to deploy glass effects via command prompt in Windows XP? If not, can someone please tell me how to get a legitimate copy of Vista without subscribing to MSDN, TechNet, etc?Anonymous
April 24, 2006
Tim Sneath, Windows Vista tech evangelist extraordinaire, has a good post up on how to add...Anonymous
April 25, 2006
Hi,
I was awaiting for such article on WPF. Thanks for the information you have given. I've even posted my issue on "Glass effect for windows forms" on MSDN forums. Thanks to forums too.
We have got a new requirement where in my client was to host Visio (Office 12) drawing control with in a WPF window.
Could you please let me know how can I go further of resolving this issue.
Thanks in advances..
crish (nseresha@hotmail.com)Anonymous
April 27, 2006
I have a problem with this approach. Setting the TransparencyKey for a form actually has two effects: it makes all areas of the form with that colour transparent, and it causes all mouse events in such transparent areas to be executed against the window that's behind the transparent area.
When using TransparencyKey in conjunction with glass, I don't want the second part to happen. If I use the DWM's default glass colour (black) I get glass without this effect, but then any other black items drawn over the glass area (such as control text) also become glass.
Is there any way to prevent this?Anonymous
April 27, 2006
PingBack from http://microsoft.blognewschannel.com/index.php/archives/2006/04/27/vistas-aero-glass-inside-applications/Anonymous
April 27, 2006
Looks like my comment got eaten. Here it goes again.
I have a problem adding glass to my app. Using TransparencyKey works fine to make the glass visible, but it also has another result: all clicks on the area that would've been transparent (and are now glass) are executed on the window below the glass. This is not what I want of course. Any way to prevent this?
I tried using a black brush, which seems the default "glass colour" but if I do that all other black elements (such as text) on top of the glass also become glass.
Any help?Anonymous
April 29, 2006
The comment has been removedAnonymous
April 30, 2006
The comment has been removedAnonymous
May 03, 2006
Sven: I know how you'd do it in a C++ app; Windows sends a WM_NCHITTEST message to your application before sending mouse messages, to work out what sort of mouse message (if any) it should send to the application's input queue. By judicious handling of this message, you can make any part of your app act like a title bar, sizing border, or even completely transparent.
Presumably you could override your form's WndProc to handle WM_NCHITTEST.Anonymous
May 03, 2006
And what about adding glass in WPF application?Anonymous
May 03, 2006
I've been looking at WM_NCHITTEST but it isn't the solution. Once TransparencyKey is set, the window doesn't receive WM_NCHITTEST messages (or any other mouse messages) for those areas whose colour matches the TransparencyKey.
I've been checking using reflector, and TransparencyKey is implemented using the SetLayeredWindowAttributes Win32 function. And indeed, in the Platform SDK it says "Hit testing of a layered window is based on the shape and transparency of the window. This means that the areas of the window that are color-keyed or whose alpha value is zero will let the mouse messages through."
So apparently, there is a way to extend glass into the frame without using a layered window with a color-key, since IE7 and other Vista applications manage to do it. But how? Is there perhaps some window style I can set for WS_EX_LAYERED windows that will prevent them from letting the mouse messages through? I don't mind if you give me the C++ solution, I'm familiar with C++ and Win32 and not afraid of PInvoke. :)Anonymous
May 04, 2006
Recently Tim shared some code for extending Windows Vista Aero "Glass" inside a Windows Forms window. ...Anonymous
May 04, 2006
TimS does a great post on getting the Vista “glass” look and feel in a WinForms app...
 
http://blogs.msdn.com/tims/archive/2006/04/18/578637.aspx...Anonymous
May 05, 2006
PingBack from http://www.nexusblogs.com/blogs/blogs-blog-at-runboardcom/Anonymous
May 07, 2006
I just checked with Spy++, and the windows neither Windows Media Player 11 or IE7 use WS_EX_LAYERED, so they are not using a transparency key for their glass areas. So, how do they do it?Anonymous
May 07, 2006
Any chance someone could convert this to VB .net? My C++ is a little rusty, to say the least. The only part I dont get is the dll import. The other parts I can use in VB easily I think.Anonymous
May 07, 2006
I’m starting to see more applications leveraging Aero Glass on Vista.  They look quite cool. ...Anonymous
May 24, 2006
Ok, so one of the things I hope to achieve with this blog is to share all of the little gems that I come...Anonymous
May 27, 2006
Hi, thanks for the tutorial. But there is one problem. The glass area client area is clikkeble trough the form it's annoying. How can you disable that?Anonymous
June 04, 2006
The great thing about working at a company the size of Microsoft is that sometimes people get things...Anonymous
June 07, 2006
Oguz: as you can see I've asked the same question, multiple times, but I can't seem to get an answer.Anonymous
June 09, 2006
It's not C++, its C#, coreyw.Anonymous
June 11, 2006
Hmm, apps built with this would probably crash on pre-Vista systems with a DLL not found error. Would there be a way to only DLLImport if the DLL exists? (And instead use an in-source function if it doesn't?)Anonymous
June 24, 2006
Sven Groot, the problem with this approach is that it is used for the Windows Forms package that comes with .NET. It doesn't have the power and extras that the WPF has (despite the fact that WPF was built upon .NET). You need to download the WPF Beta 2 (I think it comes with the WinFX SDK Beta 2) and go to the following website:
http://blogs.msdn.com/adam_nathan/archive/2006/05/04/589686.aspxAnonymous
July 11, 2006
I might have found a solution to the mouse inputs being sent to what ever is under the glass. Try setting the Trans. Key to some random color, one that will blend text well if possible. Then when the program start, if on Vista and glass is on, set the form background to that color.Anonymous
July 12, 2006
Okay. It looks great. But it doesn't work great. You get pick through the area where "Tim's Groovy Calender App" is displayed. Namely, once you click the area, you actually click something that is behide the Glassy Calender window, not the Glassy Calender window itself. Can we correct this?Anonymous
July 13, 2006
Windows Vista の特徴に半透明のウィンドウ フレームがあります。これは、Aero テーマが有効なときに表示されます。よく見ると、この半透明のウィンドウ フレームの裏側の画像には、ぼかしがかかっています。...Anonymous
July 21, 2006
Where I create a base class to allow windows forms to be all glassy.Anonymous
July 30, 2006
The solution to the problem actually lies in...Anonymous
August 05, 2006
How, would I get this right in VB6?Anonymous
August 15, 2006
PingBack from https://blogs.msdn.com:443/hiroyuk/archive/2006/07/14/665393.aspxAnonymous
September 05, 2006
This stuff doesn't work in RC1. Not even the sample application.
Can someone please post a recent tutorial that explains how to do this in RC1?Anonymous
September 06, 2006
Hi. First off, apologies for the long absence. This was due to some project commitments, however, that...Anonymous
September 12, 2006
this example does not work in Vista RC1 as SeBsZ said.
i've used another code in this site,
http://www.codeproject.com/useritems/textonglass.asp
it works, but controls like buttons, labels, textboxes
look so bad, i can't find a solution for it.Anonymous
September 13, 2006
stafadnymdalfoy@yahoo.co.tvAnonymous
September 13, 2006
For the most part, the Vista Desktop Window Manager is an end-user feature.  However, because it...Anonymous
October 30, 2006
The comment has been removedAnonymous
December 16, 2006
so, can anyone give this code in vb .net? i use .net, not c# for my apps... it'd be much appreciated.Anonymous
December 18, 2006
I downloaded the sample program and instead of glass it's just all black, I am running Vista (RC1).Anonymous
December 31, 2006
Aero Glass in WPFAnonymous
March 18, 2007
PingBack from http://www.se7ensins.com/forums/windows-vista-tutorials/49660-how-add-aero-glass-your-programs-using-c-programming.html#post350643Anonymous
March 20, 2007
Recently Tim shared some code for extending Windows Vista Aero "Glass" inside a Windows Forms windowAnonymous
March 25, 2007
A search on Google will return quite a lot of more or less complicated and complete articles on how to implement Windows Vista's Aero glass look in your own .NET applications. This posting will describe how to achieve this effect with as little code asAnonymous
September 25, 2007
PingBack from http://aongaang.wordpress.com/2007/09/26/%e0%b8%97%e0%b8%b3-aero-glass-%e0%b8%81%e0%b8%b1%e0%b8%9a-net-application-winapp/Anonymous
January 25, 2008
PingBack from http://dev.activebasic.com/egtra/?p=93Anonymous
February 03, 2008
PingBack from http://www.wh-forum.de/coding-webdesign-server/9883-vista-glass-erweitern-visual-basic.html#post197583Anonymous
February 16, 2008
PingBack from http://jakemchugh.com/blog/?p=126Anonymous
July 17, 2008
PingBack from http://chiafong6799.wordpress.com/2006/04/20/glass-more-glass-please/Anonymous
January 18, 2009
PingBack from http://www.keyongtech.com/613303-transparent-window