Edit

Share via


Windowing functionality migration

This topic contains guidance related to window management, including migrating from UWP's ApplicationView/CoreWindow or AppWindow to the Window App SDK Microsoft.UI.Windowing.AppWindow.

Important APIs

Summary of API and/or feature differences

The Windows App SDK provides a Microsoft.UI.Windowing.AppWindow class that's based on the Win32 HWND model. That AppWindow class is the Windows App SDK's version of UWP's ApplicationView/CoreWindow and AppWindow.

To take advantage of the Windows App SDK windowing APIs means that you'll migrate your UWP code to use the Win32 model. For more info about the Windows App SDK AppWindow, see Manage app windows.

Tip

The Manage app windows topic contains a code example demonstrating how to retrieve an AppWindow from a WinUI 3 window. In your WinUI 3 app, use that code pattern so that you can call the AppWindow APIs mentioned in the rest of this topic.

Window types in UWP versus the Windows App SDK

In a UWP app, you can host window content using ApplicationView/CoreWindow, or AppWindow. The work involved in migrating that code to the Windows App SDK depends on which of those two windowing models your UWP app uses. If you're familiar with UWP's Windows.UI.WindowManagement.AppWindow, then you might see similarities between that and Microsoft.UI.Windowing.AppWindow.

UWP window types

Windows App SDK window type

Keep in mind that the differences in windowing models between UWP and Win32 mean that there's not a direct 1:1 mapping between the UWP API surface and the Windows App SDK API surface. Even for class and member names that do carry over from UWP (reflected in this topic's mapping tables), behavior might also differ.

Splash screens

Unlike UWP apps, Win32 apps don't by default show a splash screen on launch. UWP apps relying on this feature for their launch experience might choose to implement a custom transition to their first app window.

Create, show, close, and destroy a window

The lifetime of a Microsoft.UI.Windowing.AppWindow is the same as for an HWND; meaning that the AppWindow object is available immediately after the window has been created, and is destroyed when the window is closed.

Create and show

AppWindow.Create creates an app window with the default configuration. Creating and showing a window is only necessary for scenarios where you're not working with a UI framework. If you're migrating your UWP app to a Win32-compatible UI framework, then you can still reach your AppWindow object from an already-created window by using the windowing interop methods.

Close

In UWP, ApplicationView.TryConsolidateAsync is the programmatic equivalent of the user initiating a close gesture. This concept of consolidation (in UWP's ApplicationView/CoreWindow windowing model) doesn't exist in Win32. Win32 doesn't require that windows exist in separate threads. Replicating the UWP's ApplicationView/CoreWindow windowing model would require the developer to create a new thread, and create a new window there. Under the Win32 model, the default system behavior is Close > Hide > Destroy.

UWP ApplicationView/CoreWindow UWP AppWindow Windows App SDK
ApplicationView.TryConsolidateAsync AppWindow.CloseAsync AppWindow.Destroy

Basic window customization

As you migrate from UWP to the Windows App SDK, you can expect the same experience from your default AppWindow. But if needed, you can change the default Microsoft.UI.Windowing.AppWindow for customized windowing experiences. See Microsoft.UI.Windowing.AppWindow for more info on how to customize your windows.

Resizing a window

UWP ApplicationView/CoreWindow UWP AppWindow Windows App SDK
ApplicationView.TryResizeView AppWindow.RequestSize AppWindow.Resize
CoreWindow.Bounds (commonly appears in C# as CoreWindow.GetForCurrentThread.Bounds) AppWindowPlacement.Size AppWindow.Size

Positioning a window

UWP ApplicationView/CoreWindow UWP AppWindow Windows App SDK
Not possible AppWindow.GetPlacement AppWindow.Position
Not possible Appwindow.RequestMoveXxx AppWindow.Move

Window title

UWP ApplicationView/CoreWindow UWP AppWindow Windows App SDK
ApplicationView.Title AppWindow.Title AppWindow.Title

Compact overlay, and full-screen

Apps that enter into compact overlay, or full-screen, should take advantage of the Windows App SDK AppWindowPresenter. If you're familiar with the UWP AppWindow, then you might already be familiar with the concept of presenters.

There isn't a 1:1 mapping of functionality and behavior from UWP app window presenters to Windows App SDK app window presenters. If you have a UWP ApplicationView/CoreWindow app, then you can still have compact overlay (picture-in-picture) or full-screen windowing experiences in your app, but the concept of presenters might be new to you. For more information on app window presenters, see Presenters. By default, an overlapped presenter is applied to an AppWindow at creation time. CompactOverlay and FullScreen are the only available presenters, aside from default.

Compact overlay

If you used UWP's ApplicationViewMode or AppWindowPresentionKind to present a compact overlay window, then you should use the compact overlay AppWindowPresenterKind. The Microsoft.UI.Windowing.CompactOverlayPresenter supports only three fixed window sizes at a 16:9 aspect ratio, and can't be resized by the user. Instead of ApplicationViewMode.TryEnterViewModeAsync or AppWindowPresenterKind.RequestPresentation, you should use AppWindow.SetPresenter to change the presentation of the AppWindow.

UWP ApplicationView/CoreWindow UWP AppWindow Windows App SDK
ApplicationViewMode.CompactOverlay AppWindowPresentationKind.CompactOverlay AppWindowPresenterKind.CompactOverlay
ApplicationView.TryEnterViewModeAsync with ApplicationViewMode.CompactOverlay AppWindowPresenter.RequestPresentation with AppWindowPresenterKind.CompactOverlay AppWindow.SetPresenter with AppWindowPresenterKind.CompactOverlay

Full-screen

If you used UWP's ApplicationViewWindowingMode or AppWindowPresentionKind classes to present a full-screen window, then you should use the full-screen AppWindowPresenterKind. The Windows App SDK supports only the most restrictive full-screen experience (that is, when FullScreen is IsExclusive). For ApplicationView/CoreWindow, you can use the ApplicationView.ExitFullScreenMode to take the app out of full-screen. When using presenters, you can take an app out of full-screen by setting the presenter back to overlapped/default by using AppWindow.SetPresenter.

UWP ApplicationView/CoreWindow UWP AppWindow Windows App SDK
ApplicationViewWindowingMode.FullScreen AppWindowPresentationKind.FullScreen AppWindowPresenterKind.FullScreen
ApplicationView.TryEnterFullScreenMode AppWindowPresenter.RequestPresentation with AppWindowPresenterKind.FullScreen AppWindow.SetPresenter with AppWindowPresenterKind.FullScreen

For more details on how to work with app window presenters, see the Windowing gallery sample. It demonstrates how to toggle different app window presenter states.

Custom title bar

Note

Title bar customization APIs currently work on Windows 11 only. We recommend that you check AppWindowTitleBar.IsCustomizationSupported in your code before you call these APIs.

If your app uses a default title bar, then there's no additional title bar work needed when you migrate to Win32. If on the other hand your UWP app has a custom title bar, then it's possible to recreate the following scenarios in your Windows App SDK app.

  1. Customize the system-drawn title bar
  2. App-drawn custom title bar

Code that uses the UWP ApplicationViewTitleBar, CoreApplicationViewTitleBar, and AppWindowTitleBar classes migrates to using the Windows App SDK Microsoft.UI.Windowing.AppWindowTitleBar class.

Customize the system-drawn title bar

Here's a table of the color customization APIs.

Note

When AppWindowTitleBar.ExtendsContentIntoTitleBar is true, transparency is supported only for the following properties: AppWindowTitleBar.ButtonBackgroundColor, AppWindowTitleBar.ButtonInactiveBackgroundColor, AppWindowTitleBar.ButtonPressedBackgroundColor, AppWindowTitleBar.ButtonHoverBackgroundColor and AppWindowTitleBar.BackgroundColor (implicitly set).

These Windows App SDK APIs are for further customization of the system-drawn title bar in addition to the AppWindow.Title API.

  • AppWindow.SetIcon. Sets the title bar and taskbar icon picture using either an hIcon handle or a string path to a resource or to a file.
  • AppWindowTitleBar.IconShowOptions. Gets or sets a value that specifies how the window icon is displayed in the title bar. Supports two values currently—HideIconAndSystemMenu and ShowIconAndSystemMenu.
  • AppWindowTitleBar.ResetToDefault. Resets the current title bar back to the default settings for the window.

App-drawn custom title bar (full customization)

If you're migrating to using AppWindowTitleBar, then we recommend that you check AppWindowTitleBar.IsCustomizationSupported in your code before calling the following custom title bar APIs.

UWP ApplicationView/CoreWindow Windows App SDK AppWindow
CoreApplicationViewTitleBar.ExtendViewIntoTitleBar AppWindowTitleBar.ExtendsContentIntoTitleBar
The platform continues to draw the Minimize/Maximize/Close buttons for you, and reports the occlusion information.
CoreApplicationViewTitleBar.SystemOverlayLeftInset AppWindowTitleBar.LeftInset
CoreApplicationViewTitleBar.SystemOverlayRightInset AppWindowTitleBar.RightInset
CoreApplicationViewTitleBar.Height AppWindowTitleBar.Height
AppWindowTitleBarOcclusion
AppWindowTitleBar.GetTitleBarOcclusions
Represents the system-reserved regions of the app window that will occlude app content if ExtendsContentIntoTitleBar is true. The Windows App SDK AppWindow left and right inset information, coupled with title bar height, provide the same information.
AppWindowTitleBar.LeftInset, AppWindowTitleBar.RightInset, AppWindowTitleBar.Height

These Windows App SDK APIs are for full title bar customization.

These UWP AppWindow APIs have no direct 1:1 mapping to a Windows App SDK API.

For more details on how to work with AppWindowTitleBar, see the Windowing gallery sample. It demonstrates how to create a custom color title bar and how to draw a custom title bar.

Event handling

If your UWP app uses the AppWindow.Changed event, then you can migrate that code to the Microsoft.UI.Windowing.AppWindow.Changed event.

Size changed event

When migrating size changed event-handling code, you should switch to using the Windows App SDK AppWindowChangedEventArgs.DidSizeChange property. The value is true if the size of the app window changed, otherwise it's false.

MainPage and MainWindow

When you create a new UWP project in Visual Studio, the project template provides you with a MainPage class. For your app, you might have renamed that class (and/or added more pages and user controls). The project template also provides you with navigation code in the methods of the App class.

When you create a new Windows App SDK project in Visual Studio, the project template provides you with a MainWindow class (of type Microsoft.UI.Xaml.Window), but no Page. And the project template doesn't provide any navigation code.

However, you have the option to add pages and user controls to your Windows App SDK project. For example, you could add a new page item to the project (WinUI > Blank Page (WinUI 3)), and name it MainPage.xaml, or some other name. That would add to your project a new class of type Microsoft.UI.Xaml.Controls.Page. Then, for info about adding navigation code to the project, see Do I need to implement page navigation?.

For Windows App SDK apps that are simple enough, you needn't create pages or user controls, and you can copy your XAML markup and code-behind into MainWindow. But for info about exceptions to that workflow, see Visual State Manager, and Page.Resources.

Change CoreWindow.Dispatcher to Window.DispatcherQueue

Some use cases for UWP's Windows.UI.Core.CoreWindow class migrate to the Windows App SDK's Microsoft.UI.Xaml.Window.

For example, if you're using the Windows.UI.Core.CoreWindow.Dispatcher property in your UWP app, then the solution is not to migrate to the Microsoft.UI.Xaml.Window.Dispatcher property (which always returns null). Instead, migrate to the Microsoft.UI.Xaml.Window.DispatcherQueue property, which returns a Microsoft.UI.Dispatching.DispatcherQueue.

For more info, and code examples, see Change Windows.UI.Core.CoreDispatcher to Microsoft.UI.Dispatching.DispatcherQueue.