Archives

Archives / 2006 / August
  • Windows Vista for Developers – Part 3 – The Desktop Window Manager

    Although Windows 95 (and Window NT 3.51) introduced Windows developers to non-rectangular windows, through the ability to set the window region for a given window using the SetWindowRgn function, this did not provide transparency since the window was still completely opaque and merely afforded the developer some control over the window’s shape. Windows 2000 introduced layered windows by means of the WS_EX_LAYERED extended window style and developers were finally able to control not only the shape but also the level of transparency within the window region. Windows Vista introduces yet another twist on the road away from non-rectangular windows by allowing developers to apply translucency to portions of a window.

    In this part 3 of the Windows Vista for Developers series, we are looking at the Desktop Window Manager (DWM) API. The DWM is responsible for the composition of windows on the desktop and the DWM API allows developers to control how composition affects a particular window. As you will see, the DWM is responsible for much more than just “glass”. We will also look at the existing functionality for transparency that Windows Vista inherited from Windows 2000 and see how it complements the new DWM functionality.

    Terminology

    When it comes to graphics, the terminology can be confusing. Here are some common terms you should be familiar with when working with transparency and translucency in Windows.

    Transparency – Refers to the ability to see through something clearly and without obstruction. Think of it as clear glass. Some applications and APIs use the term transparency to refer to a scale that ranges from “completely” transparent to “completely” opaque.

    Translucency – People often use translucency and transparency interchangeably but they actually mean very different things. Translucency refers to the ability to see through something where the background appears unclear whether it is out-of-focus or simply blurry in some way. Windows Vista refers to the glass effect as “transparent glass” when it technically should be called translucent glass.

    Opacity – Opacity refers to the state of being opaque and opaque refers to something that is neither transparent nor translucent. Some applications and APIs use the term opacity to refer to a scale that ranges from completely opaque to completely transparent.

    Alpha Channel – An alpha channel provides additional information for each pixel in an image that facilitates compositing images together.

    Window Regions – A window’s region determines the area within the window where system permits painting. Although Windows 95 supported window regions, it was not until Windows XP that the default theme used regions to present windows with rounded corners. Although the default Windows Vista theme also presents windows with rounded corners, regions are no longer used unless you resort to the Windows Vista Basic theme.

    Glass – Glass is the catchy marketing terms that Windows Vista uses to refer to translucency.

    Blur – Some of the DWM APIs refer to blur and again this indicates translucency. Presumably, the Windows developers felt it was easier to spell and comprehend.

    Desktop Composition – The DWM performs desktop composition, enabling visual effects on the desktop such as glass, 3D window transitions, etc.

    RGB – RGB is short for Red, Green and Blue. RGB values are typically packed into a COLORREF (which is just a DWORD) as follows: 0x00BBGGRR. As you can see, the first byte is always zero and the remaining three bytes store the individual red, green and blue values in reverse order. Each color value ranges from zero through 255. If all three values are zero then the result is black. If all three values are 255 then the result is white. For example, to represent red specify 0x000000FF. You can also use the RGB macro as follows: RGB(255, 0, 0). As you can see, RGB does not provide an alpha channel.

    ARGB – ARGB is short for Alpha, Red, Green and Blue. ARGB values are typically packed into an ARGB (which is just a DWORD) as follows: 0xAARRGGBB. The first byte stores the alpha value and the remaining three bytes store the red, green and blue values. Note that the color values are stored in the opposite order to RGB.

    GDI – The Windows Graphics Device Interface (GDI) API is the original graphics interface used for 2D drawing in Windows. With the exception of a few newer functions, the GDI API does not honor the alpha channel in images. GDI uses RGB values to represent color.

    GDI+ – GDI+ was introduced with Windows XP (and Windows Server 2003) to provide a more capable programming model for 2D drawing, imaging and typography and fully supports alpha blending. GDI+ uses ARGB values to represent color. Incidentally, GDI+ powers the the System.Drawing library in the .NET Framework.

    Is Composition Enabled?

    With the terminology out of the way, we can now dive into the guts of desktop composition. Of course, to take advantage of it we need to make sure that it is actually available at runtime. The user may have disabled desktop composition for performance reasons. This can be done as follows:

    1. Open the System Properties window using the following command:

        %windir%\system32\SystemPropertiesAdvanced.exe

    2. Click the Performance Settings button.

    3. Either check or clear the “Enabled desktop composition” check box.

    Keep in mind that desktop composition is independent of “glass”. Although glass requires desktop composition, you can use desktop composition while disabling glass.

    Windows Vista provides the DwmIsCompositionEnabled function to determine whether composition is currently enabled. Consider the following example:

    BOOL enabled = FALSE;
    HRESULT result = ::DwmIsCompositionEnabled(&enabled);

    Of course, this is not especially useful if you are targeting older platforms as your application will fail to load since it will be linked to a library that is not available. One solution is to use a blend of delay loading and runtime dynamic linking. The DWM API is provided by the dwmapi.dll library and to ensure that your application will load on older platforms you can use Visual C++’s Delay Load facility to only load the DWM library if it is actually used. The first step is to instruct the linker to delay load the DWM library. This can be done as follows:

    1. Open the project’s property pages.

    2. Navigate to the Linker > Input section.

    3. Add dwmapi.dll to the list of Delay Load DLLs. You should already have dwmapi.lib in the list of Additional Dependencies to allow the linker to find the various DWM API functions that you make use of.



    With this in place, the DWM library will only be loaded the first time you call any of its functions, but how do you know whether it is safe to do so? After all, calling DwmIsCompositionEnabled will attempt to load the DWM library and crash your application on older versions of Windows. The solution is to manually attempt to load the DWM library and for good measure attempt to retrieve the address of a DWM function. Consider the following wrapper function:

    bool IsCompositionEnabled()
    {
        HMODULE library = ::LoadLibrary(L"dwmapi.dll");
        bool result = false;

        if (0 != library)
        {
            if (0 != ::GetProcAddress(library,
                                      "DwmIsCompositionEnabled"))
            {
                BOOL enabled = FALSE;
                result = SUCCEEDED(::DwmIsCompositionEnabled(&enabled)) && enabled;
            }

            VERIFY(::FreeLibrary(library));
        }

        return result;
    }

    The IsCompositionEnabled function attempts to load the DWM library and retrieve the address of the DwmIsCompositionEnabled function. If this is successful, you can assume it is running on Windows Vista or later. It then simply calls the DwmIsCompositionEnabled function, which will actually load the DWM library, to determine whether composition is enabled. Now you simply have to ensure that you do not call any other DWM functions if IsCompositionEnabled returns false.

    The other thing to keep in mind is that since the user, and other applications for that matter (more on this in a moment), can enable and disable desktop composition at any time, your application needs to be able to cope with changes in the availability of desktop composition. The system will send your window the WM_DWMCOMPOSITIONCHANGED message to indicate that the availability of desktop composition has changed. The WPARAM and LPARAM values are not used so you must call the DwmIsCompositionEnabled function again to determine the current state of desktop composition.

    As I hinted at, it is possible for applications to temporarily disable desktop composition for the lifetime of the application or for some subset thereof. The DwmEnableComposition function allows you to disable desktop composition for the entire desktop. Desktop composition will be disabled until you call DwmEnableComposition again to enable it. If you fail to re-enable desktop composition, the system will automatically enable it when the application exits.

    The following code disables composition:

    HRESULT result = ::DwmEnableComposition(DWM_EC_DISABLECOMPOSITION);

    And the following code will enable it again:

    HRESULT result = ::DwmEnableComposition(DWM_EC_ENABLECOMPOSITION);

    Assuming you are using the default Windows Vista theme, these calls will toggle between the new “Window Vista” and “Windows Vista Basic” themes. Just remember, when you application exits, composition will be reset regardless of whether you re-enabled it.

    Is Composition Translucent?

    As I mentioned in the previous section, the fact that desktop composition is enabled does not necessarily mean that the “glass” is translucent. I took the following two window clippings of the exact same window. The one on the left was taken with translucent glass and the one of the right with opaque glass. As you can see, the translucent glass provides a hint of the desktop background color as well as the recycle bin hiding underneath the window whereas the opaque glass only offers the aurora effect provided by the DWM.