Förläng glaspanel till en WPF-applikation

Det här avsnittet visar hur du utökar Windows Vista-glasramen till klientområdet i ett WPF-program (Windows Presentation Foundation).

Anmärkning

Det här exemplet fungerar bara på en Windows Vista-dator som kör Desktop Window Manager (DWM) med glas aktiverat. Windows Vista Home Basic Edition stöder inte transparent glaseffekt. Områden som normalt återges med transparent glaseffekt på andra utgåvor av Windows Vista återges ogenomskinliga.

Utökad glasram i ett adressfält

Följande bild illustrerar glasramen som utökas till adressfältet i Internet Explorer 7:

Skärmbild som visar en utökad glasram bakom IE7-adressfältet.

För att utöka glasramen i ett WPF-program krävs åtkomst till ohanterat API. I följande kodexempel används platform invoke (pinvoke) för de två API:erna som behövs för att utöka ramen till klientområdet. Vart och ett av dessa API deklareras i en klass som heter 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);
<StructLayout(LayoutKind.Sequential)>
Public Structure MARGINS
    Public cxLeftWidth As Integer ' width of left border that retains its size
    Public cxRightWidth As Integer ' width of right border that retains its size
    Public cyTopHeight As Integer ' height of top border that retains its size
    Public cyBottomHeight As Integer ' height of bottom border that retains its size
End Structure

<DllImport("DwmApi.dll")>
Public Shared Function DwmExtendFrameIntoClientArea(ByVal hwnd As IntPtr, ByRef pMarInset As MARGINS) As Integer
End Function

DwmExtendFrameIntoClientArea är DWM-funktionen som utökar ramen till klientområdet. Det tar emot två parametrar; ett fönsterhandtag och en MARGINS struktur. MARGINALER används för att tala om för DWM hur mycket extra ramen ska utökas till klientområdet.

Utökad glasram för den inlästa händelsen

Om du vill använda funktionen DwmExtendFrameIntoClientArea måste ett fönsterhandtag hämtas. I WPF kan man hämta fönsterhandtaget från egenskapen Handle för en HwndSource. I följande exempel utökas ramen till klientområdet vid Loaded-händelsen i fönstret.

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

Utökad glasram i klientområdet

I följande exempel visas ett enkelt fönster där ramen utökas till klientområdet. Ramen utökas bakom den övre kantlinjen som innehåller de två TextBox objekten.

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

Följande bild illustrerar glasramen utsträckt i ett WPF-program:

Skärmbild som visar en glasram utökad till ett WPF-program.

Se även