In Depth Banner
Skip Navigation Links

Layered Windows

Windows Forms applications regularly use the LayeredWindow API when translucent forms are used but the control over it is rudimentary only allowing you to set the opacity of a given window. The LayeredWindow API is much more useful than that and is easy to use even though there is no direct support for it in the .NET framework and we are forced to resort to interop to get it going.

This article will deal with the simpler of the two LayeredWindow API calls, SetLayeredWindowAttributes.

Essentially, a layered window is a form of double buffering. The WM_PAINT call for a layered window is fired as normal but the hDC returned by the BeginPaint method call refers to an in-memory bitmap that used to store the contents of the window. That back-buffer can then be drawn to the screen with an element of transparency by setting the alpha level of the window. This is the way that Form.Opacity works. The other thing the SetLayeredWindowAttributes API can do is create a non-rectangular window by using a transparency colour key. Layered windows with transparent areas defined in this way are also transparent to mouse clicks in those areas so you can put layered windows to all sorts of interesting uses. Furthermore, because the alpha of a layered window may be adjusted at any time, you can create fade-in or out effects that soften the appearance or disappearance of a window.

HandyClock.

Displaying the time on the taskbar isn't mandatory and many people chose not to see it forever presented on the screen. On-screen clock applications are quite commonplace but tend to take up a lot of screen real-estate for such an infrequently used function. The demo application for this article shows off a novel use of layered windows in a Windows Forms control that provides a tiny clock which has hidden powers. Figure 1 shows the application running the handy clock control.

Figure 1. The handy clock.

Notice how the little clock-face displays the time. This is updated with the system clock and is dynamic. It's just about readable at a glance and only takes up 400 pixels of screen real-estate. If you ever want to get a real view of the time though you only need to float your mouse over the clock and the image in Figure 2 will give you a great representation instantly.

Figure 2. The HandyClock's hidden talent.

The big clock fades into view in the center of the screen, waits for a few seconds and fades away again. It also fades away if you float the mouse over any part of the clock. This stops if from interfering with the work you're doing.

Creating the window

If you wish to use the LayeredWindow system, the window must be created or adjusted to have the WS_EX_LAYERED style. This can be done by setting up a CreateParams class to contain the correct settings. In this example, the window is based on NativeWindow and uses the tooltips_class32 window class for conveinience because it doesn't show up in the task-bar. This code shows how the CreateParams are initialized for the creation of the window.

Setting the attributes

There are two distinct settings you can force onto a layered window. The transparency key colour and the level of alpha. Under normal circumstances, the window will be rectangular or conform to a window region if you choose to create one. In the case of the handy clock, the white background is nominated as the transparent colour. The alpha setting affects all of the non-transparent pixels and enable you to set the level of opacity in a range of 0-255 where 0 is fully transparent and 255 is fully opaque.

The code for the clock uses a timer that fires 20 times a second to refresh the big clock display. It only remains on-screen for about four seconds and the clock gradually increases opacity, remains fully opaque and then fades back to complete transparency before being destroyed. This code services the timer-tick event and performs the function of refreshing the clock and setting the attributes.

The tiny clock

This simple class does very little except display a few lines by calculating the positions and angles of the hands for the clock face and services the holder of end to create the larger window.  This listing shows the HandyClock control.

The Big Clock

This listing shows the code for the big clock. For variety, the method of rotating the hands has been changed form that of the HandyClock class. Matrices are used instead. The principles are fairly simple. A window with the WM_EX_TRANSPARENT style is created and a timer is set up to fire at regular intervals. When the timer fires, the current transparency setting of the window is calculated enabling it to fade in, rest for a few seconds and fade out again. When the window is painted the white background is made transparent. White was chosen because a garish colour such as Magenta which is often used for transparency keys prevents the use of antialiasing in the draw routine. If Magenta is used all the clock components seem to have a pink halo around them. Remeber to have a good look at the Interop explanations and code.

You can find the Source Code files here.

Return to the main index.

Copyright © Bob Powell 2003-2009. All rights reserved