Seesmic Look and Creating Aero Glass

Today I downloaded the freshly released Seesmic Look application. This is a twitter client that I think makes really great use of WPF. Here's a screen shot:



There are a number of great things going on here, one of which is the use of Aero glass in the WPF application. Notice how the desktop wallpaper blends through the upper part of the window. This is a pretty simple thing to do, but not well documented. There are a few links to information on how to do this that I'll enumerate here, as well as show how to do this in a sample application.

There are a number of great things going on here, one of which is the use of Aero glass in the WPF application. This is a pretty simple thing to do, but not well documented. There are a few links to information on how to do this that I'll enumerate here, as well as show how to do this in a sample application.

The two links that I found useful are:
http://blogs.msdn.com/adam_nathan/archive/2006/05/04/589686.aspx
http://blogs.msdn.com/wpfsdk/archive/2008/09/08/custom-window-chrome-in-wpf.aspx

Adam gives some code for doing this trick in WPF. I'll reproduce the entire code of the class and an implementation for completeness.

The class for forcing glass into your window is this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Media;
using System.Windows.Interop;

namespace SocialBus.Navigator.Glass
{
    public class GlassHelper
    {
        [DllImport("dwmapi.dll", PreserveSig = false)]
        static extern void DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS margins);

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

        [DllImport("user32.dll")]
        static extern uint GetWindowLong(IntPtr hWnd, int nIndex);

        [DllImport("user32.dll")]
        static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);

        private const int GWL_STYLE = -16;
        private const uint WS_SYSMENU = 0x80000;

        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;
        }
       
        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;
        }
    }
}

Now to get the window to use this, we just need to hook up the OnSourceInitialized event/override in the main window control of the application as such:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;

using SocialBus.Navigator.Glass;

namespace SocialBus.Navigator
{

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);

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

When running this, the window looks like this:

Very nice! Notice also that I have removed the system icon and title from the window. The title is easy to remove by just setting the Title in the xaml to "". The icon is a little more difficult. You just cant set the Icon property on the window control to null, as WPF takes that as meaning that you want to use the default icon. What you need to do is prvoide a transparent icon. At first I was wondering how you make an .ico file with a transparent background (I dont think you can actually). But fortunately the flexibility of WPF allows for using a .png file for an icon, so I just made a 16x16 png file that was all transparent.

To follow up this post, I actually have some nice twitter control in the works and will add those to this window to show how nice things can look with this technique.

blog comments powered by Disqus

About the author

I'm a .NET, XAML, and iOS polyglot that loves playing with new things and making cool and innovative stuff.  I am also a Mac junkie.

I am Principal Technologist for SunGard Global Services in NYC, in their Advanced Technologies practice, and I work extensively with SunGard's energy and financial customers.

Note the the posting on this blog are my own and do not represent the position, strategies or opinions of SGS.

Widget TwitterFeed not found.

The file '/widgets/TwitterFeed/widget.ascx' does not exist.X

Recent Comments

None

Month List