WPF アプリケーションへのグラス フレームの拡張

このトピックでは、Windows Vista のグラス フレームを Windows Presentation Foundation (WPF) アプリケーションのクライアント領域に拡張する方法について説明します。

注意

この例は、グラスが有効なデスクトップ ウィンドウ マネージャー (DWM) を実行している Windows Vista コンピューターでしか動作しません。 Windows Vista Home Basic エディションは、透明グラス効果をサポートしていません。 Windows Vista の他のエディションで透明グラス効果が通常レンダリングされる領域は、不透明でレンダリングされます。

アドレス バーの拡張グラス フレーム

次の図は、Internet Explorer 7 のアドレス バーに拡張されたグラス フレームを示しています。

Screenshot showing glass frame extended behind IE7 address bar.

WPF アプリケーションにグラス フレームを拡張するには、アンマネージ API へのアクセスが必要です。 次のコード例では、クライアント領域にフレームを拡張するために必要な 2 つの API のプラットフォーム呼び出し (pinvoke) を行っています。 これらの各 API は、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 は、クライアント領域にフレームを拡張する DWM 関数です。 ウィンドウ ハンドルと MARGINS 構造体の 2 つのパラメーターを受け取ります。 MARGINS は、フレームがクライアント領域に余分に拡張する量を DWM に通知するために使われます。

読み込み時のイベントでの拡張グラス フレーム

DwmExtendFrameIntoClientArea 関数を使うには、ウィンドウ ハンドルを取得する必要があります。 WPF では、ウィンドウ ハンドルは HwndSourceHandle プロパティから取得できます。 次の例では、フレームはウィンドウの Loaded イベントでクライアント領域に拡張されます。

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

クライアント領域の拡張グラス フレーム

次の例では、クライアント領域にフレームが拡張される簡単なウィンドウを示します。 フレームは、2 つの TextBox オブジェクトを含む上部の境界の背後に拡張されます。

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

次の図は、WPF アプリケーションに拡張されたグラス フレームを示しています。

Screenshot showing a glass frame extended into a WPF application.

関連項目