Compartir a través de


Ampliar el marco de vidrio en una aplicación de WPF

En este tema se muestra cómo extender el marco del estilo visual Glass (de vidrio) de Windows Vista en el área cliente de una aplicación de Windows Presentation Foundation (WPF).

NotaNota

Este ejemplo únicamente funcionará en un equipo de Windows Vista que ejecute el Administrador de ventanas de escritorio (DWM) con Glass habilitado.Windows Vista Home Basic Edition no admite el efecto de estilo visual Glass transparente.Las áreas que se representarían normalmente con el efecto de estilo visual Glass transparente en otras ediciones de Windows Vista, se representan opacas.

Ejemplo

En la ilustración siguiente se muestra el marco Glass extendido hasta la barra de direcciones de Internet Explorer 7.

Internet Explorer con marco Glass extendido detrás de la barra de direcciones.

IE7 con marco Glass extendido detrás de la barra de direcciones.

Para extender el marco Glass en una aplicación de WPF, se necesita acceso a las API no administradas. En el ejemplo de código siguiente se invoca una plataforma (pinvoke) para las dos API necesarias para extender el marco al área cliente. Cada una de estas API se declara en una clase denominada NonClientRegionAPI.

        <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
[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 es la función de DWM que extiende el marco al área de cliente. Toma dos parámetros; un identificador de ventana y una estructura MARGINS. MARGINS se utiliza para indicar a DWM la extensión adicional requerida del marco al área de cliente.

Para utilizar la función DwmExtendFrameIntoClientArea, se debe obtener un identificador de ventana. En WPF, el identificador de ventana se puede obtener de la propiedad Handle de un objeto HwndSource. En el ejemplo siguiente, el marco se extiende al área cliente cuando se produce el evento Loaded de la ventana.

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

En el ejemplo siguiente se muestra una ventana simple en la que el marco se extiende al área cliente. El marco se extiende detrás del borde superior que contiene los dos objetos TextBox.

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

En la ilustración siguiente se muestra el marco Glass extendido en una aplicación de WPF.

Marco Glass extendido en una aplicaciónWPF.

Marco Glass extendido en una aplicación WPF

Vea también

Referencia

Desktop Window Manager Overview

Desktop Window Manager Blur Overview

DwmExtendFrameIntoClientArea