乘風破浪,遇見最美Windows 11之現代Windows桌面應用開發 - 實現桌面應用現代化


關於構建現代Windows桌面應用

https://docs.microsoft.com/zh-cn/windows/apps/get-started/

若要構建適用於Windows 11Windows 10的新應用,首先要決定構建哪種類型的應用。Visual Studio中的Windows.NET開發工具提供了幾種可以構建的不同類型的應用,每種都有自己的VisualStudio項目類型和不同的優勢。

image

每種應用類型都包括應用模型(用於定義應用的生命周期)、默認UI框架(用於創建在Windows桌面環境中運行應用,例如Word和Excel)以及對一組全面的托管API本機API的訪問權限(用於使用Windows功能)。其中一些平台有一些共同的特征,更適用於特定類型的應用程序。

無論選擇從哪種應用類型開始,你都有權訪問大多數Windows平台功能,從而在應用中提供新式體驗。例如,即使生成WPF、Windows窗體或經典Win32桌面應用,仍可以使用MSIX包部署Windows OS和Windows SDK提供的Windows運行時(WinRT)API以及Windows應用SDK(Windows App SDK)提供的API

桌面應用類型

https://www.microsoft.com/design/fluent/

應用類型 備注說明
WinUI3 Windows UI庫(WinUI)3是適用於Windows桌面應用的初裝本機用戶界面(UI)框架,包括使用C#和.NET的托管應用以及將C++與Win32API結合使用的本機應用。通過將Fluent Design System整合到所有體驗、控件和樣式中,WinUI使用最新的UI模式提供一致、直觀且可訪問的體驗。

若要生成WinUI 3應用,請從Windows應用SDK(Windows App SDK)中提供的項目模板之一開始。Windows應用SDK(Windows App SDK)提供了一組統一的API和工具,各種目標Windows OS版本上的任何C++ Win32或C# .NET應用都能夠一致地使用它們。
本機Win32 本機Win32桌面應用(有時也稱為經典桌面應用)是本機Windows應用程序的原始應用類型,需要具備對Windows和硬件的直接訪問權限。這使得此應用類型成為需要最高級別性能和直接訪問系統硬件的應用程序的理想選擇。

與在托管運行時環境上(如WinRT和.NET)相比,將Win32API與C++結合使用可以實現最高級別的性能和效率,方法是通過使用非托管代碼對目標平台進行更多控制。但是,對應用程序的執行進行這種級別的控制需要更加謹慎和更集中的注意力才能正確執行,同時,需犧牲開發效率以提高運行時性能。

以下是Win32API和C++提供的一些主要功能,使你能夠生成高性能應用程序。

* 硬件級優化,包括對資源分配、對象生存期、數據布局、對齊、字節封裝等的嚴格控制。
* 通過內部函數訪問面向性能的指令集,如SSE和AVX。
* 使用模板進行高效且類型安全的泛型編程。
* 高效且安全的容器和算法。
* DirectX,尤其是Direct3D和DirectCompute(請注意,UWP還提供DirectX互操作)。
* 使用C++/WinRT創建新式桌面Win32應用,這些應用具有對Windows運行時(WinRT)API的一級訪問權限
WPF WPF是為托管型Windows應用程序而建立的平台,具有對.NET 5或.NET Framework的訪問權限,並使用XAML標記將UI與代碼分隔開來。此平台旨在用於需要復雜UI、自定義樣式和圖形密集型方案的桌面應用程序。WPF開發技能類似於UWP開發技能,因此從WPF遷移到UWP應用比從Windows窗體遷移更容易。
Windows窗體 Windows窗體是用於托管型Windows應用程序的原始平台,具有一個輕型UI模型和對.NET5或.NET Framework的訪問權限。它擅長幫助開發人員快速開始構建應用程序,即使對於剛接觸該平台的開發人員也是如此。這是一種基於窗體的快速應用程序開發平台,其中包含大量內置的可視化和非可視化拖放控件。Windows窗體不使用XAML,因此,如果決定以后將應用程序擴展到UWP,則需要完全重寫UI。
Windows版React Native React Native是Facebook的一個開發平台,可用於構建跨平台應用。React Native for Windows引入了對Windows10和Windows11 SDK的React Native支持,使你能夠使用JavaScript為Windows 10和Windows 11支持的所有設備(包括電腦、平板電腦、二合一、Xbox、混合現實設備等)構建本機Windows應用。

通過使用React Native for Windows,可以使用JavaScript或TypeScript編寫大部分或全部應用代碼,該框架會生成本機UWP XAML應用程序。如果你的應用需要調用平台API,通常可以通過眾多社區模塊中的某個來實現此目的,或者,如果尚不存在這樣一個模塊,也可以輕松編寫一個本機模塊來公開它。
UWP 通用Windows平台(UWP)為所有運行Windows10及更高版本的設備提供通用類型系統、API和應用程序模型。UWP不僅可以用於為Windows電腦創建桌面應用程序,同時,它也是Xbox、HoloLens和SurfaceHub應用程序的唯一支持平台。UWP應用可以是本機應用,也可以是托管應用。

UWP是一個高度可自定義的平台,使用XAML標記將UI(展示)與代碼(業務邏輯)分隔。UWP適用於需要復雜UI、自定義樣式和圖形密集型方案的桌面應用。UWP還針對默認UX體驗內置了對FluentDesign系統的支持,並提供了對Windows運行時(WinRT)API的訪問。

升級已有桌面應用

https://docs.microsoft.com/zh-cn/windows/apps/desktop/modernize/

如果你當前有WPFWindows窗體本機Win32桌面應用,Windows OS通用Windows應用SDK提供了很多功能可用來在應用中提供新式體驗。你可按照自己的進度,在應用中將其中大多數功能用作模塊化組件,而不必為其他平台重新編寫應用。

有很多功能可用於增強你的現有桌面應用,下面僅舉幾例:

  • Windows應用SDK NuGet包安裝到現有項目中,以調用Windows應用SDKAPI,以在應用中本地化資源、呈現文本等。

https://docs.microsoft.com/zh-cn/windows-app-sdk/get-started.md#use-the-windows-app-sdk-in-an-existing-project

  • 調用Windows運行時(WinRT)API以使用最新的Windows功能增強桌面應用。

https://docs.microsoft.com/zh-cn/windows/apps/desktop/modernize/desktop-to-uwp-enhance

  • 使用包擴展,將桌面應用與新式Windows體驗集成。例如,將“啟動”磁貼指向你的應用,將你的應用設為共享目標,或者通過你的應用發送toast通知。

https://docs.microsoft.com/zh-cn/windows/apps/desktop/modernize/desktop-to-uwp-extensions

  • 使用XAML孤島在桌面應用中托管WinRT XAML控件。很多最新Windows UI功能僅適用於WinRT XAML控件。

https://docs.microsoft.com/zh-cn/windows/apps/desktop/modernize/xaml-islands

  • 使用MSIX打包和部署桌面應用。MSIX是一種新式Windows應用包格式,提供適合所有Windows應用的通用打包體驗。MSIX匯集了MSI.appxApp-VClickOnce安裝技術的最佳方面,按照安全可靠的目標構建。

https://docs.microsoft.com/zh-cn/windows/msix/

Windows 11的桌面應用中的圓角

https://docs.microsoft.com/zh-cn/windows/apps/desktop/modernize/apply-rounded-corners

圓角是Windows 11幾何的最顯而易見的特征。在Windows 11上,系統會將所有預裝應用(Inbox App)(包括所有UWP應用)和大多數其他應用的頂級窗口自動設為圓角(但可能不會對某些Win32應用執行圓角操作)。

根據設計,應用在最大化、貼靠、在虛擬機(VM)中運行,或者在Windows虛擬桌面(WVD)上運行時不是圓角。

image

我的應用為什么不是圓角的?

如果應用的主窗口未采用自動圓角設置,這是因為你以阻止采用圓角的方式自定義了框架。從桌面窗口管理器(DWM)的角度來看,應用主要分為下面三類:

  1. 默認采用圓角設置的應用。

這包括需要系統提供的完整框架和標題控件(最小值/最大值/關閉按鈕)的應用,例如記事本。還包括向系統提供足夠信息以便系統可以正確地對它們進行圓角操作的應用,例如設置 WS_THICKFRAMEWS_CAPTION窗口樣式或提供1個像素的非工作區邊框(系統可以使用該邊框設置圓角)。

  1. 根據策略不采用圓角但實際可采用圓角的應用。

此類別中的應用通常希望自定義大多數窗口框架,但仍然需要系統繪制的邊框和陰影,例如Microsoft Office。如果應用根據策略未采用圓角,則可能由下述原因之一導致:

  • 缺少框架樣式
  • 非工作區為空
  • 其他自定義,例如用於自定義陰影的其他非子窗口

更改其中一項會破壞自動圓角設置。盡管我們確實嘗試了使用系統啟發式方法為盡可能多的應用設置圓角,但存在一些無法預測的自定義組合,因此我們針對這些情況提供了手動選擇加入API。如果你在應用中解決這些問題或調用選擇加入API(如以下部分所述),則系統可執行圓角設置。但請注意,該API是對系統的提示,不保證能執行圓角設置,具體取決於自定義項。

  1. 即使調用選擇加入API也無法采用圓角的應用。

這些應用沒有框架或邊框,通常具有高度自定義的UI。如果應用執行以下操作之一,則無法采用圓角設置:

  • 每像素alpha分層
  • 窗口區域

例如,應用可能使用每像素alpha分層在其主窗口周圍繪制透明像素,以實現自定義陰影效果,這會使窗口不再是矩形,因此系統無法對其采用圓角。

如何選擇使用圓角

a. API定義

https://www.microsoft.com/software-download/windowsinsiderpreviewSDK

如果應用根據策略未采用圓角設置,你可選擇性地調用我們新的API,來使你的應用可選擇使用圓角。此API表示為要傳遞到DwmSetWindowAttribute API的枚舉值,如新的DWM_WINDOW_CORNER_PREFERENCE枚舉中所示。DWM_WINDOW_CORNER_PREFERENCEdwmapi.h標頭中定義,且在最新的Insider Preview SDK中提供。

枚舉值 說明
DWMWCP_DEFAULT 讓系統決定是否對窗口采用圓角設置。
DWMWCP_DONOTROUND 絕不對窗口采用圓角設置。
DWMWCP_ROUND 適當時采用圓角設置。
DWMWCP_ROUNDSMALL 適當時可采用半徑較小的圓角設置。

指向此枚舉中相應值的指針將傳遞給DwmSetWindowAttribute的第三個參數。對於指定要設置的屬性的第二個參數,傳遞在DWMWINDOWATTRIBUTE枚舉中定義的新DWMWA_WINDOW_CORNER_PREFERENCE值。

b. 對於C#應用

DwmSetWindowAttribute是本機C++ API。如果應用基於.NET並使用C#,則需要使用P/Invoke導入dwmapi.dllDwmSetWindowAttribute函數簽名。系統會將所有標准的WinFormsWPF應用像任何其他應用一樣自動設為圓角,但如果你自定義了窗口框架或使用第三方框架,並且這樣做導致丟失了默認的圓角操作,則可能需要選擇加入采用圓角

c. 示例 1 - 在C#中對應用的主窗口采用圓角 - WPF

若要在C# WPF桌面應用中調用DwmSetWindowAttribute,需要使用P/Invoke導入dwmapi.dllDwmSetWindowAttribute函數簽名。首先,需要重新定義本機dwmapi.h標頭中所需的枚舉值,然后使用C#類型來聲明等效於原始本機函數的函數。由於原始本機函數采用第三個參數的指針,因此請確保使用ref關鍵字,以便可以在調用該函數時傳遞變量的地址。可以在MainWindow.xaml.csMainWindow類中執行此操作。

using System.Runtime.InteropServices;
using System.Windows.Interop;

public partial class MainWindow : Window
{
    // The enum flag for DwmSetWindowAttribute's second parameter, which tells the function what attribute to set.
    public enum DWMWINDOWATTRIBUTE
    {
        DWMWA_WINDOW_CORNER_PREFERENCE = 33
    }

    // The DWM_WINDOW_CORNER_PREFERENCE enum for DwmSetWindowAttribute's third parameter, which tells the function
    // what value of the enum to set.
    public enum DWM_WINDOW_CORNER_PREFERENCE
    {
        DWMWCP_DEFAULT      = 0,
        DWMWCP_DONOTROUND   = 1,
        DWMWCP_ROUND        = 2,
        DWMWCP_ROUNDSMALL   = 3
    }

    // Import dwmapi.dll and define DwmSetWindowAttribute in C# corresponding to the native function.
    [DllImport("dwmapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern long DwmSetWindowAttribute(IntPtr hwnd,
                                                     DWMWINDOWATTRIBUTE attribute,
                                                     ref DWM_WINDOW_CORNER_PREFERENCE pvAttribute,
                                                     uint cbAttribute);

    // ...
    // Various other definitions
    // ...
}

接下來,在MainWindow構造函數中,在調用InitalizeComponent后創建WindowInteropHelper類的新實例,以獲取指向基礎HWND窗口句柄)的指針。請確保在顯示窗口之前使用EnsureHandle方法強制系統為窗口創建HWND,因為通常系統僅在退出構造函數后創建HWND

public MainWindow()
{
    InitializeComponent();

    IntPtr hWnd = new WindowInteropHelper(GetWindow(this)).EnsureHandle();
    var attribute = DWMWINDOWATTRIBUTE.DWMWA_WINDOW_CORNER_PREFERENCE;
    var preference = DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_ROUND;
    DwmSetWindowAttribute(hWnd, attribute, ref preference, sizeof(uint));

    // ...
    // Perform any other work necessary
    // ...
}

d. 示例 2 - 在C#中對應用的主窗口采用圓角 - WinForms

WPF一樣,對於WinForms應用,首先需要使用P/Invoke導入dwmapi.dllDwmSetWindowAttribute函數簽名。可以在主Form類中執行此操作。

using System;
using System.Runtime.InteropServices;

public partial class Form1 : Form
{
    // The enum flag for DwmSetWindowAttribute's second parameter, which tells the function what attribute to set.
    public enum DWMWINDOWATTRIBUTE
    {
        DWMWA_WINDOW_CORNER_PREFERENCE = 33
    }            

    // The DWM_WINDOW_CORNER_PREFERENCE enum for DwmSetWindowAttribute's third parameter, which tells the function
    // what value of the enum to set.
    public enum DWM_WINDOW_CORNER_PREFERENCE
    {
        DWMWCP_DEFAULT      = 0,
        DWMWCP_DONOTROUND   = 1,
        DWMWCP_ROUND        = 2,
        DWMWCP_ROUNDSMALL   = 3
    }               

    // Import dwmapi.dll and define DwmSetWindowAttribute in C# corresponding to the native function.
    [DllImport("dwmapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern long DwmSetWindowAttribute(IntPtr hwnd, 
                                                     DWMWINDOWATTRIBUTE attribute, 
                                                     ref DWM_WINDOW_CORNER_PREFERENCE pvAttribute, 
                                                     uint cbAttribute);
    
    // ...
    // Various other definitions
    // ...
}

調用DwmSetWindowAttribute也與使用WPF應用時相同,但不必使用幫助程序類獲取HWND,因為它只是Form的屬性。在調用InitializeComponent后,從Form構造函數中調用它。

public Form1()
{
    InitializeComponent();

    var attribute = DWMWINDOWATTRIBUTE.DWMWA_WINDOW_CORNER_PREFERENCE;
    var preference = DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_ROUND;
    DwmSetWindowAttribute(this.Handle, attribute, ref preference, sizeof(uint));
    
    // ...
    // Perform any other work necessary
    // ...
}

e. 示例 3 - 在C++中對應用的主窗口采用圓角

對於本機C++應用,可以在創建窗口后,在消息處理函數中調用DwmSetWindowAttribute,以要求系統執行圓角設置。

LRESULT ExampleWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{
    switch (message)
    {
    // ...
    // Handle various window messages...
    // ...

    case WM_CREATE:
        // ...
        // Perform app resource initialization after window creation
        // ...
        
        if(hWnd)
        {
            DWM_WINDOW_CORNER_PREFERENCE preference = DWMWCP_ROUND;
            DwmSetWindowAttribute(hWnd, DWMWA_WINDOW_CORNER_PREFERENCE, &preference, sizeof(preference));
        }
        break;

    // ...
    // Handle various other window messages...
    // ...
    }

    return 0;
}

f. 示例 4 - 對菜單采用半徑較小的圓角設置 - C++

默認情況下,菜單是彈出窗口,不采用圓角設置。如果你的應用創建一個自定義菜單,而你希望它沿用其他標准菜單的圓角策略,那么你可調用API來讓系統知道該窗口應該采用圓角設置,即使它貌似與默認的圓角策略不匹配也是如此。

HWND CreateCustomMenu()
{
    // Call an app-specific helper to make the window, using traditional APIs.
    HWND hWnd = CreateMenuWindowHelper();

    if (hWnd)
    {
        // Make sure we round the window, using the small radius 
        // because menus are auxiliary UI.
        DWM_WINDOW_CORNER_PREFERENCE preference = DWMWCP_ROUNDSMALL;
        DwmSetWindowAttribute(hWnd, DWMWA_WINDOW_CORNER_PREFERENCE, &preference, sizeof(preference));
    }

    return hWnd;
}

g. 示例 5 - 自定義窗口內容來采用圓角設置 - C++

當窗口采用圓角設置時,窗口工作區的一小部分會被剪裁掉。某些應用可能需要調整其內容來進行適應。

例如,垂直滾動條的縮略圖可能剛好放在窗口的右下角,因此在采用圓角時可能會被剪裁掉。如果這在視覺上來說是不需要的,你可在窗口采用圓角設置時,調整滾動條的位置。不過,由於窗口並非總是采用圓角設置(例如,在最大化時永遠不會是圓角),因此你應調用DwmGetWindowAttribute來確定是否需要調整UI以及調整多少。

LRESULT ExampleWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{
    switch (message)
    {
    // ...
    // Handle various window messages...
    // ...

    case WM_SIZE:
        // Whenever an interesting size change takes place, there may be a corresponding rounding change.
        int radius = 0;
        if (SUCCEEDED(DwmGetWindowAttribute(hWnd, DWMWA_WINDOW_CORNER_RADIUS, &radius, sizeof(radius))))
        {
            AdjustScrollbarForCornerRadius(radius);
        }
        break;

    // ...
    // Handle various other window messages...
    // ...
    }

    return 0;
}

Windows 11桌面應用中應用貼靠布局菜單

貼靠布局菜單是Windows 11中的一項關鍵功能,有助於用戶了解窗口貼靠的強大功能。借助該菜單,用戶只需將鼠標懸停在“最大化”按鈕上或按Win+Z,即可快速對窗口進行布局以在更大的屏幕上進行多任務處理,並通過引導式貼靠助手創建整個布局

image

在Windows 11上,如果應用程序提供了“最大化”標題按鈕,系統會自動為所有收件箱應用(包括所有UWP應用和大多數其他應用)提供貼靠布局菜單。但是,某些桌面應用可能沒有貼靠布局菜單

為什么我的應用沒有貼靠布局菜單?

如果應用程序的主窗口提供了“最大化”標題按鈕,但沒有提供貼靠布局菜單,這可能是由於你已經以阻止標題按鈕或標題欄的方式自定義了標題按鈕或標題欄

如何選擇使用貼靠布局菜單

如果你有自定義標題欄,可以:

  • 使用Windows應用SDK窗口化API ,並讓平台繪制和實現標題按鈕。

https://docs.microsoft.com/zh-cn/windows/apps/windows-app-sdk/windowing/windowing-overview

  • 對於Win32應用,請確保你正確響應了WM_NCHITTEST (“最大化/還原”按鈕的返回值為HTMAXBUTTON)。

https://docs.microsoft.com/zh-cn/windows/win32/inputdev/wm-nchittest

  • 如果應用使用Electron,你可更新到Electron的v13穩定版本,為應用啟用貼靠浮出控件

https://www.electronjs.org

有貼靠布局菜單,但無法正確貼靠?

如果應用程序可調用貼靠布局菜單,但無法正確貼靠到貼靠區域,這可能是因為應用程序的最小大小對於貼靠區域來說太大,無法正確適應。

應用程序應支持最大500epx的最小寬度,才可使貼靠正常工作。但是,建議支持更小的最小寬度(330epx或更小),因為它將與更多的設備和貼靠布局兼容。

桌面應用中調用Windows 運行時 API

https://docs.microsoft.com/zh-cn/windows/apps/desktop/modernize/desktop-to-uwp-enhance

你可以使用Windows運行時(WinRT)API向桌面應用添加令Windows 10/11用戶感到滿意的新式體驗。

首先,使用必需的引用設置項目。然后,從代碼中調用Windows運行時API以為桌面應用帶來Windows 10/11體驗。你可以為Windows 10/11用戶單獨生成,也可以不考慮用戶所運行的Windows版本而向所有用戶分發相同的二進制文件。

修改.NET項目以使用Windows 運行時API

有幾個用於.NET項目的選項:

  • 從.NET5開始,可以在項目文件中添加目標框架名字對象(TFM),用於訪問WinRT API。此選項支持面向Windows10 1809版或更高版本的項目。
  • 對於早期版本的.NET,可以安裝Microsoft.Windows.SDK.ContractsNuGet包,以便將所有必要的引用添加到項目中。此選項支持面向Windows10 1803版或更高版本的項目。
  • 如果你的項目同時面向.NET5(或更高版本)和早期版本的.NET等多個目標,可將項目文件配置為同時使用這兩個選項。

修改C++ 桌面 (Win32) 項目以使用Windows 運行時 API

通過C++/WinRT來使用Windows運行時APIC++/WinRT是Windows運行時(WinRT)API的完全標准新式C++ 17語言投影,以基於標頭文件的庫的形式實現,旨在為你提供對新式Windows API的一流訪問。

若要為C++/WinRT配置項目,請執行以下操作:

  • 對於新項目,你可以安裝`C++/WinRTVisualStudio擴展(VSIX)``,並使用該擴展中包含的其中一個C++/WinRT項目模板。

https://marketplace.visualstudio.com/items?itemName=CppWinRTTeam.cppwinrt101804264

  • 對於現有項目,可以在項目中安裝Microsoft.Windows.CppWinRTNuGet包。

https://www.nuget.org/packages/Microsoft.Windows.CppWinRT/

添加Windows 10/11體驗

a. 首先,確定要添加的體驗

有很多選擇。例如,可通過使用盈利API來簡化你的采購訂單流,或在要分享有趣的內容時(例如其他用戶發布了新圖片)吸引用戶對應用程序的注意。

image

即使用戶忽略或關閉你的消息,他們仍可在操作中心中再次看到該消息,然后單擊該消息打開你的應用。這可以加強用戶與應用程序的互動,並使你的應用程序看似已與操作系統深度集成。稍后,我們將在本文中向你演示用於實現該體驗的代碼。

b. 決定是增強還是擴展

你經常會聽到我們使用術語“增強”和“擴展”,因此我們需要花些時間來說明一下這兩個術語的確切含義。

我們使用術語“增強”來描述可以直接從桌面應用對其進行調用的Windows運行時API(無論你是否選擇將應用程序打包到MSIX包中)。當你選擇Windows 10/11體驗后,請確定創建它所需的API,然后查看該API是否出現在此列表中。這是你可以直接從桌面應用中調用的API的列表。如果你的API未出現在此列表中,那是因為與該API關聯的功能只在UWP進程內運行。通常情況下,其中包括呈現UWP XAML(例如UWP地圖控件或Windows Hello安全提示)的API。

盡管通常不能直接從桌面調用呈現UWPXAML的API,但你可以使用其他方法。如果要托管UWPXAML控件或其他自定義視覺體驗,則可以使用XAML島(從Windows10版本1903開始)和可視化層(從Windows10版本1803開始)。可以在打包或未打包的桌面應用中使用這些功能。

如果已選擇將桌面應用打包到MSIX包中,則另一種選擇是通過向解決方案中添加UWP項目來“擴展”應用程序。桌面項目仍是應用程序的入口點,但UWP項目使你可以訪問此列表中未顯示的所有API。桌面應用可以使用應用服務來與UWP進程通信,我們可針對如何進行相關設置提供很多指導。如果你要添加的體驗需要UWP項目,請參閱使用UWP組件進行擴展。

c. 引用API協定

如果你可以直接從桌面應用中調用API,請打開瀏覽器並搜索該API的引用主題。在API的摘要下,你會找到一個描述用於該API的API協定的表。下面是該表的一個示例:

image

如果你有基於.NET的桌面應用,請添加對該API協定的引用,然后將該文件的CopyLocal屬性設置為False。如果你有一個基於C++的項目,請將包含此協定的文件夾的路徑添加到“附加包含目錄”中。

d. 調用API以添加你的體驗

https://docs.microsoft.com/zh-cn/windows/uwp/design/shell/tiles-and-notifications/adaptive-interactive-toasts

以下代碼用於顯示我們之前看到的通知窗口。此列表中顯示了這些API,因此你可以將此代碼添加到桌面應用中並立即執行此代碼。

支持Windows XP、Windows Vista和Windows 7/8安裝庫

你可以為適用於Windows 10/11的應用程序增加新式體驗,而無需創建新分支和維護不同代碼庫。

如果要為Windows 10/11用戶生成單獨的二進制文件,請使用條件編譯。如果你希望生成要部署到所有Windows用戶的一組二進制文件,請使用運行時檢查。

讓我們快速查看一下每個選項。

a. 條件編譯

你可以保留一個代碼庫,並編譯一組僅面向Windows 10/11用戶的二進制文件。

首先,向項目中添加新的生成配置。

image

對於該生成配置,請創建一個常量以標識調用Windows運行時API的代碼。

對於基於.NET的項目,該常量稱為“條件編譯常量”。

image

對於基於C++的項目,該常量稱為“預處理器定義”。

image

在任意UWP代碼塊前添加該常量。

[System.Diagnostics.Conditional("_UWP")]
private void ShowToast()
{
 ...
}
#if _UWP
void UWP::ShowToast()
{
 ...
}
#endif

僅當在活動生成配置中定義了該常量時,編譯器才會生成該代碼。

b. 運行時檢查

可以不考慮用戶所運行的Windows版本而為所有Windows用戶編譯一組二進制文件。僅當用戶在Windows 10/11上以打包的應用程序形式運行應用程序時,應用程序才會調用Windows運行時API

https://docs.microsoft.com/zh-cn/archive/blogs/appconsult/desktop-bridge-identify-the-applications-context

向代碼添加運行時檢查最簡單的方法是安裝以下Nuget包:桌面橋幫助程序,然后使用IsRunningAsUWP()方法關閉調用Windows運行時API的所有代碼。

相關示例


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM