Langue

Gérer les fenêtres d’application

Le SDK d'application Windows 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 SDK d'application Windows, 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 SDK d'application Windows : 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 Modifié (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));
}

Définir la taille de la fenêtre en pixels logiques (expérimental)

Important

Les Window propriétés de dimensionnement de cette section sont des API expérimentales introduites dans SDK d'application Windows 2.3 Expérimental A. Les API sont marquées expérimentales et peuvent changer ou être supprimées dans une version ultérieure. Ne les utilisez pas dans les applications de production. Pour obtenir des liens de téléchargement, consultez les derniers téléchargements du SDK d’application Windows.

AppWindow.Resize et AppWindow.ResizeClient prennent des tailles en pixels physiques. Pour obtenir la même taille sur les affichages avec différents facteurs d’échelle, vous devez convertir les valeurs vous-même. Dans les versions expérimentales, la classe Microsoft.UI.Xaml.Window a des propriétés qui permettent d’obtenir et de définir la taille de la zone cliente de la fenêtre en pixels logiques, également appelés pixels indépendants du périphérique (DIP). La fenêtre convertit les valeurs selon l’échelle d’affichage actuelle, de sorte qu’une zone cliente d’une largeur de Width640 mesure 640 pixels physiques de large à une échelle de 100 % et 960 pixels physiques de large à une échelle de 150 %. Vous pouvez définir ces propriétés en XAML ou en code, sans passer par la propriété Window.AppWindow.

Propriété Description
Largeur, Hauteur Taille de la zone cliente lorsque la fenêtre est dans son état restauré.
MinWidth, MinHeight La taille minimale de la zone cliente à laquelle l’utilisateur peut redimensionner la fenêtre. La valeur par défaut est 0.
MaxWidth, MaxHeight La plus grande zone cliente jusqu’à laquelle l’utilisateur peut redimensionner la fenêtre. La valeur par défaut est l’infini positif, ce qui signifie qu’il n’y a pas de maximum.

Cet exemple montre comment définir la taille initiale et les limites de taille d’une fenêtre dans son fichier 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>

Cet exemple montre comment définir les mêmes valeurs en C# pour une fenêtre qu’elle crée dans le code.

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

Ce tableau montre comment les Window propriétés sont liées aux API de AppWindow dimensionnement. Par exemple, AppWindow.Resize(new SizeInt32(1200, 800)) rend la fenêtre entière, y compris sa bordure et sa barre de titre, de 1200 par 800 pixels physiques. Régler Width sur 1200 et Height sur 800 donne à la zone client une taille de 1200 par 800 pixels logiques, soit 1800 par 1200 pixels physiques sur un affichage à une échelle de 150 %.

API Ce que cela redimensionne Unités
Window. Largeur, Window. Hauteur (expérimentale) Zone cliente de la fenêtre restaurée. Vous pouvez récupérer et définir les valeurs. Pixels logiques
Window.Limites Zone cliente actuelle. Lecture seule. Pixels logiques
AppWindow.Redimensionner La fenêtre entière, y compris la bordure et la barre de titre. Pixels physiques
AppWindow.ResizeClient L’espace client. Pixels physiques
AppWindow.Size, AppWindow.ClientSize Fenêtre actuelle et zone cliente. Lecture seule. Pixels physiques

Gardez ces comportements à l’esprit lorsque vous utilisez les propriétés de Window dimensionnement :

  • Taille restaurée. Lorsque la fenêtre est agrandie ou réduite, Width et Height renvoient la taille du client à laquelle la fenêtre revient lorsqu’elle est restaurée. Si vous les définissez dans cet état, la taille restaurée change et la fenêtre reste maximisée ou minimisée. Si la fenêtre utilise un FullScreenPresenter ou CompactOverlayPresenter, une taille que vous définissez est appliquée lorsque la fenêtre bascule vers un OverlappedPresenter.
  • Limites de taille.MinWidth, MinHeight, MaxWidth et MaxHeight prennent effet lorsque la fenêtre utilise un présentateur OverlappedPresenter, qui est le présentateur par défaut. La fenêtre définit pour vous les propriétés PreferredMaximumWidth, PreferredMaximumHeight, PreferredMinimumWidth et PreferredMinimumHeight du présentateur, et les met à jour lorsque la fenêtre passe à un affichage avec une échelle différente. Ne définissez pas vous-même ces propriétés de présentateur pour une dimension que vous limitez par le biais des propriétés Window. Pour plus d’informations sur les propriétés du présentateur, consultez Modifier OverlappedPresenter.
  • Taille maximisée. Comme les propriétés PreferredMaximumHeight et PreferredMaximumWidth du présentateur, MaxWidth et MaxHeight limitent la taille de la fenêtre même lorsqu’elle est agrandie. Par exemple, lorsque vous agrandissez la fenêtre mentionnée dans les exemples précédents, sa zone cliente n’est pas supérieure à 960 par 720 pixels logiques, même sur un affichage plus grand.
  • Valeurs valides. Définissez Height et Width sur des valeurs comprises entre les limites minimale et maximale. Width, Height, MinWidth et MinHeight doivent être des valeurs finies et supérieures ou égales à 0. MaxWidth et MaxHeight doivent être égaux à 0 ou supérieurs, ou à l’infini positif pour indiquer qu’il n’y a pas de maximum. D’autres valeurs provoquent la levée d’une exception par le setter, qui est une exception ArgumentException en C#.

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'SDK d'application Windows 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 facile de la barre de titre, qui conserve par défaut l’interface utilisateur de Windows 11 (coins arrondis, menu déroulant des groupes 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 SDK d'application Windows antérieures à la version 1.3 (ou d’autres infrastructures d’application de bureau)

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

C#. Les wrappers .NET pour les fonctions d’interopérabilité de fenêtrage sont mis en œuvre 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 SDK d'application Windows ne fournit actuellement pas de méthodes pour attacher le contenu de l'infrastructure d'interface utilisateur à un AppWindow.