Aero Glass inside a WPF Window


Recently Tim shared some code for extending Windows Vista Aero “Glass” inside a Windows Forms window.  It sounds like he’s eventually planning on showing this with WPF (among other things).  I also looked into this for my upcoming WPF book, and I couldn’t wait to share the results of my little WPF glass experiment!  Sorry, Tim, if I’m stealing your thunder!


NOTE: This code will require WPF Beta 2 or later (and Windows Vista).  I’ll share the whole project (including an updated Internet Hearts app) when Beta 2 is released.


I took the WPF UI I created for the Internet Hearts migration, slapped it in a System.Windows.Window, and “glassified” it.  Here is the result:


I didn’t change a thing in the Hearts UI, and everything worked as expected: the 2D & 3D animations, the elements that already had partial opacity (like the card table), etc.


And when doing a “Flip 3D” (which I’m surprisingly finding more useful than the standard Alt+Tab), the result is pretty cool:


Of course, I’m now breaking all sorts of style, usability, and performance guidelines by my overzealous use of glass, but it’s still an interesting exercise!


All it took was this function, which extends the glass frame into the client area of any WPF Window based on the passed-in margin:


public class GlassHelper
{
  public static bool ExtendGlassFrame(Window window, Thickness margin)
  {
    if (!DwmIsCompositionEnabled())
      return false;


    IntPtr hwnd = new WindowInteropHelper(window).Handle;
    if (hwnd == IntPtr.Zero)
      throw new InvalidOperationException(“The Window must be shown before extending glass.”);


    // Set the background to transparent from both the WPF and Win32 perspectives
    window.Background = Brushes.Transparent;
    HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor = Colors.Transparent;


    MARGINS margins = new MARGINS(margin);
    DwmExtendFrameIntoClientArea(hwnd, ref margins);
    return true;
  }

}


We need the HWND of the Window to pass to DwmExtendFrameIntoClientArea, and WindowInteropHelper enables us to get it.  The MARGINS structure controls how much to extend the glass on each of the four sides.  To get the “sheet of glass” effect, you can pass -1 for all four sides.


The trickiest thing is knowing to set not only Window’s Background to Transparent, but also the BackgroundColor of the corresponding HwndSource’s CompositionTarget (which is set to black by default).


The MARGINS structure passed to DwmExtendFrameIntoClientArea is similar in spirit to WPF’s Thickness type, so I chose to expose Thickness from ExtendGlassFrame and defined MARGINS with a constructor that does the conversion:


struct MARGINS
{
  public MARGINS(Thickness t)
  {
    Left = (int)t.Left;
    Right = (int)t.Right;
    Top = (int)t.Top;
    Bottom = (int)t.Bottom;
  }
  public int Left;
  public int Right;
  public int Top;
  public int Bottom;
}


The two DWM APIs are defined as follows:


[DllImport(“dwmapi.dll”, PreserveSig=false)]
static extern void DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS margins);


[DllImport(“dwmapi.dll”, PreserveSig=false)]
static extern bool DwmIsCompositionEnabled();


Finally, the Window calls ExtendGlassFrame inside OnSourceInitialized:


protected override void OnSourceInitialized(EventArgs e)
{
  base.OnSourceInitialized(e);
  // This can’t be done any earlier than the SourceInitialized event:
  GlassHelper.ExtendGlassFrame(this, new Thickness(-1));
}


Note that with Thickness I can pass a single value (-1) that will be used for all four MARGIN fields.


I’m going to add dwmapi.dll (and other Windows Vista DLLs) to pinvoke.net so folks can start sharing managed signatures for new APIs such as this.  Enjoy!

Comments (26)

  1. Eli says:

    Someone really needs to add some glass support to Window Forms.

  2. Adam Nathan says:

    Eli, see http://blogs.msdn.com/tims/archive/2006/04/18/578637.aspx.  Or were you hoping for more built-in support?

  3. keeron says:

    Any idea if there are plans to ship the DWM library (or similar library for Aero) for XP? I see lot of new applications that are built for Vista, also being supported on XP.. and like old times, we’ll see

    if(VER < 6)

    … no glass

    if(Ver >= 6)

     … glass…

  4. Adam Nathan says:

    keeron, you’re right.  You’ll have to do something like

    if (System.Environment.OSVersion.Version.Major < 6 || !DwmIsCompositionEnabled())

      // No glass

    else

      // glass

    Fortunately, in the case of glass it’s pretty easy to have reasonable fallback behavior.  And applications that only run on Windows Vista need to consider this anyway in case the user doesn’t have glass enabled.

  5. CedarLogic says:

    I&amp;rsquo;m starting to see more applications leveraging Aero Glass on Vista.&amp;nbsp; They look quite cool.&amp;nbsp;…

  6. Kevin Daly says:

    I don’t have anything intelligent to say, I just want to observe that that effect looks absolutely beautiful.

    Nifty-as-you-know-what.

  7. sheldon says:

    I assume this requires Vista and can not be executed on XP running the WinFX installation.

    Just checking.

  8. imothep says:

    Hi

    I see you’re right…i’d like to ask you, how can make glass effect in vb.net if im usin xp. If it’s possible please somebody write me a little code to use it.

    Thnx

  9. Currently, I am struggling with WinFX and I must admit that I do not like the way how WPF (Windows Presentation…

  10. Pablo Fernicola says:

    The DWM functionality will not be available on XP.  It is Windows Vista only, requires the new driver model (WDDM).

    -Pablo

  11. Kam VedBrat says:

    The great thing about working at a company the size of Microsoft is that sometimes people get things…

  12. Adam, thanks for the !DwmIsCompositionEnabled function. That is most of the solution for the problem I was having in my WinForms app. Question, though: is there an event I can subscribe to that my WinForms app can handle incase Composition state changes? The problem I’m having is that I do my dev work in VirtualPC, and VPC turns DesktopComp off. So When I test my app, and DesktopComp goes off, it looks terrible. But since there’s no event to handle… can’t fix it. Any thoughts?

    Thanks!

  13. Searching from google about WPF, I found a cool blogger. His name is Adam Nathan, He is good in Win32API…

  14. Hi,

    Beta 2 has been released, don’t want to beg, but: Can we have the code?

    Thanks! 😀

  15. jpelak says:

    Does this still work on June CTP + 5456?

  16. Hi. First off, apologies for the long absence. This was due to some project commitments, however, that…

  17. For the most part, the Vista Desktop Window Manager is an end-user feature.&amp;nbsp; However, because it…

  18. Shell Blog says:

    One of the reasons we created this site was to give some insight into feature design decisions or why

  19. I Got Rhythm says:

    Style Snooper (or StyleSnooper?), originally posted by Lester, is a tool that can extract control styles

  20. 匡匡 says:

    今天在网上看到一篇讲解在 WPF 窗口内部使用 Aero 效果的文章。文章地址 Aero Glass inside a WPF Window

  21. Hi. First off, apologies for the long absence. This was due to some project commitments, however, that