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

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

メモメモ

この例は、グラス対応の Desktop Window Manager (DWM) を実行している Windows Vista コンピューターでのみ機能します。Windows Vista Home Basic は、透明なグラス効果をサポートしていません。その他の Windows Vista で通常は透明なグラス効果でレンダリングされる領域は、不透明にレンダリングされます。

使用例

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

アドレス バーの背後にグラス フレームが拡張された Internet Explorer

アドレス バーの背後にグラス フレームが拡張された IE7。

グラス フレームを WPF アプリケーションで拡張するには、アンマネージ API へのアクセスが必要です。 フレームをクライアント領域に拡張するために必要な 2 つの API に対してプラットフォーム呼び出し (pinvoke) を実行する方法を次のコード例に示します。 これらの API は、それぞれ 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 は、フレームをクライアント領域に拡張する 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="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>

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

WPF アプリケーション拡張されたグラス フレーム

WPF アプリケーションに拡張されたグラス フレーム。

参照

参照

Desktop Window Manager Overview

Desktop Window Manager Blur Overview

DwmExtendFrameIntoClientArea