Partager via


Gérer les fenêtres d’application

Le Windows App SDK fournit la classe Microsoft.UI.Windowing.AppWindow, qui représente une abstraction de haut niveau du HWND. Il existe une correspondance 1:1 entre un AppWindow et un HWND de premier niveau dans votre application. AppWindow et ses classes associées fournissent des API qui vous permettent de gérer de nombreux aspects des fenêtres de niveau supérieur de votre application sans avoir besoin d'accéder directement au HWND.

Note

Cet article montre comment utiliser AppWindow des API dans votre application. En guise de prérequis, nous vous recommandons de lire et de comprendre les informations AppWindow dans Vue d’ensemble de WinUI 3 et Windows App SDK, qui s’appliquent si vous utilisez WinUI ou un autre framework d’interface utilisateur.

Icône galerie WinUI 3 L’application Galerie WinUI 3 inclut des exemples interactifs de contrôles et de fonctionnalités WinUI. Obtenez l’application à partir du Microsoft Store ou parcourez le code source sur GitHub.

Vous pouvez utiliser AppWindow API avec n’importe quelle infrastructure d’interface utilisateur prise en charge par les Windows App SDK : WinUI, WPF, WinForms ou Win32. AppWindow Les API fonctionnent en même temps que les API de fenêtrage spécifiques à l’infrastructure :

Vous utilisez généralement les API AppWindow pour :

Répondre aux modifications de AppWindow

Vous répondez aux modifications apportées en AppWindow gérant l’événement Change unique, puis en vérifiant les arguments d’événement (AppWindowChangedEventArgs) pour déterminer le type de modification qui s’est produit. Si la modification que vous souhaitez apporter s’est produite, vous pouvez y répondre. Les modifications potentielles incluent la position, la taille, le présentateur, la visibilité et l’ordre z.

Voici un exemple de gestionnaire d’événements 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 taille et positionnement

La AppWindow classe a plusieurs propriétés et méthodes que vous pouvez utiliser pour gérer la taille et le placement de la fenêtre.

Catégorie Propriétés
Propriétés en lecture seule Position, Taille, ClientSize
Événements Changed (DidPositionChange, DidSizeChange)
Méthodes de taille et de position Déplacer, Redimensionner, RedimensionnerClient, DéplacerEtRedimensionner
Méthodes D’ordre Z MoveInZOrderAtBottom, MoveInZOrderAtTop, MoveInzOrderBelow

Appelez Redimensionner pour spécifier une nouvelle taille de fenêtre.

Dans cet exemple, le code se trouve dans MainWindow.xaml.cs, vous pouvez donc utiliser la Windowpropriété .AppWindow pour obtenir l’instance AppWindow .

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

Appelez la méthode Move pour modifier la position d’une fenêtre.

Cet exemple montre comment déplacer la fenêtre à centrer sur l’écran lorsque l’utilisateur clique sur un bouton.

Cela se produit dans le fichier de code d'une classe Page, vous n'avez donc pas automatiquement accès aux objets Window ou AppWindow. Vous avez quelques options pour obtenir le 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));
}

La classe AppWindowPresenter et ses sous-classes

Chacun AppWindow a un AppWindowPresenter (présentateur) appliqué à lui. Un présentateur est créé par le système et appliqué à un objet AppWindow au moment de la création. Chaque sous-classe d’AppWindowPresenter fournit une configuration prédéfinie appropriée à l’objectif de la fenêtre. Ces présentateurs dérivés d’AppWindowPresenter sont fournis et sont disponibles sur toutes les versions de système d’exploitation prises en charge.

  • CompactOverlayPresenter

    Configure une fenêtre toujours en haut d’une taille fixe, avec un rapport d’aspect de 16:9 pour permettre des expériences de type image dans l’image. Par défaut, InitialSize est défini sur CompactOverlaySize.Small, mais vous pouvez le changer pour Medium ou Large. Vous pouvez également appeler AppWindow. Redimensionnez pour remplacer le rapport d’aspect 16:9 et faites de la fenêtre une taille souhaitée.

  • FullScreenPresenter

    Configure une fenêtre pour fournir une expérience en plein écran adaptée à l’observation de la vidéo. La fenêtre n’a pas de bordure ou de barre de titre et masque la barre des tâches système.

  • OverlappedPresenter

    La configuration de fenêtre standard, qui, par défaut, fournit une bordure avec des poignées de redimensionnement et une barre de titre avec des boutons réduire/agrandir/restaurer.

Note

En tant que nouveau concept pour le modèle d’application Win32, un présentateur est similaire à (mais pas identique à) une combinaison d’état de fenêtre et de styles. Certains présentateurs ont également des comportements qui ne peuvent pas être inspectés à partir des propriétés classiques d’état et de style des fenêtres (tels que la barre de titre à masquage automatique).

Présentateur par défaut

Le présentateur par défaut appliqué lors de la création d'un AppWindow est une instance de OverlappedPresenter avec les paramètres de propriété par défaut. Il n'est pas nécessaire de conserver une référence à celle-ci pour revenir au modèle par défaut d'une fenêtre après avoir appliqué un autre modèle. C’est parce que le système conserve la même instance de ce présentateur pendant toute la durée de vie de l’élément AppWindow pour lequel il a été créé ; et que vous pouvez le réappliquer en appelant leAppWindow . Méthode SetPresenter avec AppWindowPresenterKind.Default en tant que paramètre.

Important

L’appel SetPresenter(AppWindowPresenterKind.Default) applique toujours à nouveau l’instance de présentateur par défaut créée avec le AppWindow. Si vous créez et appliquez un autre présentateur et que vous souhaitez le réappliquer ultérieurement, vous devez conserver une référence à votre présentateur.

Vous pouvez également obtenir une référence à l’instance de présentateur par défaut et la modifier. Si vous avez appliqué un nouveau présentateur, vérifiez d’abord que le présentateur par défaut est appliqué, comme indiqué ici :

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

Modifier un OverlappedPresenter

OverlappedPresenter est un présentateur flexible que vous pouvez configurer de différentes manières.

Les Createméthodes * vous permettent de créer un présentateur superposé avec les paramètres de propriété standard, ou un avec des paramètres de propriété préconfigurés pour un usage spécifique.

Ce tableau montre comment les propriétés de configuration sont définies lorsque vous créez un objet OverlappedPresenter à partir de chaque méthode.

Propriété 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

Le présentateur appliqué est un objet actif. Toute modification apportée à n’importe quelle propriété de l’objet AppWindow.Presenter prend effet immédiatement. Il n’existe aucun événement pour vous avertir de ces modifications, mais vous pouvez vérifier les propriétés des valeurs actuelles à tout moment.

Les propriétés HasBorder et HasTitleBar sont en lecture seule. Vous pouvez définir ces valeurs en appelant la méthode SetBorderAndTitleBar (SetBorderAndTitleBar(bool hasBorder, bool hasTitleBar)). Un OverlappedPresenter ne peut pas avoir de barre de titre sans bordure. Autrement dit, si le hasTitleBar paramètre est true, le hasBorder paramètre doit également être true. Sinon, une exception est générée avec ce message :

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

Définissez IsMaximizable pour false masquer le bouton Agrandir dans la barre d’outils. Nous vous recommandons de le faire si vous définissez les propriétés PreferredMaximumHeight ou PreferredMaximumWidth, car ces propriétés limitent la taille de la fenêtre même à l’état maximisé. Cela n’affecte pas les appels à la méthode Maximize .

Définissez IsMinimizable pour false masquer le bouton réduire dans la barre d’outils. Cela n’affecte pas les appels à la méthode De réduction .

Définissez IsResizable pour false masquer les contrôles de redimensionnement et empêcher l’utilisateur de redimensionner la fenêtre. Cela n’a pas d'incidence sur les appels à la méthode AppWindow.resize.

Définissez IsAlwaysOnTop pour true conserver cette fenêtre au-dessus d’autres fenêtres. Si vous appelez l’une des AppWindow.MoveInZOrder* méthodes, elles prennent toujours effet pour modifier l’ordre z de la fenêtre même si cette propriété est true.

Définissez PreferredMaximumHeight et PreferredMaximumWidth pour limiter la taille maximale à laquelle l’utilisateur peut étendre la fenêtre. Nous vous recommandons de définir IsMaximizable sur false si vous définissez les propriétés de taille maximale, car ces propriétés limitent la taille de la fenêtre même dans l’état maximisé. Ces propriétés affectent également les appels à AppWindow. Redimensionner ; la fenêtre ne sera pas redimensionnée plus grande que la hauteur et la largeur maximale spécifiées.

Définissez PreferredMinimumHeight et PreferredMinimumWidth pour définir la taille minimale à laquelle l’utilisateur peut réduire la fenêtre. Ces propriétés affectent également les appels à AppWindow. Redimensionner ; la fenêtre ne sera pas redimensionnée plus petite que la hauteur minimale et la largeur spécifiées.

Vous pouvez définir IsModal pour true créer une fenêtre modale. Une fenêtre modale est une fenêtre distincte qui bloque l’interaction avec sa fenêtre propriétaire jusqu’à ce qu’elle soit fermée. Toutefois, pour créer une fenêtre modale, vous devez également définir la fenêtre propriétaire ; sinon, une exception est levée avec ce message :

The parameter is incorrect.

The window should have an owner when IsModal=true.

Pour définir la fenêtre propriétaire dans une application WinUI, l’interopérabilité Win32 est nécessaire. Pour plus d’informations et pour obtenir des exemples de code, consultez la AppWindow page de l’exemple d’application galerie WinUI 3.

Appliquer un présentateur

Un présentateur ne peut être appliqué qu’à une seule fenêtre à la fois. Tenter d’appliquer le même présentateur à une deuxième fenêtre génère une exception. Cela signifie que si vous avez plusieurs fenêtres et que vous souhaitez passer chacune d’elles dans un mode de présentation spécifique, vous devez créer plusieurs présentateurs du même type, puis appliquer chacun d’eux à sa propre fenêtre.

Lorsqu'un nouveau présentateur est appliqué (la propriété AppWindow.Presenter change), votre application est avertie par un événement AppWindow.Changed sur l'AppWindow affecté, avec la propriété AppWindowChangedEventArgs.DidPresenterChange définie sur true.

Conseil / Astuce

Si vous appliquez un présentateur modifié et autorisez les changements entre présentateurs, veillez à conserver une référence au présentateur modifié afin qu’il puisse être réappliqué au AppWindow.

Cet exemple montre comment réaliser les éléments suivants :

Ici, un présenteur est créé, modifié et appliqué dans le constructeur de la fenêtre.

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

Dans la page qui constitue le contenu de la fenêtre, vous pouvez obtenir une référence à l'AppWindow et au présentateur appliqué.

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

Interopérabilité entre le framework d’interface utilisateur et HWND

La AppWindow classe est disponible pour n’importe quel HWND de niveau supérieur dans votre application. Cela signifie que lorsque vous travaillez avec une infrastructure d’interface utilisateur de bureau (y compris WinUI), vous pouvez continuer à utiliser le point d’entrée de ce framework pour créer une fenêtre et attacher son contenu. Une fois que vous avez créé une fenêtre avec cette infrastructure d'interface utilisateur, vous pouvez utiliser les fonctions d'interopérabilité de fenêtrage (voir ci-dessous) fournies dans l'Windows App SDK pour accéder au AppWindow correspondant et à ses méthodes, propriétés et événements.

Certains des avantages de l’utilisation AppWindow (même lors de l’utilisation d’une infrastructure d’interface utilisateur) sont les suivants :

  • Personnalisation simple de la barre de titre qui préserve par défaut l’interface utilisateur de Windows 11 (coins arrondis, fonctionnalité de groupe d’ancrage).
  • Expériences de superposition en plein écran et en format compact fournies par le système (image dans l'image).
  • Surface API de Windows Runtime (WinRT) pour certains concepts fondamentaux du fenêtrage Win32.

Obtenez le AppWindow pour les versions de Windows App SDK antérieures à la version 1.3 (ou d’autres infrastructures d’application de bureau)

La propriété Window.AppWindow est disponible dans Windows App SDK version 1.3 et ultérieure. Pour les versions antérieures, veuillez utiliser l’exemple de code fonctionnellement équivalent fourni dans cette section.

C#. .NET wrappers pour les fonctions d’interopérabilité de fenêtrage sont implémentés en tant que méthodes de la classe Microsoft.UI.Win32Interop. Consultez également Appeler des API d'interopérabilité à partir d’une application .NET.

C++. Les fonctions d’interopérabilité sont définies dans le fichier d’en-tête winrt/Microsoft.ui.interop.h .

L’exemple de code ci-dessous montre le code source réel ; mais voici la recette permettant de récupérer un AppWindow objet en fonction d’une fenêtre existante :

  1. Récupérez le HWND pour votre objet de fenêtre existant (pour votre infrastructure d’interface utilisateur), si vous ne l’avez pas déjà.
  2. Passez ce HWND à la fonction d’interopérabilité GetWindowIdFromWindow pour récupérer un WindowId.
  3. Passez ce WindowId à la méthode statique AppWindow.GetFromWindowId pour récupérer le 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!");
    }
}

Pour plus d’exemples d’utilisation de AppWindow, consultez l’exemple de galerie Windowing.

Limites

Le Windows App SDK ne fournit actuellement pas de méthodes pour attacher le contenu de l'infrastructure d'interface utilisateur à un AppWindow.