認識第一個 WinUI C++ 程式

上一堂課,我們完成 WinUI C++ 的安裝並建立第一支程式,且程式能夠正常執行。本堂課,我們就來解析這第一個 WinUI C++ 專案。

專案的方案目錄

接下來逐一解說各個檔案與資料夾的用途

解析專案目錄

方案名稱

最上方的 Solution ‘App3’ 即為方案名稱,名稱是 App3。建立專案時可自訂方案名,預設會和專案名稱相同

建立專案的介面

上圖第一個輸入欄是專案名稱,最後一個欄位則是方案名稱,預設兩者相同,你也可以設定成不同名稱。

一個方案內可包含多個專案,這裡目前只有一個桌面封裝專案 App3 (Desktop)

1. References(參考)

存放專案相依的 SDK、Windows App SDK、WinRT 執行階段、NuGet 安裝的元件參考:

  • Windows SDK、WinUI 3 控制項函式庫、C++/WinRT 標頭檔函式庫、Microsoft.UI.Xaml 等相依項目都在此管理;
  • 無需手動修改,透過 VS 管理 NuGet 套件時會自動更新。
參考項目,截圖僅顯示部分內容

2. External Dependencies(外部相依)

此資料夾會自動掃描系統標頭檔、SDK 標頭、第三方函式庫標頭:

  • Windows.h、winrt/ 系列標頭、Microsoft.UI.Xaml 底層標頭;
  • 唯讀,僅供檢視外部引入的程式碼,無法手動編輯。這些檔案大多是安裝 Visual Studio 時附帶的函式庫。
外部相依檔案(部分)

隨意雙擊開啟任一檔案,就能看見檔案位於 Visual Studio 的安裝目錄下;將滑鼠游標移到上方檔名處,會顯示完整路徑

3. Assets 資源資料夾(應用程式圖示 / 啟動畫面)

存放所有給微軟市集、系統彈窗、開機啟動畫面、鎖定畫面使用的影像資源,用於封裝上架至 Microsoft Store:

為什麼會有這些圖檔?因為我們建立專案時選的是封裝型範本。所謂封裝,代表日後可編譯成 MSIX 或微軟市集專用安裝檔。那封裝與未封裝專案差在哪?未封裝專案可直接綠色執行,過去我們開發的許多專案,編譯出 EXE 後雙擊就能執行;封裝專案則是把所有 EXE、DLL 與各類資源打包成單一安裝檔,使用者雙擊該檔案即可安裝程式,這就是封裝。由於我們開發完成後要上架微軟市集,因此選擇 packaged 封裝專案範本。

上圖是建立專案時選取的範本,從說明文字可得知,此範本專用來編譯 MSIX 檔、上架微軟市集。市集上架需要各式圖示與宣傳圖片,因此專案內預先載入這些資源。是否能不使用封裝模式?可以,我們也能編譯出獨立 EXE 直接執行,後續課程會詳細說明。

各張圖片用途說明
檔案名稱用途
LockScreenLogo.scale-200.png鎖定畫面應用程式圖示(200% 高 DPI 縮放)
SplashScreen.scale-200.png程式啟動載入畫面
Square44x44Logo…多張圖檔開始功能表小圖示、工作列圖示、Alt+Tab 視窗縮圖
Square150x150Logo.scale-200.png開始功能表中型磚塊圖示
StoreLogo.png微軟市集展示的程式大圖
Wide310x150Logo.scale-200.png開始功能表寬版磚塊

app.manifest

傳統 Windows 應用程式資訊清單(相容 Win32)

  • 設定程式權限、相容 Windows 版本、DPI 感知、管理員執行權限、視窗縮放行為;
  • 和 UWP 使用的 Package.appxmanifest 不同,桌面封裝專案會同時存在兩份資訊清單。

4. App.xaml / App.xaml.h / App.xaml.cpp

應用程式全域進入點根類別(對應 winrt::App3::App

  1. App.xaml XAML 全域資源字典:存放全域樣式、控制項範本、色彩、字型、主題資源,整個專案所有頁面共用。
  2. App.xaml.h C++/WinRT 自動產生的標頭檔,定義 App 類別宣告,包含 OnLaunched、OnActivated 等生命週期函式。
  3. App.xaml.cpp 實作應用程式生命週期邏輯:
    • OnLaunched:程式啟動時執行,建立並顯示 MainWindow
    • 處理視窗啟用、暫停、主題切換、例外捕捉;
    • 全域初始化邏輯(字型、資料庫、單例服務)皆寫在此處。

打開 cpp 檔案,可以看見以下程式碼

    void App::OnLaunched([[maybe_unused]] LaunchActivatedEventArgs const& e)
    {
        window = make<MainWindow>();
        window.Activate();
    }Code language: C++ (cpp)
程式執行到這裡後,流程就交給 MainWindow。App 只是程式進入點,並不會建立可見視窗;MainWindow 才是實際產生我們所見視窗、控制項與對話視窗的地方。

5. MainWindow.xaml 完整檔案群(主視窗)

程式預設主視窗,桌面應用程式的根視覺容器,最上層的主要視窗。

  1. MainWindow.xaml 視窗介面版面:按鈕、文字方塊、導覽控制項、頁面載入器 Frame 都定義於此;
  2. MainWindow.idl IDL 介面定義檔(C++/WinRT 核心) 定義視窗對外公開的屬性、方法、事件,供 XAML 繫結、跨元件呼叫、產生型別中繼資料;修改後會自動產生對應 .h/.cpp 橋接程式碼。
  3. MainWindow.xaml.h 由 IDL + XAML 自動產生的類別標頭檔,存放控制項成員、建構子、事件處理函式宣告。
  4. MainWindow.xaml.cpp 視窗商業邏輯:按鈕點擊事件、資料繫結、頁面切換、控制項互動程式碼。

下方 MainWindow.xaml 就是放置控制項與編排版面的地方

<?xml version="1.0" encoding="utf-8"?>
<Window
    x:Class="App3.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App3"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Title="App3">

    <Grid>

    </Grid>
</Window>
Code language: HTML, XML (xml)

6. module.g.cpp

C++/WinRT 全域模組自動產生檔案,禁止手動修改

  • 依據專案內所有 .idl 檔產生 WinRT 型別註冊程式碼;
  • 提供 winrt::App3::implementation 命名空間入口,讓系統辨識自訂 XAML 控制項、視窗類別;
  • 新增或刪除 IDL 檔後,Visual Studio 會自動重新產生此檔。

7. Package.appxmanifest(MSIX 封裝資訊清單,核心重點)

將桌面應用程式封裝成 MSIX/MSIX 安裝包的設定檔,雙擊可開啟視覺化編輯器:

  • 設定應用程式名稱、版本、發行者、圖示、啟動入口;
  • 宣告程式所需系統權限(檔案存取、攝影機、網路、背景工作);
  • 關聯檔案開啟協定、URL 協定、自訂擴充功能;
  • 設定市集上架資訊、桌面捷徑、檔案關聯;和 app.manifest 區分:此檔是微軟市集 / MSIX 封裝專用資訊清單,專屬 UWP 與封裝型桌面程式。

這裡可設定市集相關資訊,例如版本、封裝名稱、發行者等,這些資訊需至微軟市集開發者後台取得

8. packages.config

NuGet 套件設定檔:記錄專案安裝的所有 NuGet 套件版本,例如:

  • Microsoft.Windows.SDK.NET、Windows App SDK、C++/WinRT、WinUI 3 函式庫;
  • 團隊協作或更換開發電腦時,Visual Studio 會依據此檔自動還原所有相依套件。

9. pch.h/pch.cpp(先行編譯標頭,加速 C++ 編譯速度)

pch = Precompiled Header,先行編譯標頭

  1. pch.h:統一匯入全域共用標頭(winrt/Windows.*、Microsoft.UI.Xaml.*、標準函式庫),所有 cpp 檔開頭都會加上 #include "pch.h"
  2. pch.cpp:先行編譯標頭的來源檔;用途:大幅縮短編譯時間,不用每支程式碼重複匯入大量系統標頭。

將所有常用參考統一寫在此檔,其他程式碼只需引入這支檔,就能減少重複程式碼、加快編譯速度。

10. readme.txt

Visual Studio 範本內附說明文件,記載 WinUI 3 C++ 專案基礎編譯、封裝、偵錯操作說明。

容易混淆的兩份資訊清單

  1. app.manifest → 傳統 Win32 處理程序資訊清單(視窗設定、系統相容性、執行權限)
  2. Package.appxmanifest → MSIX 應用程式封裝資訊清單(市集上架、安裝設定、系統功能宣告)

專案完整執行流程

  1. 程式啟動 → 進入 App::OnLaunched(App.xaml.cpp)
  2. 建立 MainWindow 實例並啟用顯示 window = make(); window.Activate();
  3. MainWindow.xaml 繪製介面,對應 cpp 檔處理使用者互動
  4. 封裝發行時讀取 Package.appxmanifest 產生安裝包,Assets 內所有圖示會嵌入安裝檔

以上就是最簡空白專案的完整目錄結構與執行流程。下一堂課我們會在視窗新增按鈕,實作點擊按鈕數字遞增的功能,透過實例理解 WinUI C++ 框架的執行機制。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *