Manage app windows (Windows App SDK)

This topic contains a Code example section.

The Windows App SDK provides the easy-to-use Microsoft.UI.Windowing.AppWindow class. AppWindow is framework-agnostic, and available to all Windows apps including Win32, WPF, and WinForms. You can contrast the framework-agnostic nature of AppWindow to Microsoft.UI.Xaml.Window, which is the window class specifically for the WinUI 3 framework. AppWindow is also an evolution of the Universal Windows Platform's (UWP's) Windows.UI.WindowManagement.AppWindow.

The Windows App SDK version of Microsoft.UI.Windowing.AppWindow doesn't rely on asynchronous patterns; and it provides immediate feedback to your app about whether API calls have succeeded. Going forward—when it comes to introducing new features, integrating with Windows UI/UX, and enabling new windowing scenarios—the Windows App SDK windowing APIs will be the focus. We recommend that you start leveraging these APIs for your windowing operations.

Also see Install tools for the Windows App SDK, Create your first WinUI 3 project, and Use the Windows App SDK in an existing project.

The AppWindow class

Microsoft.UI.Windowing.AppWindow is a high-level windowing API that allows for easy-to-use windowing scenarios. AppWindow integrates well with the Windows UI/UX and with other apps.

AppWindow represents a high-level abstraction of a system-managed container for the content of an app. It's the container in which your content is hosted; and it represents the entity that users interact with when they resize and move your app on-screen. If you're familiar with Win32, the "app window" can be seen as a high-level abstraction of the HWND. If you're familiar with UWP, the "app window" can be seen as a replacement for CoreWindow/ApplicationView/Windows.UI.WindowManagement.AppWindow.

For the Windows App SDK version of Microsoft.UI.Windowing.AppWindow we're supporting only top-level HWNDs. There's a 1:1 mapping between an AppWindow and a top-level HWND.

The lifetime of an AppWindow object and an HWND is the same—the AppWindow is available immediately after the window has been created; and it's destroyed when the window is closed.

The AppWindowPresenter class, and subclasses

Each AppWindow has an AppWindowPresenter (presenter) applied to it. If you're a UWP developer who's worked with Windows.UI.WindowManagement.AppWindow, then this will be familiar; even if it's not a 1:1 mapping of functionality and behavior. Also see See Windowing functionality migration.

As a new concept to the Win32 application model, a presenter is akin to (but not the same as) a combination of window state and styles. Some presenters also have UI/UX behaviors defined in them that aren't inspectable from classic window state and style properties (such as an auto-hiding titlebar).

By default, a presenter is created by the system, and applied to an AppWindow at creation time. In the Windows App SDK 1.0 Stable, on Windows desktop, the type of presenter is OverlappedPresenter, which is a subclass of AppWindowPresenter. There's no need for your app to stash it, nor to keep a reference to it in order to go back to the default presenter for a window after having applied another presenter. That's because the system keeps the same instance of this presenter around for the lifetime of the AppWindow for which it was created; and your app can reapply it by calling the AppWindow.SetPresenter method with AppWindowPresenterKind.Default as a parameter.

A presenter can be applied to only a single window at a time. Trying to apply the same presenter to a second window throws an exception. That means that if you have multiple windows, and you want to switch each one into a specific presentation mode, then you need to create multiple presenters of the same kind, and then apply each to its own window.

Some presenters have functionality that allows a user to make changes outside of your app's own control. When such a change happens, your app is notified by an AppWindow.Changed event on the affected AppWindow, with the AppWindowChangedEventArgs.DidPresenterChange property set to true. Your app should then inspect the property of the applied presenter to see what changed.

The applied presenter is a live object. A change to any property of the AppWindow.Presenter object takes effect immediately.

A presenter can't be destroyed while it's applied to a window. To destroy a presenter object, first apply a different presenter object to the window; that way, the presenter that you intend to destroy is removed from the window. You can do that either by applying another specific presenter to the window, or by calling the AppWindow.SetPresenter method with AppWindowPresenterKind.Default as an argument, which will reapply the default system-created presenter to the window. If you happened to keep a reference to the system-created presenter for the window, then it will be valid at this point (that is, the instance that was first created for the window is re-applied).

Available presenters

These AppWindowPresenter-derived presenters are provided, and they're available on all of the supported OS versions.

  • CompactOverlayPresenter. Creates an always-on-top window of a fixed size, with a 16:9 aspect ratio to allow for picture-in-picture-like experiences.
  • FullScreenPresenter. Allows a window to go into a full-screen experience.
  • OverlappedPresenter. The system-created default presenter, which allows you to request and react to minimize/maximize/restore operations and state changes.

UI framework and HWND interop

The AppWindow class is available for any top-level HWND in your app. That means that when you're working with a UI framework you can continue to use that framework's entry point for creating a window, and attaching its content. And once you've created a window, you can use the windowing interop functions provided in the Windows App SDK to access the corresponding AppWindow and its methods, properties, and events.

C#. .NET wrappers for the windowing interop functions are implemented as methods of the Microsoft.UI.Win32Interop class. Also see Call interop APIs from a .NET app.

C++. The interop functions are defined in the winrt/Microsoft.ui.interop.h header file.

To retrieve an AppWindow object, given an HWND for an existing window, use the GetWindowIdFromWindow interop function. See the Code example section below.

Some of the benefits of using AppWindow even when working with a UI framework are:

  • Easy title bar customization, which by default maintains the Windows 11 UI (rounded corners, snap group flyout).
  • System-provided full-screen and compact overlay (picture-in-picture) experiences.
  • Windows Runtime (WinRT) API surface for some of the core Win32 windowing concepts.

Code example

This code example demonstrates how to retrieve an AppWindow from a WinUI 3 window. To use the example, create a new Blank App, Packaged (WinUI 3 in Desktop) project, and paste the code in.

C#. The code example uses the WinRT.Interop.WindowNative and the Microsoft.UI.Win32Interop classes (see Call interop APIs from a .NET app). Also see Retrieve a window handle (HWND).

For additional details on how to work with AppWindow, see the Windowing gallery sample.

// 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 AppWindow::GetFromWindowId

// 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->try_as<::IWindowNative>() };
    winrt::check_bool(windowNative);
    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!");
    }
}

Limitations

  • AppWindow is available only to desktop apps (both packaged and unpackaged); it's not available to UWP apps.
  • The Windows App SDK doesn't currently provide methods for attaching UI framework content to an AppWindow. You're limited to using the HWND interop access methods demonstrated in the Code example section.
  • TitleBar customization is currently only supported on Windows 11 or later versions. See Title bar customization for details.