Aracılığıyla paylaş


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 https://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.

Comments

  • Anonymous
    September 14, 2006
    "This is useful for, for instance, the TaskBar or the SideBar which go opaque when other windows get maximized."

    Please please PLEASE tell me there's a way to turn that off, it's horribly annoying and distracting and inconsistent, not to mention ugly.  Same with the window border/title...

    Otherwise, thanks for the info.  You mention that Flip3d cannot be built with the Thumbnail API... how could, in fact, something like that be built?

  • Anonymous
    September 14, 2006
    Are there any APIs available to actually manipulate/size/move the compositor windows.  ie. to let a third party build Expose or Spaces functionality, or something better?

  • Anonymous
    September 14, 2006
    I noticed that the WPF screen update rate is pretty low under DWM in Vista RC1. It's not at fast as for example dragging windows on the desktop. Can I change this rate in a WPF application?

  • Anonymous
    September 14, 2006
    The comment has been removed

  • Anonymous
    September 14, 2006
    The comment has been removed

  • Anonymous
    September 16, 2006
    Theoretically... couldn't an Expose-like application be written using the thumbnail API? (so long as you aren't doing any 3D rotation stuff like Flip 3D)

  • Anonymous
    September 17, 2006
    I can't remember where I saw it (somewhere in an MS blog, to narrow it down a bit ;) ) but I remember seeing a blog post within the past couple of days from a guy who had written an Exposé-like app and was gonna post it on CodePlex.

  • Anonymous
    September 17, 2006
    Mike : The thing you saw was probably this :
    http://blogs.labo-dotnet.com/simon/archive/2006/09/12/11116.aspx.
    That is in french (yes, I am, sorry ^^), and there is no error / exception handling at all.
    The trigger-key is F12 (not configurable in this early version).

    This code is using exclusively Dwm thumbnails (via calls to DwmUpdateThumbnailProperties) and is not really performant... That is a shame that in a Vista / Framework .Net 3.0 environment, there is no way to obtain a VisualBrush from these thumbnails.

  • Anonymous
    September 21, 2006
    Hi Greg,

    I have a question about declerations of DwmSetDxFrameDuration and DwmModifyPreviousDxFrameDuration in dwmapi.h

    They recieve cRefreshes as Int32.
    Should I pass the DXRefreshes to these APIs?
    If so, please update the declerations like this.

    // cRefreshes -> cDXRefreshes

    DWMAPI
    DwmSetDxFrameDuration(
       HWND hwnd,
       INT cDXRefreshes
       );

    DWMAPI
    DwmModifyPreviousDxFrameDuration(
       HWND hwnd,
       INT cDXRefreshes
       BOOL fRelative
    );

  • Anonymous
    September 22, 2006
    Glass nugget

  • Anonymous
    September 27, 2006
    I've seen a couple of cool uses in the past week of the DWM Thumbnail API (described in my previous post)...

  • Anonymous
    October 09, 2006
    Making Thumbnails that are larger than the original window seems like it might be useful for an updated version of the Magnafier accessibility tool assuming it can be cropped.   Well, I guess it would also require being able to thumbnail the entire screen rather than just one window at a time, but if it can do that (I don't know but not according to my understanding) then it would be perfect.

  • Anonymous
    November 29, 2006
    Using Application Thumbnails in Vista

  • Anonymous
    January 20, 2009
    PingBack from http://www.hilpers.com/268101-wie-kann-man-das-win

  • Anonymous
    June 15, 2009
    PingBack from http://mydebtconsolidator.info/story.php?id=11470