Export (0) Print
Expand All

Extend Glass Frame Into a WPF Application

This topic demonstrates how to extend the Windows Vista glass frame into the client area of a Windows Presentation Foundation (WPF) application.

Note Note

This example will only work on a Windows Vista machine running the Desktop Window Manager (DWM) with glass enabled. Windows Vista Home Basic edition does not support the transparent glass effect. Areas that would typically render with the transparent glass effect on other editions of Windows Vista are rendered opaque.

The following image illustrates the glass frame extended into the address bar of Internet Explorer 7.

Internet Explorer with extended glass frame behind address bar.

IE7 with glass frame extended behind address bar.

To extend the glass frame on a WPF application, access to unmanaged API is needed. The following code example does a Platform Invoke (pinvoke) for the two API needed to extend the frame into the client area. Each of these API are declared in a class called NonClientRegionAPI.

[StructLayout(LayoutKind.Sequential)]
public struct MARGINS
{
    public int cxLeftWidth;      // width of left border that retains its size 
    public int cxRightWidth;     // width of right border that retains its size 
    public int cyTopHeight;      // height of top border that retains its size 
    public int cyBottomHeight;   // height of bottom border that retains its size
};


[DllImport("DwmApi.dll")]
public static extern int DwmExtendFrameIntoClientArea(
    IntPtr hwnd,
    ref MARGINS pMarInset);

DwmExtendFrameIntoClientArea _udwm_dwmextendframeintoclientarea is the DWM function that extends the frame into the client area. It takes two parameters; a window handle and a MARGINS structure. MARGINS is used to tell the DWM how much extra the frame should be extended into the client area.

To use the DwmExtendFrameIntoClientArea function, a window handle must be obtained. In WPF, the window handle can be obtained from the Handle property of an HwndSource. In the following example, the frame is extended into the client area on the Loaded event of the window.

void OnLoaded(object sender, RoutedEventArgs e)
{
   try
   {
      // Obtain the window handle for WPF application
      IntPtr mainWindowPtr = new WindowInteropHelper(this).Handle;
      HwndSource mainWindowSrc = HwndSource.FromHwnd(mainWindowPtr);
      mainWindowSrc.CompositionTarget.BackgroundColor = Color.FromArgb(0, 0, 0, 0);

      // Get System Dpi
      System.Drawing.Graphics desktop = System.Drawing.Graphics.FromHwnd(mainWindowPtr);
      float DesktopDpiX = desktop.DpiX;
      float DesktopDpiY = desktop.DpiY;

      // Set Margins
      NonClientRegionAPI.MARGINS margins = new NonClientRegionAPI.MARGINS();

      // Extend glass frame into client area 
      // Note that the default desktop Dpi is 96dpi. The  margins are 
      // adjusted for the system Dpi.
      margins.cxLeftWidth = Convert.ToInt32(5 * (DesktopDpiX / 96));
      margins.cxRightWidth = Convert.ToInt32(5 * (DesktopDpiX / 96));
      margins.cyTopHeight = Convert.ToInt32(((int)topBar.ActualHeight + 5) * (DesktopDpiX / 96));
      margins.cyBottomHeight = Convert.ToInt32(5 * (DesktopDpiX / 96));

      int hr = NonClientRegionAPI.DwmExtendFrameIntoClientArea(mainWindowSrc.Handle, ref margins);
      // 
      if (hr < 0)
      {
         //DwmExtendFrameIntoClientArea Failed
      }
   }
   // If not Vista, paint background white. 
   catch (DllNotFoundException)
   {
      Application.Current.MainWindow.Background = Brushes.White;
   }
}

The following example shows a simple window in which the frame is extended into the client area. The frame is extended behind the top border that contains the two TextBox objects.

<Window x:Class="SDKSample.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Extended Glass in WPF" Height="300" Width="400" 
    Loaded="OnLoaded" Background="Transparent"
    >
  <Grid ShowGridLines="True">
    <DockPanel Name="mainDock">
      <!-- The border is used to compute the rendered height with margins.
           topBar contents will be displayed on the extended glass frame.-->
      <Border Name="topBar" DockPanel.Dock="Top" >
        <Grid Name="grid">
          <Grid.ColumnDefinitions>
            <ColumnDefinition MinWidth="100" Width="*"/>
            <ColumnDefinition Width="Auto"/>
          </Grid.ColumnDefinitions>
          <TextBox Grid.Column="0" MinWidth="100" Margin="0,0,10,5">Path</TextBox>
          <TextBox Grid.Column="1" MinWidth="75" Margin="0,0,0,5">Search</TextBox>
        </Grid>
      </Border>
      <Grid DockPanel.Dock="Top" >
        <Grid.ColumnDefinitions>
          <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <TextBox Grid.Column="0" AcceptsReturn="True"/>
      </Grid>
    </DockPanel>
  </Grid>
</Window>

The following image illustrates the glass frame extended into a WPF application.

Glass Frame Extended into a WPF Application.

Glass Frame Extended into a WPF application.
Show:
© 2014 Microsoft