Language

アプリ ウィンドウの管理

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

注

この記事では、アプリで AppWindow API を使用する方法について説明します。 前提条件として、AppWindowの情報を読み理解することをお勧めします。この情報は、WinUI 3 と Windows アプリ SDK のウィンドウ処理の概要にあり、WinUI または他の UI フレームワークを使用する場合でも適用されます。

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

Windows アプリ SDKがサポートする任意の UI フレームワーク (WinUI、WPF、WinForms、Win32) で、AppWindow API を使用できます。 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 (DidPositionChange、DidSizeChange)
サイズおよび位置のメソッド 移動、 サイズ変更、 ResizeClient、 MoveAndResize
Z オーダー メソッド MoveInZOrderAtBottom、 MoveInZOrderAtTop、 MoveInZOrderBelow

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

この例では、コードは 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));
}

論理ピクセル単位でウィンドウ サイズを設定する (試験段階)

Important

このセクションのWindowサイズ設定プロパティは、Windows アプリ SDK 2.3 Experimental A で導入された実験用 API です。API は実験的としてマークされており、将来のリリースで変更または削除される可能性があります。 運用環境のアプリでは使用しないでください。 ダウンロード リンクについては、「最新のWindows アプリ SDKダウンロード」を参照してください。

AppWindow.Resize と AppWindow.ResizeClient は、物理ピクセル単位でサイズを受け取ります。 スケール ファクターが異なるディスプレイで同じサイズを取得するには、値を自分で変換する必要があります。 試験段階のリリースでは、Microsoft.UI.Xaml.Windowクラスには、ウィンドウのクライアント領域のサイズを取得および設定するプロパティがあります (デバイスに依存しないピクセル (DIP) とも呼ばれます)。 ウィンドウは現在の表示スケールの値を変換するため、 Width が 640 のクライアント領域は、100% スケールで幅が 640 物理ピクセル、150% スケールで 960 物理ピクセル幅になります。 これらのプロパティは、 Window.AppWindow プロパティを経由せずに XAML またはコードで設定できます。

プロパティ Description
幅、高さ ウィンドウが復元された状態にある場合のクライアント領域のサイズ。
MinWidth, MinHeight ユーザーがウィンドウのサイズを変更できる最小のクライアント領域。 既定値は 0 です。
MaxWidth、 MaxHeight ユーザーがウィンドウのサイズを変更できる最大のクライアント領域。 既定値は正の無限大であり、最大値がないことを意味します。

次の使用例は、XAML ファイル内のウィンドウの初期サイズとサイズ制限を設定します。

<Window
    x:Class="MyApp.SettingsWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="640"
    Height="480"
    MinWidth="320"
    MinHeight="240"
    MaxWidth="960"
    MaxHeight="720">
    <TextBlock Margin="24" Text="Resize this window." />
</Window>

この例では、コードで作成するウィンドウに対して C# で同じ値を設定します。

Window window = new Window
{
    Width = 640,
    Height = 480,
    MinWidth = 320,
    MinHeight = 240,
    MaxWidth = 960,
    MaxHeight = 720,
    Content = new TextBlock { Margin = new Thickness(24), Text = "Resize this window." }
};

// A size that you set before the first call to Activate is applied when the window is shown.
window.Activate();

次の表は、 Window プロパティと AppWindow サイズ設定 API の関係を示しています。 たとえば、 AppWindow.Resize(new SizeInt32(1200, 800)) では、ウィンドウ全体 (境界線とタイトル バーを含む) が 1200 x 800 物理ピクセルになります。 Widthを 1200 に設定し、Heightを 800 に設定すると、クライアント領域のサイズは 1200 x 800 論理ピクセルになります。これは、150% スケールでディスプレイ上で 1800 x 1200 物理ピクセルです。

API サイズ設定の対象 単位
Window.幅, Window.高さ (試験段階) 復元されたウィンドウのクライアント領域。 値を取得して設定できます。 論理ピクセル
Window.Bounds 現在のクライアント領域。 読み取り専用。 論理ピクセル
AppWindow.サイズ変更 ウィンドウ全体 (罫線とタイトル バーを含む)。 物理ピクセル
AppWindow.ResizeClient クライアント エリア 物理ピクセル
AppWindow.Size, AppWindow.ClientSize 現在のウィンドウとクライアント領域。 読み取り専用。 物理ピクセル

Windowのサイズ設定プロパティを使用する場合は、次の動作に注意してください。

  • 元のサイズ。 ウィンドウが最大化または最小化されると、 Width および Height は、ウィンドウが復元されたときに返されるクライアント サイズを返します。 その状態に設定すると、復元されたサイズが変更され、ウィンドウは最大化または最小化されたままになります。 ウィンドウで FullScreenPresenter または CompactOverlayPresenter を使用する場合、ウィンドウが OverlappedPresenter に戻ったときに設定したサイズが適用されます。
  • サイズ制限。MinWidth、 MinHeight、 MaxWidth、および MaxHeight は、ウィンドウが既定の Presenter である OverlappedPresenter を使用している間に有効になります。 このウィンドウは、発表者の PreferredMinimumWidth、PreferredMinimumHeight、PreferredMaximumWidth、PreferredMaximumHeight の各プロパティを設定し、ウィンドウが別のスケールのディスプレイに移動したときにそれらを更新します。 Windowプロパティを使用して制限するディメンションに対して、プレゼンター プロパティを自分で設定しないでください。 Presenter のプロパティの詳細については、「OverlappedPresenter を変更する」を参照してください。
  • 最大サイズ。 発表者の PreferredMaximumWidth プロパティや PreferredMaximumHeight プロパティと同様に、MaxWidth と MaxHeight は、ウィンドウが最大化された場合でも、ウィンドウのサイズを制限します。 たとえば、前の例のウィンドウを最大化すると、大きなディスプレイでも、クライアント領域は 960 x 720 の論理ピクセル以下になります。
  • 有効な値。 WidthとHeightを最小値と最大値の間の値に設定します。 Width、 Height、 MinWidth、および MinHeight は、有限であり、0 以上である必要があります。 MaxWidth と MaxHeight は 0 以上、または最大値を設定しない場合は正の無限大である必要があります。 その他の値を指定すると、セッターは C# では ArgumentException 例外をスローします。

AppWindowPresenter クラスとサブクラス

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

  • CompactOverlayPresenter

    画面の縦横比が16:9で固定サイズの常に最前面ウィンドウを構成して、ピクチャインピクチャのようなエクスペリエンスを可能にします。 既定では、 InitialSize は CompactOverlaySize.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.

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

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

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

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

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

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

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

The parameter is incorrect.

The window should have an owner when IsModal=true.

WinUI アプリで所有者ウィンドウを設定するには、Win32 相互運用機能が必要です。 詳細とコード例については、WinUI 3 ギャラリー サンプル アプリの 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 を含む) を使用している場合は、そのフレームワークのエントリ ポイントを引き続き使用してウィンドウを作成し、そのコンテンツを添付できます。 また、その UI フレームワークを使用してウィンドウを作成したら、Windows アプリ SDKで提供されているウィンドウ相互運用機能 (下記参照) を使用して、対応する AppWindow とそのメソッド、プロパティ、およびイベントにアクセスできます。

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

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

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

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

C#. ウィンドウ相互運用機能の.NETラッパーは、Microsoft.UI.Win32Interop クラスのメソッドとして実装されます。 .NET アプリから Call 相互運用 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 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 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 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 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 アプリ SDKでは現在、UI フレームワークコンテンツをAppWindowにアタッチするためのメソッドは提供されていません。