管理應用程式視窗 (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 演進的型態。

Microsoft.UI.Windowing.AppWindow 的 Windows 應用程式 SDK 版本並不依賴非同步模式;它會針對 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 建立的生命週期內保留該展示模式的相同執行個體,而您的應用程式只要呼叫 AppWindow.SetPresenter 方法搭配 AppWindowPresenterKind.Default 參數,就能重新套用。

展示模式一次只能套用至單一視窗。 嘗試將相同的展示模式套用到第二個視窗會擲回例外狀況。 也就是說如果您有多個視窗,且您想將每個視窗切換成特定的展示模式,則需要建立相同類型的多個展示模式,然後將每個展示模式套用至個別的視窗。

某些展示模式具有的功能,可讓使用者在應用程式自己的控制權以外進行變更。 執行這類變更時,應用程式會收到 AppWindow.Changed 事件通知,告知,AppWindow 受影響,且 AppWindowChangedEventArgs.DidPresenterChange 屬性會設為 true。 您的應用程式接著應會檢查已套用的展示模式屬性,查看變更的內容。

套用的展示模式是即時物件。 AppWindow.Presenter 物件的任何屬性發生變更都會立即生效。

展示模式在套用到視窗後無法終止。 若要終止展示模式物件,請先將不同的展示模式物件套用到視窗;如此一來,您想要終止的展示模式就會從視窗移除。 若要執行該動作,您可以將其他特定展示模式套用到視窗,或呼叫 AppWindow.SetPresenter 方法搭配引數 AppWindowPresenterKind.Default,將系統建立的預設展示模式重新套用至視窗。 如果您碰巧為視窗保留了系統建立的展示模式參照,則此參照此時會發揮作用 (也就是系統會重新套用為視窗建立的第一個執行個體)。

可用的展示模式

系統提供這些 AppWindowPresenter 衍生的展示模式,且適用於所有支援的 OS 版本。

  • CompactOverlayPresenter。 建立固定大小的「一律保持在最上方」視窗,其外觀比例為 16:9,適用於類似畫中畫的體驗。
  • FullScreenPresenter。 允許視窗進入全螢幕體驗。
  • OverlappedPresenter。 系統建立的預設展示模式,可讓您要求與回應最小化/最大化/還原作業和狀態變更。

UI 架構和 HWND Interop

AppWindow 類別適用於應用程式中的任何最上層 HWND。 也就是說,您在使用桌面 UI 架構 (包括 WinUI 3) 時,您可以繼續使用該架構的進入點來建立視窗,並附加其內容。 一旦您建立了包含該 UI 架構的視窗後,就可以使用 Windows 應用程式 SDK 提供的視窗化 Interop 函式 (見下方) 來存取對應的 AppWindow 及其方法、屬性和事件。

使用 AppWindow (即使使用 UI 架構) 的幾種優點如下:

  • 簡單的標題列自訂;預設會維持 Windows 11 UI (圓角、貼齊群組飛出視窗)。
  • 系統提供的全螢幕和精簡重疊 (畫中畫) 體驗。
  • Windows 執行階段 (WinRT) API 介面,適用於部分核心 Win32 視窗化概念。

程式碼範例

以下程式碼範例示範如何使用 Microsoft.UI.Xaml.Window.AppWindow 屬性擷取 WinUI 3 視窗中的 Microsoft.UI.Windowing.AppWindow。 若要使用此範例,請建立新的已封裝的空白應用程式 (桌面版 WinUI 3) 專案,並貼上程式碼。

如需 詳細了解如何使用 AppWindow,請參閱視窗化程式庫範例

// MainWindow.xaml.cs
private void myButton_Click(object sender, RoutedEventArgs e)
{
    // Retrieve the AppWindow for the current (XAML) WinUI 3 window.
    Microsoft.UI.Windowing.AppWindow appWindow = this.AppWindow;

    if (appWindow != null)
    {
        // With a non-null AppWindow object, 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 <winrt/Microsoft.UI.Windowing.h> // For the AppWindow class.

// mainwindow.xaml.cpp
void MainWindow::myButton_Click(IInspectable const&, RoutedEventArgs const&)
{
    // Retrieve the AppWindow for the current (XAML) WinUI 3 window.
    Microsoft::UI::Windowing::AppWindow appWindow = this->AppWindow();

    if (appWindow)
    {
        // With a non-null AppWindow object, 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!");
    }
}

1.3 版 (或其他桌面應用程式架構) 以前的 Windows 應用程式 SDK 版本程式碼範例

Microsoft.UI.Xaml.Window.AppWindow 屬性 (上述程式碼範例所使用者) 適用於 Windows 應用程式 SDK 1.3 版和之後的版本。 如為舊版,您可以使用與本節的程式碼範例對等的功能。

C#: 視窗化 Interop 函式的 .NET 包裝函式會以 Microsoft.UI.Win32Interop 類別的方法來實作。 另請參閱從 .NET 應用程式呼叫 Interop API

C++: Interop 函式定義於 winrt/Microsoft.ui.interop.h 標頭檔案中。

下列程式碼範例區段所示為實際的原始程式碼,但以下步驟是用於擷取現有視窗的 AppWindow 物件:

  1. 如果您還沒有為現有視窗物件 (適用於 UI 架構) HWND,請先擷取。
  2. HWND 傳遞至 GetWindowIdFromWindow Interop 函式以擷取 WindowId
  3. WindowId 傳遞至靜態 AppWindow.GetFromWindowId 方法,以擷取 AppWindow
// 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 the AppWindow class.

// 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->m_inner.as<::IWindowNative>() };
    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 是 WinUI 3 API。 這表示它僅適用於桌面應用程式 (已封裝和未封裝皆是),且不適用於 UWP 應用程式。
  • Windows 應用程式 SDK 目前不提供將 UI 架構內容附加至 AppWindow 的方法。 請參閱程式碼範例一節。
  • Windows 11 和之後的版本支援標題列自訂;Windows 10 1.2 版和之後的 Windows 應用程式 SDK 版本也支援。 如需詳細資訊,請參閱標題列自訂