Seesmic Look and Creating Aero Glass

by mheydt 21. January 2010 22:18 >

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.

Tags:

WPF

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.

twitter

I can't stop thinking big!
Sunday 1:08AM via WindowsLive
Just watched Moneyball. That's my pick for best movie this year.
Saturday 3:51PM via WindowsLive
@vincebelpiede: Report: Skype For Windows Phone Beta Imminent http://t.co/KYNjgg1L#mhtnd
Wednesday 8:39AM via Twitter for Mac
@mashable: Kinect Fusion Will Turn Gaming (and More) Into a 3D Fun House - http://t.co/Ihrq2fY2#mhtnd
Wednesday 8:39AM via Twitter for Mac
New Kinect SDK: http://t.co/57MvA5L5 #mhtnd
Wednesday 8:39AM via Twitter for Mac
Follow me on Twitter

recent comments

None

month list