APIs in the Desktop Window Manager

For the most part, the Vista Desktop Window Manager is an end-user feature.  However, because it so fundamentally changes the game of how the desktop gets composed, there was both the opportunity and the requirement to introduce a relatively small number of APIs that impact how the DWM operates, and allows the programmer to take advantage of DWM features.  This post will discuss the functionality and APIs that we expose at a fairly high level, and reference MSDN documentation for drilling further in.

The DWM APIs are housed in dwmapi.dll, with declarations in dwmapi.h.  dwmapi.dll is a very thin DLL that in almost all instances, simply LPC's over to the dwm.exe process in order to fulfill the API request.  The DWM-related APIs fall into a number of categories:

  • Information querying and setting functionality
  • Scheduling and media presentation
  • Thumbnail registration manipulation
  • Client-area blur/glass manipulation

You can get more information about each of these in MSDN by searching at http://windowssdk.msdn.microsoft.com.  The point of this post is to try to tell a coherent story about the set of them, that hopefully contains some of the motivation.

Information Querying and Setting

There are a number of functions that provide basic information for querying and setting certain window and system attributes:

  • DwmEnableComposition - enables and disables composition.
  • DwmIsCompositionEnabled - returns whether or not composition is occurring.
  • DwmGetColorizationColor - returns the current window colorization information.
  • Dwm{Set,Get}WindowAttribute - controls various attributes on windows, including the policy for rendering the non-client area; policies on the "thumbnail representation" for a window -- whether it should truly be a thumbnail, or be an iconic representation;  how Flip3D treats a window; enable/disable DWM transitions for a window; policy controlling client's NC area painting; access to caption button bounds; etc.

Also, there are a number of Windows messages sent under different circumstances:

  • WM_DWMCOLORIZATIONCOLORCHANGED -- when the colorization color changes, apps can react to it as they see fit (for instance, if they have elements of their client area colored based on the colorization color.
  • WM_DWMCOMPOSITIONCHANGED -- when composition is turned on or off, this message is broadcast
  • WM_DWMNCRENDERINGCHANGED -- when the non-client area rendering status of a window has changed
  • WM_DWMWINDOWMAXIMIZEDCHANGE - windows can register to hear about when other windows have been maximized.  This is useful for, for instance, the TaskBar or the SideBar which go opaque when other windows get maximized.

Scheduling and Media Presentation

These functions allow for finer grained control of exactly when the desktop is composited and presented.  This is typically needed by media and video-playback applications for whom the DWM is running asynchronously from their own presentation schedule, which can lead to sampling artifacts if not tightly controlled.

  • DwmEnableMMCSS -- allows the DWM to participate in the Multimedia Class Schedule Service to have stronger control over the use of CPU resources in conjunction with another app using MMCSS (typically for video playback)
  • DwmGetCompositionTimingInfo -- provides information about the rate at which the DWM is composing, how many frames are completed, how many are pending, dropped frames, etc.
  • DwmModifyPreviousDxFrameDuration, DwmSetDxFrameDuration, DwmSetPresentParameters -- these allow applications to queue up multiple DirectX surfaces for presentation and precisely control when they're to be presented.  They're typically used by video presentation applications to counteract the latency that's inherent in a compositing system.

Thumbnail Registration and Manipulation

Thumbnails in the DWM are not static snapshots of a window.  They're dynamic, constant connections between a thumbnail source window, and a place on a target window that that source window will get a "thumbnail rendering".  Thus, a thumbnail is really a registration between a source HWND and a destination HWND.  Once a thumbnail is registered, one can update it's properties like the source and destination rectangles, opacity, visibility, and whether the source's NC area should be part of the thumbnail.

The functions available for thumbnail manipulation are:

  • DwmRegisterThumbnail -- establish a relationship between a source HWND and a destination HWND, and return a new thumbnail ID.
  • DwmUnregisterThumbnail -- end the relationship represented by the thumbnail ID.
  • DwmUpdateThumbnailProperties -- update source/destination rectangles, opacity, visibility, etc.
  • DwmQueryThumbnailSourceSize -- helper function ot figure out the source window size from a thumbnail, which is otherwise painful to figure out on your own.

The way thumbnails are implemented is effectively via the same VisualBrush mechanism that we have in WPF.  The DwmRegisterThumbnail API effectively creates a link into a node representing a window in the visual tree that makes up the desktop (discussed in this post), and references that node from the thumbnail target HWND.  Thus when the thumbnail source is a live video, the target HWND is rendered by rendering that live video there as well.  So these thumbnails are very much "live". 

I should also point out here that things like Flip3D cannot be built using the thumbnail API.  That's because thumbnails are always rendered head on in their target window in 2D.

Because of how thumbnails work as described here, it's possible to make interesting topologies of thumbnails -- for instance, having a thumbnail of another thumbnail, and nested further than that, is perfectly viable (though cycles are prohibited and checked for).  Having an application show many thumbnails in a window is just fine and in fact is exactly what Alt-Tab does in Vista Aero.  Thumbnails can also be any size -- in fact, they can even be larger than their original source.

Even though the Client-Area Blur/Glass APIs described below have gotten more initial attention in the community, I'm hopeful that the thumbnail APIs will be put to really interesting uses.  They really hold the promise of some very, very interesting uses.  So if you're out there reading this -- get inspired and do something cool with these and let me know... I'd love to post about it.

Client-Area Blurred Glass Manipulation

Lastly, there's the set of APIs for adding the blurred glass affect to the client area of your windows.  Many windows in Vista use this -- the Explorer and IE for their bread-crumb bar.  Windows Media Player for its transport controls.  Photo Gallery for its manipulation controls.  The Sidebar Gadget Picker puts its Gadgets on a big pane of glass.  The Alt-Tab UI is on a big pane of glass.  There are two primary means of getting blurred glass in your client area.  I'll explain with the first two function definitions:

  • DwmExtendFrameIntoClientArea - this insets from the margins and makes a border inset within the client area merge seamlessly with the blurred glass of the window frame.
  • DwmEnableBlurBehindWindow - this allows a GDI HRGN to be specified on a window, and the DWM will blur what's behind that region.

In both of these cases, it's the complete responsibility of the application to ensure that the areas being presented that will now have blurred glass behind them are rendered with the proper transparency values in the alpha channel.  Unfortunately, very few GDI functions respect alpha (really the "alpha blit" function in GDI is the only one that reliably does).  Thus you may be forced to render your GDI content offscreen, use memory operations to clean up the alpha channel, and then alpha blit back.

There's been a fair amount written in the community around how to use Client-Area Blurred Glass in your applications.  Here are some choice examples:

It's very important though to realize and honor the performance implications of using blurred glass in more parts of your window.  Since you can see through, updates in windows behind that otherwise wouldn't have caused repaints now do cause repaints.  And the blurring itself is a somewhat expensive operation that happens in the GPU.  So blurred glass should really be used sparingly in applications, and to good design purpose.