Dax Pandhi's nAESTHETIC Dax Pandhi's nAESTHETIC Dax Pandhi's nAESTHETIC Subscribe to this Blog's RSS feed Subscribe to my DeviantArt RSS feed

Popular art from my DeviantArt account:


  Saturday, September 23, 2006


How to use Aero Glass in your WPF applications

Aero Glass
Just about everyone making (or thinking of making) an application for Windows Vista wants to try out the cool new Aero User Experience. Software such as Windows Media Player, Windows Calendar, and the Windows Sidebar really show off the Aero glass look.

While overusing the glass bit is a certain possibility (and a probability), using it judiciously can seriously help spice up your app. A few things to keep in mind when using Aero Glass:

  • Avoid a full glass window. This creates performance as well as usability issues.
  • Use full glass windows only for non-resizable, non-maximizing windows.
  • The glass portions of the window should always allow the entire window to be dragged.
  • When designing the window, keep in mind what it will look like in a pre-Vista OS – i.e., without glass. Always have a non-Glass look ready to fall back on if Aero is disabled or if the app is run on an older Windows.

This exercise will require a good GPU (128MB AGP recommended).

Thanks to Adam Nathan for the original code!

The Code

Create a new code file and add the following code:

using System;

using System.IO;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Navigation;

using System.Windows.Interop;

using System.Runtime.InteropServices;

using System.Collections.Generic;

 

namespace AeroGlassExample

{

    public class GlassHelper

    {

        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;

        }

 

        [DllImport("dwmapi.dll", PreserveSig = false)]

        static extern void DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS margins);

 

        [DllImport("dwmapi.dll", PreserveSig = false)]

        static extern bool DwmIsCompositionEnabled();

 

 

        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

            SolidColorBrush background = new SolidColorBrush(Colors.Red);

            background.Opacity = 0.5;

            window.Background = Brushes.Transparent;

            HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor = Colors.Transparent;

 

            MARGINS margins = new MARGINS(margin);

            DwmExtendFrameIntoClientArea(hwnd, ref margins);

            return true;

        }

    }

} 

 

In your Window.xaml file, make the DocumentRoot object's Background to NULL then just insert the following code (marked in bold) in the codebehind file:

using System;

using System.Text;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Imaging;

using System.Windows.Shapes;

 

namespace AeroGlassExample

{

    /// <summary>

    /// Interaction logic for Window1.xaml

    /// </summary>

       

    public partial class Window1 : System.Windows.Window

    {

       

        private bool neverRendered = true;

       

        public Window1()

        {

            InitializeComponent();

            this.SourceInitialized += new EventHandler(Window1_SourceInitialized);

     

        }

       

        void Window1_SourceInitialized(object sender, EventArgs e)

        {

            GlassHelper.ExtendGlassFrame(this, new Thickness(-1));

        }

       

        protected override void OnContentRendered(EventArgs e)

        {

            if (this.neverRendered)

            {

                // The window takes the size of its content because SizeToContent

                // is set to WidthAndHeight in the markup. We then allow

                // it to be set by the user, and have the content take the size

                // of the window.

                this.SizeToContent = SizeToContent.Manual;

       

                FrameworkElement root = this.Content as FrameworkElement;

                if (root != null)

                {

                    root.Width = double.NaN;

                    root.Height = double.NaN;

                }

       

                this.neverRendered = false;

            }

       

            base.OnContentRendered(e);

        }

       

    }

       

}




You will get the following result:



If you replace the thickness(-1) with thickness(5,70,5,42) you get something like this:



You can download the full code below. It requires Windows Vista RC1 or later, .NET Framework 3.0 (RC1), and Microsoft Expression Interactive Designer September CTP.

AeroGlassExample.zip (14.43 KB)









3/29/2008 4:09:13 PM (India Standard Time, UTC+05:30)
Hi Dax!
Nice work.
What if you want to drag the window when you drag from that glass?
Any ideas?


Cheers,
Aakash
Name
E-mail
Home page

Comment (HTML not allowed)  

Enter the code shown (prevents robots):

Copyright � 2005-2007 Dax Pandhi. All rights reserved.
designed by nukeation
Sign In