管理应用窗口(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版本,我们仅支持顶级 HWNDAppWindow 与顶级 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 对象的方案:

  1. 为 UI 框架) 检索现有窗口对象的 HWND ((如果还没有)。
  2. 将该 HWND 传递给 GetWindowIdFromWindow 互操作函数以检索 WindowId
  3. 将该 WindowId 传递到静态 AppWindow.GetFromWindowId 方法以检索 AppWindow

即使使用 UI 框架) ,使用 AppWindow (的一些好处包括:

  • 轻松自定义标题栏;默认情况下,它维护Windows 11 UI (圆角、对齐组浮出控件) 。
  • 系统提供的全屏和紧凑覆盖 (画中画) 体验。
  • Windows 运行时 (WinRT) 一些核心 Win32 窗口化概念的 API 图面。

代码示例

此代码示例演示如何从 WinUI 3 窗口检索 AppWindow 。 若要使用此示例,请在 桌面) 项目中创建新的空白应用、打包 (WinUI 3 ,然后将代码粘贴到中。

C# 中的检测示例。 该代码示例使用 WinRT.Interop.WindowNativeMicrosoft.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或更高版本上受支持。 有关详细信息 ,请参阅标题栏自定义