Cam Çerçeveyi WPF Uygulamasında Genişletme

Bu konu başlığında, Windows Vista cam çerçevesini bir Windows Presentation Foundation (WPF) uygulamasının istemci alanına genişletme açıklanır.

Not

Bu örnek yalnızca cam etkin Windows (DWM) Masaüstü Pencere Yöneticisi bir Vista makinesi üzerinde çalışır. Windows Vista Home Basic sürümü saydam cam etkisini desteklemez. Vista'nın diğer sürümleri üzerinde genellikle saydam cam etkisiyle Windows alanlar opak işlenir.

Örnek

Aşağıdaki görüntüde, 7. görüntüde yer alan adres çubuğuna genişletilmiş Internet Explorer göstermektedir:

Screenshot showing glass frame extended behind IE7 address bar.

WPF uygulamasındaki cam çerçeveyi genişletmek için, unmanaged API'ye erişim gerekir. Aşağıdaki kod örneği, çerçeveyi istemci alanına genişletmek için gereken iki API için bir Platform Çağırma (pinvoke) yapar. Bu API'lerden her biri NonClientRegionAPI adlı bir sınıfta bildirildi.

[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, çerçeveyi istemci alanına genişleten DWM işlevidir. İki parametre alır; bir pencere tanıtıcısı ve MARGINS yapısı. MARGINS, DWM'ye çerçevenin istemci alanına ne kadar ek olarak genişlet gerektiğini söylemek için kullanılır.

Örnek

DwmExtendFrameIntoClientArea işlevini kullanmak için bir pencere tanıtıcısı elde etmek gerekir. WPF'de pencere tanıtıcısı bir Handle özelliğinden elde HwndSource edilir. Aşağıdaki örnekte çerçeve, pencere olayında istemci alanına Loaded genişletildi.

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

Örnek

Aşağıdaki örnekte çerçevenin istemci alanına genişletildi olduğu basit bir pencere gösterilir. Çerçeve, iki nesne içeren üst kenarlığı arkasına TextBox genişletildi.

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

Aşağıdaki görüntüde WPF uygulamasına genişletilmiş cam çerçeve göstermektedir:

Screenshot showing a glass frame extended into a WPF application.

Ayrıca bkz.