Edit

Share via


Windowing overview for WinUI and Windows App SDK

Windowing functionality in a WinUI app is provided by a combination of the XAML Window class and the AppWindow class, both of which are based on the Win32 HWND model.

The WinUI 3 Gallery app includes interactive examples of most WinUI 3 controls, features, and functionality. Get the app from the Microsoft Store or get the source code on GitHub

XAML Window

In your app, the window object is an instance of the Microsoft.UI.Xaml.Window class (or a derived class) that represents the window in your program code. You create it directly with a call to the constructor. The XAML Window is where you attach your app content and manage the lifecycle of your app's windows.

HWND

The application window is created by the Windows operating system and is represented by a Win32 window object. It's a system-managed container in which your content is hosted, and represents the entity that users interact with when they resize and move your app on-screen. (See About Windows in the Win32 documentation for more info.)

After Windows creates the application window, the creation function returns a window handle (HWND) that uniquely identifies the window. A window handle has the HWND data type, although it's surfaced in C# as an IntPtr. It's an opaque handle to an internal Windows data structure that corresponds to a window that's drawn by the OS and consumes system resources when present.

The HWND is created after the XAML Window object, typically when the Window.Activate method is called.

AppWindow

The Windows App SDK provides additional windowing functionality through the Microsoft.UI.Windowing.AppWindow class. AppWindow represents a high-level abstraction of the HWND. There's a 1:1 mapping between an AppWindow and a top-level HWND in your app. AppWindow and its related classes provide APIs that let you manage many aspects of your app's top-level windows without the need to access the HWND directly.

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.

Windowing API diagram

This diagram shows the relationship between the classes and APIs that you use to manage windows in your app, and which classes are responsible for each part of window management. In some cases, like ExtendsContentIntoTitleBar, the API is a member of AppWindow to make it available to other UI frameworks, but is also exposed on the Window class for convenience. The diagram is not comprehensive, but shows the most commonly used APIs.

win u i windowing diagram

Note

You can use AppWindow APIs with any UI framework that the Windows App SDK supports - Win32, WPF, WinForms, or WinUI 3. For frameworks other than WinUI 3, the functionality shown in the XAML Window box of the diagram would be replaced by the appropriate framework-specific windowing APIs:

Window/AppWindow API comparison

If you use WinUI 3 XAML as your app's UI framework, both the Window and the AppWindow APIs are available to you. Starting in Windows App SDK 1.4, you can use the Window.AppWindow property to get an AppWindow object from an existing XAML window. With this AppWindow object you have access to the additional window management APIs.

Important

If you're not using WinUI 3 1.3 or later, use interop APIs to get the AppWindow in order to use the AppWindow APIs. For more about the interop APIs, see Manage app windows - UI framework and HWND interop and the Windowing gallery sample.

Lifetime management

XAML Window AppWindow
Constructor Create, GetFromWindowId
Activate Show, Hide
Close, Closed Destroy, Destroying, Closing
>>> Id, OwnerWindowId

When you create a new WinUI project in Visual Studio, the project template provides a MainWindow class for you, which is a sub-class of Window. If your app only needs one window, this is all you need. To learn how to create and manage additional windows, and why you might want to, see Show multiple windows for your app.

The AppWindow class has APIs to create and destroy a new window; however, for a WinUI app, you won't do this in practice because there is no API to attach content to the window you create. Instead, you get an instance of AppWindow that's created by the system and associated with the XAML Window and HWND. In WinUI 1.4 and later, you can use the Window.AppWindow property to get the instance of AppWindow. In other cases, you can use the static AppWindow.GetFromWindowId method to get the AppWindow instance. See Manage app windows for more info.

Content

XAML Window AppWindow
Content N/A

The Window.Content property is where you attach your app content to the window that displays it. You can do this in XAML or in code.

Title, icon, and title bar

XAML Window AppWindow
Title Title
SetTitleBar TitleBar
>>> SetIcon, SetTaskbarIcon, SetTitleBarIcon
ExtendsContentIntoTitleBar AppWindow.TitleBar.ExtendsContentIntoTitleBar

You can modify your app's title bar to varying degrees; setting the title and icon, changing the colors, or completely replacing the title bar with custom app content.

For information about using title bar APIs, including code examples, see Title bar customization.

Size and position

XAML Window AppWindow
Bounds Position, Size, ClientSize
SizeChanged Changed (DidPositionChange, DidSizeChange)
>>> Move, Resize, ResizeClient, MoveAndResize
>>> MoveInZOrderAtBottom, MoveInZOrderAtTop, MoveInZOrderBelow

You use the Window.Bounds property and SizeChanged event for managing things in your app UI, like moving elements around when the window size changes. XAML uses effective pixels (epx), not actual physical pixels. Effective pixels are a virtual unit of measurement, and they're used to express layout dimensions and spacing, independent of screen density.

AppWindow, on the other hand, uses the Window Coordinate System, where the basic unit of measurement is physical device pixels. You use the the AppWindow APIs for windowing actions, like resizing the window or moving it in relation to something else on the screen.

In some cases you might need to use measurements from one class in the other class, in which case you'll need to convert between effective pixels and device pixels. For example, if you set drag regions in a custom title bar, you'll need to convert measurements. For an example of how to use XamlRoot.RasterizationScale to convert measurements, see the interactive content section of the Title bar customization article.

Appearance and behavior

XAML Window AppWindow
SystemBackdrop N/A
>>> Presenter, SetPresenter
>>> IsShownInSwitchers
Visible, VisibilityChanged IsVisible, Changed (DidVisibilityChange)
DispatcherQueue DispatcherQueue, AssociateWithDispatcherQueue
Compositor N/A

XAML Window APIs are generally responsible for the appearance of your app content, like the background. For more info about SystemBackdrop, see Apply Mica or Acrylic materials.

AppWindow APIs are responsible for the non-client portion of the window and your app's interaction with the Windows OS.

Note

The XAML Window class has several properties that were carried over from the UWP Windows.UI.Xaml.Window class, but are not supported in WinUI apps. These properties always have a null value and are not used in WinUI apps: CoreWindow, Current, and Dispatcher.

Track the current window

Even though the Current property is not supported in WinUI apps, you still might need to access the Window APIs from other places in your app. For example, you might need to get the Window bounds or handle the Window.SizeChanged event from code for a Page. In this case, you can provide access to the Window in a similar way to the Current property by using a public static property on your App class.

To do so, modify the Window declaration in the App class as shown here.

// App.xaml.cs in a WinUI app
public partial class App : Application
{
    ...
    public static Window Window { get { return m_window; } }
    private static Window m_window;
}
// App.xaml.h in a WinUI app
...
struct App : AppT<App>
{
    ...
    static winrt::Microsoft::UI::Xaml::Window Window(){ return window; };

private:
    static winrt::Microsoft::UI::Xaml::Window window;
};
...

// App.xaml.cpp
...
winrt::Microsoft::UI::Xaml::Window App::window{ nullptr };
...

Then, to access the Window from other places in your app, use App.Window, like this:

// MainPage.xaml.cs in a WinUI app
var width = App.Window.Bounds.Width;
// MainPage.xaml.cpp in a WinUI app
#include <App.xaml.h>
auto width{ App::Window().Bounds().Width };

Important

Using a static Window property in your App class is useful if your app only uses a single window. If your app uses multiple windows, you should use WindowId to track the Window instances instead, to ensure that you are accessing the correct instance of Window. See Show multiple windows for your app for more info and examples.