管理应用窗口(Windows 应用 SDK)
本主题包含 代码示例 部分。
Windows 应用 SDK提供易于使用的 Microsoft.UI.Windowing.AppWindow 类。 AppWindow 与框架无关,适用于所有 Windows 应用,包括 Win32、WPF 和 WinForms。 可以将 AppWindow 与框架无关的性质与 Microsoft.UI.Xaml.Window(专用于 WinUI 3 框架的窗口类)进行对比。 AppWindow 也是通用 Windows 平台 (UWP) Windows.UI.WindowManagement.AppWindow 的演变。
Windows 应用 SDK版本的 Microsoft.UI.Windowing.AppWindow 不依赖于异步模式;它立即向应用提供有关 API 调用是否成功的反馈。 今后,在引入新功能、与 Windows UI/UX 集成以及启用新的开窗方案时,Windows 应用 SDK窗口化 API 将是重点。 建议开始将这些 API 用于开窗操作。
另请参阅安装Windows 应用 SDK工具、创建第一个 WinUI 3 项目和在现有项目中使用Windows 应用 SDK。
AppWindow 类
Microsoft.UI.Windowing.AppWindow 是一种高级窗口化 API,支持易于使用的窗口化方案。 AppWindow 与 Windows UI/UX 和其他应用很好地集成。
AppWindow 表示应用内容的系统托管容器的高级抽象。 它是托管内容的容器;它表示用户在屏幕上调整应用大小和移动应用时与之交互的实体。 如果你熟悉 Win32,可以将“应用窗口”视为 HWND 的高级抽象。 如果你熟悉 UWP,可以将“应用窗口”视为 CoreWindow/ApplicationView/Windows.UI.WindowManagement.AppWindow 的替代。
对于 microsoft.UI.Windowing.AppWindow 的Windows 应用 SDK版本,我们仅支持顶级 HWND。 AppWindow 与顶级 HWND 之间存在 1:1 映射。
AppWindow 对象和 HWND 的生存期是相同的 , AppWindow 在创建窗口后立即可用;当窗口关闭时,它将被销毁。
AppWindowPresenter 类和子类
每个 AppWindow 都有一个 应用 appWindowPresenter (演示者) 。 如果你是使用 Windows.UI.WindowManagement.AppWindow 的 UWP 开发人员,那么这将很熟悉:即使它不是功能和行为的 1:1 映射。 另请参阅 窗口功能迁移。
作为 Win32 应用程序模型的新概念,演示者类似于 (但不等同于) 窗口状态和样式的组合。 某些演示者还定义了 UI/UX 行为,这些行为无法从经典窗口状态和样式属性 ((例如自动隐藏标题栏) )进行检查。
默认情况下,演示者由系统创建,并在创建时应用于 AppWindow 。 在 Windows 应用 SDK 1.0 中,在 Windows 桌面上,演示者的类型为 OverlappedPresenter,它是 AppWindowPresenter 的子类。 应用无需将其藏起来,也无需保留对它的引用,即可在应用另一个演示者后返回到窗口的默认演示者。 这是因为系统在为其创建它的 AppWindow 的生存期内保留此演示者的同一实例;应用可以通过使用 AppWindowPresenterKind.Default 作为参数调用 AppWindow.SetPresenter 方法来重新应用它。
演示者一次只能应用于单个窗口。 尝试将同一演示者应用于第二个窗口会引发异常。 这意味着,如果你有多个窗口,并且你想要将每个窗口切换到特定的演示模式,则需要创建多个相同类型的演示者,然后将每个演示者应用到自己的窗口。
某些演示者具有允许用户在应用自身控制之外进行更改的功能。 发生此类更改时,应用将通过受影响的 AppWindow 上的 AppWindow.Changed 事件通知应用,AppWindowChangedEventArgs.DidPresenterChange 属性设置为 true
。 然后,应用应检查应用的演示者的属性,以查看更改的内容。
应用的呈现器是一个实时对象。 对 AppWindow.Presenter 对象的任何属性的更改将立即生效。
演示者在应用于窗口时无法销毁它。 若要销毁演示者对象,请先向窗口应用不同的演示者对象;这样,你打算销毁的演示者就会从窗口中删除。 可以通过向窗口应用另一个特定演示者,或通过调用 AppWindowPresenterKind.Default 作为参数的 AppWindow.SetPresenter 方法来执行此操作,这将将系统创建的默认演示者重新应用到窗口。 如果碰巧为窗口保留对系统创建的演示者的引用,则此时该引用将有效 (即,首次为窗口创建的实例) 重新应用。
可用的呈现器
提供这些 AppWindowPresenter 派生的演示者,并且可在所有受支持的操作系统版本上使用。
- CompactOverlayPresenter。 创建具有 16:9 纵横比的 固定大小始终位于顶部 的窗口,以实现类似 画中画的体验。
- FullScreenPresenter。 允许窗口进入全屏体验。
- OverlappedPresenter。 系统创建的默认演示者,允许你请求和响应最小化/最大化/还原操作和状态更改。
UI 框架和 HWND 互操作
AppWindow 类可用于应用中的任何顶级 HWND。 这意味着,在使用桌面 UI 框架 (包括 WinUI 3) 时,可以继续使用该框架的入口点来创建窗口并附加其内容。 使用 UI 框架创建窗口后,可以使用窗口互操作函数 (请参阅以下) Windows 应用 SDK中提供,以访问相应的 AppWindow 及其方法、属性和事件。
C# 中的检测示例。 窗口互操作函数的 .NET 包装器作为 Microsoft.UI.Win32Interop 类的方法实现。 另请参阅 从 .NET 应用调用互操作 API。
C++。 互操作函数在 winrt/Microsoft.ui.interop.h 头文件中定义。
下面的 代码示例 部分显示了实际的源代码;但下面是在给定现有窗口的情况下检索 AppWindow 对象的方案:
- 为 UI 框架) 检索现有窗口对象的 HWND ((如果还没有)。
- 将该 HWND 传递给 GetWindowIdFromWindow 互操作函数以检索 WindowId。
- 将该 WindowId 传递到静态 AppWindow.GetFromWindowId 方法以检索 AppWindow。
即使使用 UI 框架) ,使用 AppWindow (的一些好处包括:
- 轻松自定义标题栏;默认情况下,它维护Windows 11 UI (圆角、对齐组浮出控件) 。
- 系统提供的全屏和紧凑覆盖 (画中画) 体验。
- Windows 运行时 (WinRT) 一些核心 Win32 窗口化概念的 API 图面。
代码示例
此代码示例演示如何从 WinUI 3 窗口检索 AppWindow 。 若要使用此示例,请在 桌面) 项目中创建新的空白应用、打包 (WinUI 3 ,然后将代码粘贴到中。
C# 中的检测示例。 该代码示例使用 WinRT.Interop.WindowNative 和 Microsoft.UI.Win32Interop 类 (请参阅 从 .NET 应用) 调用互操作 API 。 另请参阅 检索 (HWND) 的窗口句柄 。
有关如何使用 AppWindow 的其他详细信息,请参阅 Windowing 库示例。
// 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!");
}
}
限制
- AppWindow 仅适用于 (打包和未打包) 的桌面应用;它不适用于 UWP 应用。
- Windows 应用 SDK当前不提供将 UI 框架内容附加到 AppWindow 的方法。 只能使用代码示例部分演示的 HWND 互操作访问方法。
- TitleBar 自定义目前仅在Windows 11或更高版本上受支持。 有关详细信息 ,请参阅标题栏自定义 。