Compartir a través de


Administración de ventanas de aplicaciones

El SDK de aplicaciones de Windows proporciona la clase Microsoft.UI.Windowing.AppWindow que representa una abstracción de alto nivel de HWND. Hay una asignación de 1:1 entre un AppWindow y un HWND de nivel superior en su aplicación. AppWindow y sus clases relacionadas proporcionan API que te permiten administrar muchos aspectos de las ventanas de nivel superior de la aplicación sin necesidad de acceder directamente al HWND.

Nota:

En este artículo se muestra cómo usar AppWindow las API en la aplicación. Como requisito previo, recomendamos que lea y comprenda la información de AppWindow en Visión general de ventanas para WinUI y Windows App SDK, que es aplicable tanto si usa WinUI como otro marco de trabajo de interfaz de usuario.

La aplicación WinUI 3 Gallery incluye ejemplos interactivos de la mayoría de los controles, características y funcionalidades de WinUI 3. Obtén la aplicación desde la Microsoft Store o consigue el código fuente en GitHub

Puedes usar AppWindow las API con cualquier marco de interfaz de usuario compatible con Windows App SDK: WinUI 3, WPF, WinForms o Win32. AppWindow Las API funcionan junto con las API de ventanas específicas del marco:

Normalmente, se usan AppWindow API para:

  • Administre el tamaño y la posición de la ventana de la aplicación.

  • Administrar el título de la ventana, el icono y el color de la barra de título; o cree una barra de título totalmente personalizada con las API de AppWindowTitleBar.

    Consulta Personalización de la barra de título para obtener más información y ejemplos.

  • Administre la apariencia y el comportamiento de la ventana con las API derivadas de AppWindowPresenter.

Responder a los cambios de AppWindow

Puede responder a los cambios en AppWindow mediante el control del único evento Changed y, a continuación, comprobar los argumentos del evento (AppWindowChangedEventArgs) para determinar qué tipo de cambio ha ocurrido. Si se ha producido el cambio que le interesa, puede responder a él. Entre los posibles cambios se incluyen la posición, el tamaño, el moderador, la visibilidad y el orden z.

Este es un ejemplo de un controlador de eventos .AppWindowChanged.

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 tamaño y colocación

La AppWindow clase tiene varias propiedades y métodos que puede usar para administrar el tamaño y la ubicación de la ventana.

Categoría Propiedades
Propiedades de solo lectura Position, Size, ClientSize
Eventos Modificado (DidPositionChange, DidSizeChange)
Métodos de tamaño y posición Move, Resize, ResizeClient, MoveAndResize
Métodos de orden Z MoveInzOrderAtBottom, MoveInzOrderAtTop, MoveInzOrderBelow

Llame a Resize para especificar un nuevo tamaño de ventana.

En este ejemplo, el código está en MainWindow.xaml.cs, por lo que puede usar la Windowpropiedad .AppWindow para obtener la AppWindow instancia.

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

Llame al método Move para cambiar la posición de una ventana.

En este ejemplo se mueve la ventana para centrarse en la pantalla cuando el usuario hace clic en un botón.

Esto ocurre en el archivo de código de una clase Page , por lo que no tiene acceso automáticamente a los Window objetos o AppWindow . Tienes algunas opciones para obtener el 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 clase AppWindowPresenter y las subclases

Cada AppWindow tiene un AppWindowPresenter (moderador) aplicada. El sistema crea un moderador y se aplica a una AppWindow en el momento de la creación. Cada subclase de AppWindowPresenter proporciona una configuración predefinida adecuada para el propósito de la ventana. Se proporcionan estos presentadores derivados de AppWindowPresenter y están disponibles en todas las versiones del sistema operativo compatibles.

  • CompactOverlayPresenter

    Configura una ventana siempre visible de un tamaño fijo, con una relación de aspecto de 16:9 para permitir experiencias de imagen en imagen. De forma predeterminada, InitialSize es CompactOverlaySize.Small, pero puede cambiarlo a Medium o Large. También puede llamar a AppWindow.Resize para anular la relación de aspecto 16:9 y establecer la ventana en cualquier tamaño deseado.

  • FullScreenPresenter

    Configura una ventana para proporcionar una experiencia de pantalla completa adecuada para ver vídeo. La ventana no tiene un borde ni una barra de título y oculta la barra de tareas del sistema.

  • SuperpuestoPresenter

    La configuración de ventana estándar, que, de forma predeterminada, proporciona un borde con identificadores de cambio de tamaño y una barra de título con botones de minimización, maximización y restauración.

Nota:

Como nuevo concepto para el modelo de aplicación Win32, un presentador es similar a (pero no igual a) una combinación de estado de ventana y estilos. Algunos presentadores también tienen comportamientos que están definidos y que no se pueden inspeccionar a partir de las propiedades de estado y estilo de ventana clásico (como una barra de título que se oculta automáticamente).

El presentador predeterminado

El presentador predeterminado aplicado cuando se crea un AppWindow es una instancia de OverlappedPresenter con la configuración de propiedad predeterminada. No es necesaria una referencia para volver al moderador predeterminado de una ventana una vez aplicado otro moderador. Esto se debe a que el sistema mantiene la misma instancia de este presentador durante toda la vida útil del AppWindow para el cual se creó; y puede volver a aplicarlo llamando al AppWindow.método SetPresenter con AppWindowPresenterKind.Default como parámetro.

Importante

Al llamar a SetPresenter(AppWindowPresenterKind.Default), siempre se vuelve a aplicar la instancia predeterminada del presentador que se crea con AppWindow. Si crea y aplica otro moderador y desea volver a utilizarlo más adelante, debe mantener una referencia al moderador.

También puede obtener una referencia a la instancia predeterminada del presentador y modificarla. Si ha aplicado un nuevo moderador, asegúrese primero de que se aplique el moderador predeterminado, como se muestra aquí:

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

Modificar un OverlappedPresenter

OverlappedPresenter es un presentador flexible que se puede configurar de diversas maneras.

Los métodos Create permiten crear un presentador de superposición con valores de propiedad predeterminados, o uno con valores de propiedad preconfigurados para un uso específico.

En esta tabla se muestra cómo se establecen las propiedades de configuración al crear un objeto OverlappedPresenter a partir de cada método.

Propiedad 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

El moderador aplicado es un objeto activo. Un cambio en cualquier propiedad del objeto AppWindow.Presenter surte efecto inmediatamente. No hay ningún evento para notificarle estos cambios, pero puede comprobar las propiedades de los valores actuales en cualquier momento.

Las propiedades HasBorder y HasTitleBar son de solo lectura. Puede establecer estos valores llamando al método SetBorderAndTitleBar (SetBorderAndTitleBar(bool hasBorder, bool hasTitleBar)). Un OverlappedPresenter no puede tener una barra de título sin borde. Es decir, si el hasTitleBar parámetro es true, el hasBorder parámetro también debe ser true. De lo contrario, se produce una excepción con este mensaje:

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

Establezca IsMaximizable a false para ocultar el botón de maximizar de la barra de herramientas. Se recomienda hacerlo si establece las PreferredMaximumHeight propiedades o PreferredMaximumWidth , ya que estas propiedades restringen el tamaño de la ventana incluso en el estado maximizado. Esto no afecta a las llamadas al método Maximize .

Establezca IsMinimizable en false para ocultar el botón minimizar de la barra de herramientas. Esto no afecta a las llamadas al método Minimize .

Establezca IsResizable en false para ocultar los controles de cambio de tamaño y evitar que el usuario vuelva a cambiar el tamaño de la ventana. Esto no afecta a las llamadas al método AppWindow.Resize.

Establezca IsAlwaysOnTop en true para mantener esta ventana encima de otras ventanas. Si llama a cualquiera de los AppWindow.MoveInZOrder* métodos, siguen surtindo efecto para cambiar el orden z de la ventana aunque esta propiedad sea true.

Establezca PreferredMaximumHeight y PreferredMaximumWidth para restringir el tamaño máximo al que el usuario puede ajustar la ventana. Se recomienda establecer IsMaximizablefalse en si establece las propiedades de tamaño máximo, ya que estas propiedades restringen el tamaño de la ventana incluso en el estado maximizado. Estas propiedades también afectan a las llamadas a AppWindow. Cambio de tamaño; la ventana no se cambiará de tamaño mayor que el alto y ancho máximo especificados.

Establezca PreferredMinimumHeight y PreferredMinimumWidth para establecer el tamaño mínimo en el que el usuario puede reducir la ventana. Estas propiedades también afectan a las llamadas a AppWindow. Cambio de tamaño; la ventana no se cambiará de tamaño menor que el alto y el ancho mínimos especificados.

Puede establecer IsModal en true para crear una ventana modal. Una ventana modal es una ventana independiente que bloquea la interacción con su ventana de propietario hasta que se cierra. Sin embargo, para crear una ventana modal, también debe establecer la ventana de propietario; De lo contrario, se produce una excepción con este mensaje:

The parameter is incorrect.

The window should have an owner when IsModal=true.

Para establecer la ventana del propietario en una aplicación WinUI, es necesario la interoperabilidad de Win32. Para obtener más información y código de ejemplo, consulte la página AppWindow en la aplicación de ejemplo de la Galería WinUI.

Asignar un presentador

Un moderador solo se puede aplicar a una sola ventana a la vez. Al intentar aplicar el mismo moderador a una segunda ventana, se produce una excepción. Esto significa que si tienes varias ventanas y deseas cambiar cada una a un modo de presentación específico, debes crear varios moderadores del mismo tipo y, a continuación, aplicar cada uno a su propia ventana.

Cuando se aplica un nuevo presentador (la propiedad AppWindow.Presenter cambia), la aplicación recibe una notificación por un evento AppWindow.Changed en el AppWindow afectado, con la propiedad AppWindowChangedEventArgs.DidPresenterChange establecida en true.

Sugerencia

Si aplica un moderador modificado y permite cambiar entre moderadores, asegúrese de mantener una referencia al moderador modificado de modo que pueda volver a aplicarse a AppWindow.

En este ejemplo se muestra cómo hacer lo siguiente:

Aquí, se crea, modifica y aplica un presentador en el constructor de la ventana.

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

En la página que es el contenido de la ventana, puede obtener una referencia a AppWindow y al moderador aplicado.

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

Marco de interfaz de usuario e interoperabilidad de HWND

La clase AppWindow está disponible para cualquier HWND de nivel superior en su aplicación. Esto significa que, al trabajar con un marco de interfaz de usuario de escritorio (incluido WinUI 3), puedes seguir usando el punto de entrada de ese marco para crear una ventana y adjuntar su contenido. Y una vez que haya creado una ventana con ese marco de interfaz de usuario, puede usar las funciones de interoperabilidad de ventanas (consulte a continuación) proporcionadas en windows App SDK para acceder a los métodos, propiedades y eventos correspondientes AppWindow y sus métodos.

Algunas de las ventajas de usar AppWindow (incluso cuando se trabaja con un marco de interfaz de usuario) son:

  • Personalización sencilla de la barra de título; que de forma predeterminada mantiene la interfaz de usuario de Windows 11 (esquinas redondeadas, control flotante del grupo de ajuste).
  • Experiencias de pantalla completa y superposición compacta (imagen en imagen) proporcionadas por el sistema.
  • Superficie de API de Windows Runtime (WinRT) para algunos de los conceptos básicos de ventanas de Win32.

Obtener el AppWindow para las versiones de Windows App SDK anteriores a la 1.3 (u otros marcos de aplicaciones de escritorio)

La Windowpropiedad .AppWindow está disponible en Windows App SDK versión 1.3 y posteriores. Para versiones anteriores, puedes usar el ejemplo de código funcionalmente equivalente en esta sección.

C#. Los contenedores de .NET para las funciones de interoperabilidad de ventanas se implementan como métodos de la clase Microsoft.UI.Win32Interop . Consulta también Llamada a las API de interoperabilidad desde una aplicación con .NET.

C++. Las funciones de interoperabilidad se definen en el archivo de encabezado winrt/Microsoft.ui.interop.h.

En la sección de ejemplo de código siguiente se muestra el código fuente real; pero aquí está el procedimiento para obtener un AppWindow objeto dada una ventana existente.

  1. Obtén el HWND de tu objeto de ventana existente (para el framework de la interfaz de usuario), si aún no lo tienes.
  2. Pase ese HWND a la función de interoperabilidad GetWindowIdFromWindow para recuperar un WindowId.
  3. Pase ese WindowId al método estático AppWindow.GetFromWindowId para recuperar el 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!");
    }
}

Para obtener más ejemplos de cómo trabajar con AppWindow, consulte el ejemplo de la galería de ventanas.

Limitaciones

El SDK de aplicaciones de Windows no proporciona actualmente métodos para asociar contenido del marco de interfaz de usuario a .AppWindow