Freigeben über


Erweitern von Glasframe in eine WPF-Anwendung

Aktualisiert: November 2007

In diesem Thema wird veranschaulicht, wie Sie einen Windows Vista-Glasframe in den Clientbereich einer Windows Presentation Foundation (WPF)-Anwendung erweitern.

Tipp

Dieses Beispiel funktioniert nur auf einem Windows Vista-Computer, auf dem der Desktopfenster-Manager (DWM) mit aktiviertem Glaseffekt ausgeführt wird. Windows Vista Home Basic-Edition unterstützt den transparenten Glaseffekt nicht. Bereiche, die in anderen Editionen von Windows Vista normalerweise mit dem transparenten Glaseffekt gerendert werden würden, werden nicht transparent gerendert.

Beispiel

Die folgende Abbildung zeigt den in die Adressleiste von Internet Explorer 7 erweiterten Glasframe.

Internet Explorer mit erweitertem Glasframe hinter der Adressleiste.

IE7 mit sich hinter die Adressleiste ausdehnendem Glasrahmen

Um den Glasframe in eine WPF-Anwendung zu erweitern, ist der Zugriff auf die unverwaltete API erforderlich. Das folgende Codebeispiel führt einen Plattformaufruf (pinvoke) für die beiden APIs aus, die erforderlich sind, um den Frame in den Clientbereich zu erweitern. Jede dieser APIs wird in einer Klasse mit dem Namen NonClientRegionAPI deklariert.

[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 ist die DWM-Funktion, die den Frame in den Clientbereich erweitert. Es werden zwei Parameter übernommen: ein Fensterhandle und eine MARGINS-Struktur. MARGINS legt für den DWM fest, wie weit der Frame in den Clientbereich erweitert werden soll.

Um die DwmExtendFrameIntoClientArea-Funktion zu verwenden, muss ein Fensterhandle abgerufen werden. In WPF kann das Fensterhandle aus der Handle-Eigenschaft einer HwndSource abgerufen werden. Im folgenden Beispiel wird der Frame in den Clientbereich des Loaded-Ereignisses des Fensters erweitert.

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

Das folgende Beispiel zeigt ein einfaches Fenster, in dem der Frame in den Clientbereich erweitert wird. Der Frame wird hinter dem oberen Rand erweitert, der die beiden TextBox-Objekte enthält.

<Window x:Class="SDKSample.Window1"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://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>

Die folgende Abbildung zeigt den in eine WPF-Anwendung erweiterten Glasframe.

Glasframe, erweitert in eine WPF -Anwendung.

In eine WPF-Anwendung erweiterter Glasframe

Siehe auch

Referenz

Übersicht über den Desktopfenster-Manager

Übersicht über den Desktopfenster-Manager-Weichzeichner

DwmExtendFrameIntoClientArea