次の方法で共有


アプリ ウィンドウの管理

Windows アプリ SDK には、HWND の高度な抽象化を表す Microsoft.UI.Windowing.AppWindow クラスが用意されています。 アプリの AppWindow と最上位の HWND の間には、1 対 1 のマッピングがあります。 AppWindow および関連するクラスには、HWND に直接アクセスする必要なく、アプリのトップレベル ウィンドウのさまざまな側面を管理できる API が用意されています。

この記事では、アプリで AppWindow API を使用する方法について説明します。 前提条件として、AppWindow化の概要に関するページの情報を読んで理解することをお勧めします。これは、WinUI または別の UI フレームワークのどちらを使用する場合でも適用可能です。

WinUI 3 ギャラリー アプリには、ほとんどの WinUI 3 コントロールと機能の対話型の例が含まれています。 Microsoft Store からアプリを取得するか、GitHub でソース コードを取得する

AppWindow API は、Windows App SDK でサポートされている任意の UI フレームワーク (WinUI 3、WPF、WinForms、または Win32) で使用できます。 AppWindow API は、フレームワーク固有のウィンドウ API と共に機能します。

通常、 AppWindow API は次の用途に使用します。

  • アプリのウィンドウのサイズと位置を管理します。

  • ウィンドウのタイトル、アイコン、タイトル バーの色を管理します。または、 AppWindowTitleBar API を使用して完全にカスタムのタイトル バーを作成します。

    詳細と例については、「 タイトル バーのカスタマイズ 」を参照してください。

  • AppWindowPresenter から派生した API を使用して、ウィンドウの外観と動作を管理します。

AppWindowの変更に対応する

1 つの AppWindow イベントを処理し、イベント引数 (AppWindowChangedEventArgs) を調べて、発生した変更の種類を確認することで、への変更に応答します。 関心のある変更が発生した場合は、それに対応できます。 潜在的な変更には、位置、サイズ、発表者、可視性、z オーダーが含まれます。

AppWindow.Changed イベント ハンドラーの例を次に示します。

private void AppWindow_Changed(AppWindow sender, AppWindowChangedEventArgs args)
{
    // ConfigText and SizeText are TextBox controls defined in XAML for the page.
    if (args.DidPresenterChange == true)
    {
        ConfigText.Text = sender.Presenter.Kind.ToString();
    }

    if (args.DidSizeChange == true)
    {
        SizeText.Text = sender.Size.Width.ToString() + ", " + sender.Size.Height.ToString();
    }
}

Window サイズと配置

AppWindow クラスには、ウィンドウのサイズと配置を管理するために使用できるいくつかのプロパティとメソッドがあります。

カテゴリ プロパティ
読み取り専用プロパティ 位置サイズClientSize
イベント Changed (DidPositionChangeDidSizeChange)
サイズおよび位置のメソッド 移動サイズ変更ResizeClientMoveAndResize
Z オーダー メソッド MoveInZOrderAtBottomMoveInZOrderAtTopMoveInZOrderBelow

[ サイズ変更] を呼び出して、新しいウィンドウ サイズを指定します。

この例では、コードは MainWindow.xaml.csであるため、 Window.AppWindow プロパティを使用して AppWindow インスタンスを取得できます。

public MainWindow()
{
    InitializeComponent();
    AppWindow.Resize(new Windows.Graphics.SizeInt32(1200, 800));
}

Move メソッドを呼び出して、ウィンドウの位置を変更します。

次の使用例は、ユーザーがボタンをクリックしたときにウィンドウを画面の中央に移動します。

これは Page クラスのコード ファイルで発生するため、 Window オブジェクトや AppWindow オブジェクトに自動的にアクセスすることはできません。 AppWindowを取得するには、いくつかのオプションがあります。

private void MoveWindowButton_Click(object sender, RoutedEventArgs e)
{
    AppWindow appWindow = AppWindow.GetFromWindowId(XamlRoot.ContentIslandEnvironment.AppWindowId);
    RectInt32? area = DisplayArea.GetFromWindowId(appWindow.Id, DisplayAreaFallback.Nearest)?.WorkArea;
    if (area == null) return;
    appWindow.Move(new PointInt32((area.Value.Width - appWindow.Size.Width) / 2, (area.Value.Height - appWindow.Size.Height) / 2));
}

AppWindowPresenter クラスとサブクラス

AppWindowにはAppWindowPresenter(プレゼンター)が適用されています。 プレゼンターはシステムによって作成され、AppWindow の作成時に適用されます。 AppWindowPresenter の各サブクラスには、ウィンドウの目的に適した定義済みの構成が用意されています。 これらの AppWindowPresenter から派生した発表者が提供され、サポートされているすべての OS バージョンで使用できます。

  • CompactOverlayPresenter

    画面の縦横比が16:9で固定サイズの常に最前面ウィンドウを構成して、ピクチャインピクチャのようなエクスペリエンスを可能にします。 既定では、 InitialSizeCompactOverlaySize.Small ですが、 Medium または Largeに変更できます。 AppWindowを呼び出すこともできますサイズを変更して 16:9 の縦横比をオーバーライドし、ウィンドウを任意のサイズにします。

  • FullScreenPresenter

    ビデオの視聴に適した全画面表示エクスペリエンスを提供するようにウィンドウを構成します。 ウィンドウに罫線またはタイトル バーがないため、システム タスク バーが非表示になります。

  • オーバーラップドプレゼンター

    標準のウィンドウ構成では、既定では、サイズ変更ハンドルを含む境界線と、最小化/最大化/復元ボタンを含むタイトル バーが提供されます。

Win32 アプリケーション モデルの新しい概念として、発表者はウィンドウの状態と スタイルの組み合わせに似ています (ただし、同じではありません)。 また、一部の発表者には、クラシック ウィンドウの状態やスタイル プロパティ (タイトル バーの自動非表示など) から検査できない動作が定義されています。

既定の発表者

AppWindowの作成時に適用される既定の発表者は、既定のプロパティ設定を持つ OverlappedPresenter のインスタンスです。 別のプレゼンターを適用した後、ウィンドウを既定のプレゼンターに戻すために、参照を保持しておく必要はありません。 これは、システムがのライフタイム中、このプレゼンターの同じインスタンスを保持するためであり、.SetPresenterメソッドをAppWindowPresenterKind.Defaultをパラメーターとして呼び出すことで再適用できます。

Important

SetPresenter(AppWindowPresenterKind.Default)呼び出すと、AppWindowで作成された既定の発表者インスタンスが常に再適用されます。 別の発表者を作成して適用し、後で再適用する場合は、発表者への参照を保持する必要があります。

また、既定の発表者インスタンスへの参照を取得して変更することもできます。 新しい発表者を適用した場合は、次に示すように、最初に既定の発表者が適用されていることを確認します。

appWindow.SetPresenter(AppWindowPresenterKind.Default);
OverlappedPresenter defaultPresenter = (OverlappedPresenter)appWindow.Presenter;
defaultPresenter.IsMaximizable = false;
defaultPresenter.IsMinimizable = false;

OverlappedPresenter を変更する

OverlappedPresenter は、さまざまな方法で構成できる柔軟な発表者です。

Create* メソッドを使用すると、既定のプロパティ設定、または特定の用途用に事前に構成されたプロパティ設定を持つ重複する発表者を作成できます。

次の表は、各メソッドから OverlappedPresenter オブジェクトを作成するときの構成プロパティの設定方法を示しています。

プロパティ Create CreateForContextMenu CreateForDialog CreateForToolWindow
HasBorder true true true true
HasTitleBar true false true true
IsAlwaysOnTop false false false false
IsMaximizable true false false true
IsMinimizable true false false true
IsModal false false false false
IsResizable true false false true

適用されたプレゼンターはライブ オブジェクトです。 AppWindowのPresenterオブジェクトの任意のプロパティに対する変更はすぐに有効になります。 これらの変更を通知するイベントはありませんが、現在の値のプロパティはいつでも確認できます。

HasBorder プロパティと HasTitleBar プロパティは読み取り専用です。 これらの値は 、SetBorderAndTitleBar メソッド (SetBorderAndTitleBar(bool hasBorder, bool hasTitleBar)) を呼び出すことによって設定できます。 OverlappedPresenter は、罫線のないタイトル バーを持つことはできません。 つまり、 hasTitleBar パラメーターが trueされている場合は、 hasBorder パラメーターも trueする必要があります。 それ以外の場合は、次のメッセージで例外がスローされます。

The parameter is incorrect.
Invalid combination: Border=false, TitleBar=true.

ツールバーの最大化ボタンを非表示にするには、 IsMaximizablefalse に設定します。 PreferredMaximumHeightプロパティまたはPreferredMaximumWidthプロパティを設定する場合は、ウィンドウ サイズが最大化された状態でも制約されるため、これを行うことをお勧めします。 これは、 Maximize メソッドの呼び出しには影響しません。

IsMinimizablefalse に設定すると、ツールバーの最小化ボタンが非表示になります。 これは 、Minimize メソッドの呼び出しには影響しません。

IsResizablefalse に設定すると、サイズ変更コントロールが非表示になり、ユーザーがウィンドウのサイズを変更できなくなります。 これは、AppWindow メソッドの呼び出しには影響しません。

IsAlwaysOnToptrue に設定すると、このウィンドウが他のウィンドウの上に表示されます。 AppWindow.MoveInZOrder*メソッドのいずれかを呼び出しても、このプロパティがtrueされている場合でも、ウィンドウの z オーダーを変更するために有効になります。

PreferredMaximumHeightPreferredMaximumWidth を設定して、ユーザーがウィンドウを拡大できる最大サイズを制限します。 最大サイズのプロパティを設定する場合は、 IsMaximizablefalse に設定することをお勧めします。これらのプロパティは、最大化された状態でもウィンドウ サイズを制限するためです。 これらのプロパティは、AppWindowの呼び出しにも影響します。サイズ変更;ウィンドウのサイズは、指定された最大の高さと幅を超えるサイズに変更されません。

PreferredMinimumHeightPreferredMinimumWidth を設定して、ユーザーがウィンドウを縮小できる最小サイズを設定します。 これらのプロパティは、AppWindowの呼び出しにも影響します。サイズ変更;ウィンドウのサイズは、指定された最小の高さと幅よりも小さくされません。

IsModaltrue に設定すると、モーダル ウィンドウを作成できます。 モーダル ウィンドウは、ウィンドウが閉じられるまで 、その所有者ウィンドウ との対話をブロックする別のウィンドウです。 ただし、モーダル ウィンドウを作成するには、所有者ウィンドウも設定する必要があります。それ以外の場合は、次のメッセージで例外がスローされます。

The parameter is incorrect.

The window should have an owner when IsModal=true.

WinUI アプリで所有者ウィンドウを設定するには、Win32 相互運用機能が必要です。 詳細とコード例については、WinUI ギャラリーサンプル アプリの AppWindow ページを参照してください。

プレゼンターを適用する

プレゼンターは、一度に 1 つのウィンドウにのみ適用できます。 2 番目のウィンドウに同じ発表者を適用しようとすると、例外が発生します。 これは、複数のウィンドウがあり、それぞれを特定のプレゼンテーション モードに切り替える必要がある場合に、同じ種類の複数のプレゼンターを作成し、それぞれを独自のウィンドウに適用する必要があるということです。

新しいプレゼンターが適用されたとき (AppWindow.Presenter プロパティが変更されたとき)、影響を受けたAppWindowにおいて、 イベントによりアプリに通知され、AppWindow プロパティが に設定されます。

ヒント

変更した発表者を適用し、発表者間の変更を許可する場合は、変更した発表者への参照を保持して、 AppWindowに再適用できるようにします。

この例では、次の操作を行う方法を示します。

ここでは、ウィンドウのコンストラクターでプレゼンターが作成され、変更され、適用されます。

OverlappedPresenter presenter = OverlappedPresenter.Create();
presenter.PreferredMinimumWidth = 420;
presenter.PreferredMinimumHeight = 550;
AppWindow.SetPresenter(presenter);

ウィンドウコンテンツである ページ では、 AppWindow と適用された発表者への参照を取得できます。

AppWindow appWindow;
OverlappedPresenter modifiedPresenter;

private void AppWindowPage_Loaded(object sender, RoutedEventArgs e)
{
    appWindow = AppWindow.GetFromWindowId(XamlRoot.ContentIslandEnvironment.AppWindowId);
    modifiedPresenter = (OverlappedPresenter)appWindow.Presenter;

    appWindow.Changed += AppWindow_Changed;
}

private void AppWindow_Changed(AppWindow sender, AppWindowChangedEventArgs args)
{
    if (args.DidPresenterChange)
    {
        // ConfigText is a TextBox control defined in XAML for the page.
        ConfigText.Text = appWindow.Presenter.Kind.ToString();
    }
}

private void CompactOverlayButton_Click(object sender, RoutedEventArgs e)
{
    if (appWindow.Presenter.Kind != AppWindowPresenterKind.CompactOverlay)
    {
        appWindow.SetPresenter(CompactOverlayPresenter.Create());
        fullScreenButton.IsChecked = false;
    }
    else
    {
        appWindow.SetPresenter(modifiedPresenter);
    }
}

private void FullScreenButton_Click(object sender, RoutedEventArgs e)
{
    if (appWindow.Presenter.Kind != AppWindowPresenterKind.FullScreen)
    {
        appWindow.SetPresenter(FullScreenPresenter.Create());
        compactOverlayButton.IsChecked = false;
    }
    else
    {
        appWindow.SetPresenter(modifiedPresenter);
    }
}

UI フレームワークと HWND の相互運用性

AppWindow クラスは、アプリ内の任意の最上位 HWND で使用できます。 つまり、デスクトップ UI フレームワーク (WinUI 3 を含む) を使用している場合は、そのフレームワークのエントリ ポイントを引き続き使用してウィンドウを作成し、そのコンテンツをアタッチできます。 また、その UI フレームワークを使用してウィンドウを作成したら、Windows App SDK で提供されているウィンドウ相互運用機能 (下記参照) を使用して、対応する AppWindow とそのメソッド、プロパティ、イベントにアクセスできます。

(UI フレームワークを使用する場合でも) AppWindow を使用する利点の一部は次のとおりです。

  • タイトルバーの簡単なカスタマイズ。既定で Windows 11 UI 丸みを帯びた角、スナップ グループ ポップアップ) が維持されます。
  • システムが提供する全画面表示およびコンパクトオーバーレイ(ピクチャー・イン・ピクチャー)機能。
  • Win32 ウィンドウの基本的な概念の一部を対象とした Windows ランタイム (WinRT) API のインターフェース。

1.3 より前のバージョンの Windows App SDK (または他のデスクトップ アプリ フレームワーク) の AppWindow を取得する

Window.AppWindow プロパティは、Windows App SDK バージョン 1.3 以降で使用できます。 以前のバージョンでは、このセクションの機能的に同等のコード例を使用できます。

C#. ウィンドウ相互運用機能の .NET ラッパーは、 Microsoft.UI.Win32Interop クラスのメソッドとして実装されます。 「.NET アプリから相互運用機能 API を呼び出す」も参照してください。

C++。 相互運用機能は、 winrt/Microsoft.ui.interop.h ヘッダー ファイルで定義されています。

次のコード例セクションは、実際のソース コードを示しています。しかし、既存のウィンドウを指定して AppWindow オブジェクトを取得するためのレシピを次に示します。

  1. 既存のウィンドウ オブジェクト (UI フレームワーク用) の HWND を取得します (まだない場合)。
  2. その HWND を GetWindowIdFromWindow 相互運用関数に渡して 、WindowId を取得します
  3. その WindowId を静的メソッドAppWindow.GetFromWindowIdに渡してAppWindowを取得します。
// MainWindow.xaml.cs
private void myButton_Click(object sender, RoutedEventArgs e)
{
    // Retrieve the window handle (HWND) of the current (XAML) WinUI 3 window.
    var hWnd =
        WinRT.Interop.WindowNative.GetWindowHandle(this);

    // Retrieve the WindowId that corresponds to hWnd.
    Microsoft.UI.WindowId windowId =
        Microsoft.UI.Win32Interop.GetWindowIdFromWindow(hWnd);

    // Lastly, retrieve the AppWindow for the current (XAML) WinUI 3 window.
    Microsoft.UI.Windowing.AppWindow appWindow =
        Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId);

    if (appWindow != null)
    {
        // You now have an AppWindow object, and you can call its methods to manipulate the window.
        // As an example, let's change the title text of the window.
        appWindow.Title = "Title text updated via AppWindow!";
    }
}
// pch.h
#include "microsoft.ui.xaml.window.h" // For the IWindowNative interface.
#include <winrt/Microsoft.UI.Interop.h> // For the WindowId struct and the GetWindowIdFromWindow function.
#include <winrt/Microsoft.UI.Windowing.h> // For the AppWindow class.

// mainwindow.xaml.cpp
void MainWindow::myButton_Click(IInspectable const&, RoutedEventArgs const&)
{
    // Retrieve the window handle (HWND) of the current (XAML) WinUI 3 window.
    auto windowNative{ this->m_inner.as<::IWindowNative>() };
    HWND hWnd{ 0 };
    windowNative->get_WindowHandle(&hWnd);

    // Retrieve the WindowId that corresponds to hWnd.
    Microsoft::UI::WindowId windowId = 
        Microsoft::UI::GetWindowIdFromWindow(hWnd);

    // Lastly, retrieve the AppWindow for the current (XAML) WinUI 3 window.
    Microsoft::UI::Windowing::AppWindow appWindow = 
        Microsoft::UI::Windowing::AppWindow::GetFromWindowId(windowId);

    if (appWindow)
    {
        // You now have an AppWindow object, and you can call its methods to manipulate the window.
        // As an example, let's change the title text of the window.
        appWindow.Title(L"Title text updated via AppWindow!");
    }
}

AppWindowを使用する方法の他の例については、Windowing ギャラリーのサンプルを参照してください。

制限事項

現在、Windows App SDK には、UI フレームワークコンテンツを AppWindowにアタッチするためのメソッドは用意されていません。