アプリ ウィンドウの管理 (Windows App SDK)

このトピックには、コード例のセクションがあります。

Windows App SDK には、使いやすい Microsoft.UI.Windowing.AppWindow クラスが用意されています。 AppWindow はフレームワークに依存せず、Win32、WPF、WinForms を含むすべての Windows アプリで使用できます。 AppWindow のフレームワークに依存しない性質を、WinUI 3 フレームワーク専用のウィンドウ クラスである Microsoft.UI.Xaml.Window と比較できます。 AppWindow は、ユニバーサル Windows プラットフォーム (UWP) の Windows.UI.WindowManagement.AppWindow の進化版です。

Windows App SDK バージョンの Microsoft.UI.Windowing.AppWindow は、非同期パターンに依存せず、API 呼び出しが成功したかどうかについてアプリにすぐにフィードバックを提供します。

また、「Windows アプリ SDK 用のツールをインストールする」、「WinUI 3 (Windows App SDK) プロジェクトを初めて作成する」、および「既存のプロジェクトで Windows App SDK を使用する」も参照してください。

AppWindow クラス

Microsoft.UI.Windowing.AppWindow は、使いやすいウィンドウの作成および管理するシナリオを実現できる高度なウィンドウ API です。 AppWindow は、Windows UI/UX や他のアプリとスムーズに統合されます。

AppWindow は、アプリのコンテンツのシステム マネージド コンテナーを表す高水準の抽象化を表します。 これはコンテンツがホストされるコンテナーであり、ユーザーが画面上でアプリのサイズを変更したり移動したりするときにユーザーが操作するエンティティを表します。 Win32 に習熟している開発者にとって、アプリ ウィンドウHWND の高水準の抽象化と考えることができます。 UWP に習熟している開発者にとって、アプリ ウィンドウCoreWindow/ApplicationView/Windows.UI.WindowManagement.AppWindow の代わりと見なすことができます。

Windows App SDK バージョンの Microsoft.UI.Windowing.AppWindow では、最上位の HWND のみをサポートしています。 AppWindow と最上位レベルの HWND の間には 1 対 1 のマッピングがあります。

AppWindow オブジェクトの有効期間は、HWND の場合と同じです。つまり、AppWindow オブジェクトは、ウィンドウが作成された直後に使用可能になり、ウィンドウが閉じられたときに破棄されます。

AppWindowPresenter クラスとサブクラス

AppWindow には、AppWindowPresenter (プレゼンター) が適用されています。 以前に Windows.UI.WindowManagement.AppWindow を使用したことがある UWP 開発者にとって理解しやすいことですが、機能や動作は 1 対 1 で対応しません。 「ウィンドウ機能の移行」も参照してください。

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

既定では、プレゼンターはシステムによって作成され、作成時に AppWindow に適用されます。 Windows App SDK 1.0 の Windows デスクトップでは、プレゼンターの種類はAppWindowPresenter のサブクラスである OverlappedPresenter です。 別のプレゼンターを適用した後、ウィンドウの既定のプレゼンターに 戻るために、アプリがそれを隠したり、その参照を保持したりする必要はありません。 システムは、このプレゼンターの同じインスタンスを、それが作成された AppWindow の有効期間にわたって保持します。アプリでは、AppWindowPresenterKind.Default をパラメーターとして SetPresenter メソッドを呼び出すことによってこれを再適用できます。

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

一部のプレゼンターには、ユーザーがアプリの制御の範囲外で変更を加えることができる機能があります。 このような変更が発生した場合は、 AppWindowChangedEventArgs.DidPresenterChange プロパティが true に設定されている、影響を受けた AppWindowAppWindow.Changed イベントによってアプリに通知されます。 次に、アプリは、適用されたプレゼンターのプロパティを調べて、変更内容を確認する必要があります。

適用されたプレゼンターはライブ オブジェクトです。 AppWindow.Presenter オブジェクトの任意のプロパティ変更は、すぐに有効になります。

プレゼンターは、ウィンドウに適用されている間は破棄されることはありません。 プレゼンター オブジェクトを破棄するには、最初に別のプレゼンター オブジェクトをウィンドウに適用します。そうすることで、破棄しようとしているプレゼンターがウィンドウから削除されます。 これを行うには、別の特定のプレゼンターをウィンドウに適用します。または、引数として AppWindowPresenterKind.Default を指定して AppWindow.SetPresenter メソッドを呼び出し、システムが作成した既定のプレゼンターをウィンドウに再適用します。 システムが作成したプレゼンターへの参照をウィンドウに対して保持していた場合は、この時点でそれが有効になります (つまり、ウィンドウに対して最初に作成されたものと同じインスタンスが再適用されます)。

使用可能なプレゼンター

これらの AppWindowPresenter から派生したプレゼンターは、サポートされているすべての OS バージョンで使用できます。

  • CompactOverlayPresenter。 縦横比が 16:9 の固定サイズの 常に手前に表示されるウィンドウを作成して、ピクチャ イン ピクチャのようなエクスペリエンスを実現します。
  • FullScreenPresenter。 ウィンドウを全画面表示にできるようにします。
  • OverlappedPresenter。 システムによって作成される "既定の" プレゼンター。これにより、アプリは、最小化、最大化、および復元操作と状態変更を要求し、それに対応することができます。

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

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

AppWindow を使用すると (UI フレームワークを使用する場合でも)、次のような利点があります。

  • タイトルバーのカスタマイズが簡単。既定で Windows 11 UI 丸みを帯びた角、スナップ グループ ポップアップ) が維持されます。
  • システムが提供する FullScreen および CompactOverlay (ピクチャ イン ピクチャ) エクスペリエンス。
  • いくつかの基本的な Win32 ウィンドウ化の概念のための Windows ランタイム (WinRT) API サーフェス。

コードの例

このコード例では、Microsoft.UI.Xaml.Window.AppWindow プロパティを使用して、WinUI 3 ウィンドウからMicrosoft.UI.Windowing.AppWindow を取得する方法を示します。 この例を使用するには、新しい 空のアプリ、パッケージ (WinUI 3 in Desktop) プロジェクトを作成し、コードを貼り付けます。

AppWindow の操作方法の詳細については、「ウィンドウ ギャラリーのサンプル」を参照してください。

// MainWindow.xaml.cs
private void myButton_Click(object sender, RoutedEventArgs e)
{
    // Retrieve the AppWindow for the current (XAML) WinUI 3 window.
    Microsoft.UI.Windowing.AppWindow appWindow = this.AppWindow;

    if (appWindow != null)
    {
        // With a non-null AppWindow object, 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 <winrt/Microsoft.UI.Windowing.h> // For the AppWindow class.

// mainwindow.xaml.cpp
void MainWindow::myButton_Click(IInspectable const&, RoutedEventArgs const&)
{
    // Retrieve the AppWindow for the current (XAML) WinUI 3 window.
    Microsoft::UI::Windowing::AppWindow appWindow = this->AppWindow();

    if (appWindow)
    {
        // With a non-null AppWindow object, 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!");
    }
}

1.3 より前のバージョンのWindows App SDK (または他のデスクトップ アプリ フレームワーク) のコード例

Microsoft.UI.Xaml.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 は WinUI 3 API です。 つまり、(パッケージ化された、またはパッケージ化されていない) デスクトップ アプリでのみ使用できます。UWP アプリでは使用できません。
  • 現在、Windows App SDK には、UI フレームワーク コンテンツを AppWindow にアタッチするためのメソッドが用意されていません。 コード例 のセクションを参照してください。
  • タイトル バーのカスタマイズは、Windows 11 以降と、Windows 10 の Windows App SDK バージョン 1.2 以降でサポートされています。 詳しくは、「タイトル バーのカスタマイズ」をご覧ください。