WPF GlassEffect For Non Vista OS

For those of us fortunate enough to own Windows Vista we can now see transparent windows that show the content behind our window through a glass window. This is down to the Desktop Windows Manager ability to extend the glass effect into the client area. This is however only possible on Windows Vista.

I had a little play around with WPF today and came up with a very crude (no resize window support) example for non Vista Windows versions that can run WPF. As I say its very crude but gives you the basic idea.

The idea is that you set the Window mode to AllowTransparency and set the WindowStyle to None, and then within any Glass enabled window you use some boiler plate code which mimics the Vista glass effect.

This is done via the use of a Canvas layout control. As Canvas allows objects to be placed using different ZIndex, you can create an overall semi-transparent area (the Glass) and then lay your controls on top of that. The only down side is that as canvas is an X/Y layout manager you will probably have to do at least 1 piece of code that makes sure the actual content is given the correct size you want.

 

Lets see the code, first the XAML

 .csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
   1:  <Window x:Class="GlassWindowForXP.Window1"
   2:      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   4:      Background="Transparent"
   5:      Title="Window1" Height="600" Width="800"
   6:      x:Name="Window">
   7:      <Canvas x:Name="canvmain">
   8:   
   9:          <Canvas.Resources>
  10:   
  11:              <ControlTemplate x:Key="imageButton" 
  12:                               TargetType="{x:Type Button}">
  13:                  <Image Source="{Binding 
  14:                      RelativeSource={RelativeSource TemplatedParent},
  15:                   Path=Tag}" Width="{TemplateBinding Width}"
  16:                         Height="{TemplateBinding Height}" 
  17:                         Stretch="Fill"/>
  18:              </ControlTemplate>
  19:   
  20:          </Canvas.Resources>
  21:   
  22:          <Rectangle Opacity="0.800000" x:Name="back"
  23:                     Width="{Binding ElementName=canvmain, 
  24:                      Path=ActualWidth}" 
  25:                     Height="{Binding ElementName=canvmain, 
  26:                      Path=ActualHeight}" 
  27:                     StrokeThickness="2.000000" Stroke="#55505050" 
  28:                     StrokeMiterLimit="1.000000">
  29:              <Rectangle.Fill>
  30:                  <LinearGradientBrush StartPoint="0.499999,0.019669" 
  31:                                       EndPoint="0.499999,0.957376">
  32:                      <LinearGradientBrush.GradientStops>
  33:                          <GradientStop Offset="0.000000" 
  34:                                        Color="#ffe8e8e8"/>
  35:                          <GradientStop Offset="1.000000" 
  36:                                        Color="#ffbababa"/>
  37:                      </LinearGradientBrush.GradientStops>
  38:                  </LinearGradientBrush>
  39:              </Rectangle.Fill>
  40:          </Rectangle>
  41:   
  42:          <DockPanel Margin="0" Background="Transparent" LastChildFill="True">
  43:              <DockPanel DockPanel.Dock="Top" Background="RoyalBlue" 
  44:                         Width="{Binding ElementName=canvmain, Path=ActualWidth}" >
  45:                  <Label x:Name="lblTitle" DockPanel.Dock="Left" 
  46:                         Content="{Binding Path=Title, ElementName=Window, 
  47:                          Mode=Default}" 
  48:                         VerticalAlignment="Center" FontFamily="Arial Rounded MT" 
  49:                         FontSize="12" FontWeight="Bold" Foreground="#FFFFFFFF" />
  50:                  <StackPanel DockPanel.Dock="Right" Height="30" Width="75" 
  51:                              Orientation="Horizontal" HorizontalAlignment="Right"  >
  52:                      <Button x:Name="btnMin" Width="21" Height="21" Margin="2" 
  53:                              Template="{StaticResource imageButton}" Tag="images/minimise.png" 
  54:                              HorizontalAlignment="Right" Click="btnMin_Click" 
  55:                              VerticalAlignment="Center"/>
  56:                      <Button x:Name="btnMax" Width="21" Height="21" Margin="2" 
  57:                              Template="{StaticResource imageButton}" Tag="images/maximise.png" 
  58:                              HorizontalAlignment="Right" Click="btnMax_Click" 
  59:                              VerticalAlignment="Center"/>
  60:                      <Button x:Name="btnClose" Width="21" Height="21" Margin="2" 
  61:                              Template="{StaticResource imageButton}" Tag="images/close.png" 
  62:                              HorizontalAlignment="Right" Click="btnClose_Click" 
  63:                              VerticalAlignment="Center"/>
  64:                  </StackPanel>
  65:              </DockPanel>
  66:   
  67:              <TabControl Margin="20" Height="400">
  68:                  <TabItem Header="TabItem">
  69:                      <Grid/>
  70:                  </TabItem>
  71:                  <TabItem Header="TabItem">
  72:                      <Grid/>
  73:                  </TabItem>
  74:              </TabControl>
  75:          </DockPanel>
  76:      </Canvas>
  77:  </Window>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

And here is the C# code for it

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:  using System.Windows;
   6:  using System.Windows.Controls;
   7:  using System.Windows.Data;
   8:  using System.Windows.Documents;
   9:  using System.Windows.Input;
  10:  using System.Windows.Media;
  11:  using System.Windows.Media.Imaging;
  12:  using System.Windows.Navigation;
  13:  using System.Windows.Shapes;
  14:   
  15:  namespace GlassWindowForXP
  16:  {
  17:      /// <summary>
  18:      /// Interaction logic for Window1.xaml
  19:      /// </summary>
  20:      public partial class Window1 : Window
  21:      {
  22:          public Window1()
  23:          {
  24:   
  25:              this.WindowStyle = WindowStyle.None;
  26:              this.AllowsTransparency = true;
  27:              this.Background = new 
  28:                  SolidColorBrush(Color.FromArgb(0, 34, 34, 34));
  29:              InitializeComponent();
  30:          }
  31:   
  32:          protected override void 
  33:              OnMouseLeftButtonDown(MouseButtonEventArgs e)
  34:          {
  35:              base.OnMouseLeftButtonDown(e);
  36:              this.DragMove();
  37:          }
  38:   
  39:          private void btnClose_Click(object sender, RoutedEventArgs e)
  40:          {
  41:              this.Close();
  42:          }
  43:   
  44:          private void btnMin_Click(object sender, RoutedEventArgs e)
  45:          {
  46:              this.WindowState = WindowState.Minimized;
  47:          }
  48:   
  49:          private void btnMax_Click(object sender, RoutedEventArgs e)
  50:          {
  51:              this.WindowState = WindowState.Maximized;
  52:          }
  53:      }
  54:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

And here is what it looks like running

image

 

And here is a link to the source code glasswindowforxp.zip as I say this is very crude, and wouldn’t be suitable for production code the way it is, but it gives you a starting point

Advertisements

6 thoughts on “WPF GlassEffect For Non Vista OS

  1. Martin says:

    Well that’s quite nice, but this isn’t Glass. This is only Transparancy.
    What about this:
    .NET 3.5 SP1 supports custom BitmapEffects. You could write your own “Glass-Effect” and apply it to your Canvas… Would this work? I guess not, as the background isn’t accesible… but maybe one could combine this with a static screenshot used as background image…
    Just an idea… 🙂

  2. sacha says:

    I have got .NET 3.5 SP1 installed and the Effects are mjuch better, but I have not investigated this yet. BUt good idea man

  3. Jens Peter says:

    It would help to add some blur, you really do not need custom bitmap effects to achieve that.

  4. chaiguy1337 says:

    Unfortunately a blur bitmap effect (even in 3.5 SP1) will not blur anything external to the window. It would be nice if it did though; I’m still not sure how Vista does that blur effect on its windows.

  5. sacha says:

    I think you need to dig deep into the Dwm…Thats C++ all the way I feel.

  6. cheap car insurance 21 says:

    A pleasure to look at, go on with this! Thanks!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: