sh1’s diary

プログラミング、読んだ本、資格試験、ゲームとか私を記録するところ

Win UI3 の入門(1)hello world

この記事は、Windows App SDK の使い方について学んだ基本的な内容をアウトプットしたものです。

入門記事は、何回かにわたって更新する予定です。

Windows App SDK (WinUI 3) とは

Microsoft の開発環境の(WPF ユーザー目線のざっくり)流れのおさらいです。

Windows でしか動作しないアプリケーション開発・実行環境 .NET Framework があり .NET Framework を利用するアプリケーション Forms と WPF がありました。

つぎに、Windows でしか動作しなかったアプリケーション開発・実行環境をクロスプラットフォーム(異なるプラットフォーム上で、同じ仕様のアプリケーションを動かせる)にした .NET(.NET Core と呼ばれた)が生まれて、同じくクロスプラットフォームで動作するアプリケーション UWP ができました。(2015年くらいの話だったと思います)

クロスプラットフォームに対応したことで、アプリケーション開発環境に平和が訪れたかと思いきや、UWP は旧来の Win32 API を利用することができず、(Windows デスクトップ用アプリケーションとしては)素直な上位互換として受け取れなかった。

Uno Platform(クロスプラットフォーム向け)が生まれたりしましたが、UWP を広げる試みだったと思います。ほかにも、MAUI(Blazor WebAssembly 系)が生まれたりしていますが、どちらもクロスプラットフォームの趣きがあり、素直な従来のデスクトップアプリケーション開発をする WPF の後継といった感じではなかった。

そのため Windows App SDK (WinUI 3) が登場する機会が生まれたと思います。(完全に WPF ぽいかというとそうでもなく、UWP 成分も含みます)

WPF からはモダン API が使いづらく(できないわけではない)、UWP からは Win32 API を(基本的に)使えないのが今の環境です。なので、Windows App SDK (WinUI 3) は、もともとの開発名「Project Reunion」と呼ばれたように開発環境を「reunion = 再会、再結合」したい。

reunion が指すところは「Win32 API を利用できるし、モダンなアプリケーションを作りやすい」UI ライブラリがゴール、というコンセプトを示しているようです。

Windows 11 および Windows 10 (1809) 以降が対象のアプリケーション開発環境です。

Win UI の補足

WinUI は Windows App SDK に含まれる WinUI 3 が2023年現在だと最新なので、「4」はまだなくて「3」が一番新しいです。それでは「1」と「2」は何? という話ですが、明確な答えになる(一次情報の)記事が見つけられませんでした。おそらく次のとおり。

  1. WinUI 1...初出は 2011 年ごろなので、Windows 8 ごろの「Windows 8 Metro」などが該当するのではないかと思いますが詳細不明。
  2. WinUI 2...UWP で利用する UI ライブラリ。(XAML Islands の登場で、UWP の UI は WPF などのレガシー GUI でも拡張すれば利用可能になっています)(参考
  3. WinUI 3...Windows App SDK で提供される UI ライブラリ。

Windows App SDK の機能」は、正確には WinUI3 のほかにも提供される機能があるため、ソフトウェア開発キットです。Windows App SDK の一部に(大きいけど)WinUI 3 がある、といった関係です。

それから、WinUI は上述のように Windows App SDK (Project Project Reunion) の登場以前から存在する UI ライブラリのひとつだったので上述のように WinUI 2 なんかがある。でも、Windows App SDK の一部として提供されるようになったので、流れとしては(WinUI 3 になって)組み込まれたということになります。(WinRT XAML を別パッケージとして分離もした)

Hello World

とにもかくにも、プログラムを作ってみることにします。古典に従い「Hello World」を目指しましょう。

環境構築とプロジェクトの作成

Hello World をするためには、Visual Studio Installer から「.NET デスクトップ開発」のインストール詳細にある「Windows アプリ SDK C# テンプレート」を有効にしてください。

「新しいプロジェクトの追加」で、プログラムのソリューション「空のアプリ、パッケージ化(デスクトップの WinUI 3)」を選択して、プロジェクトを作成します。

または、「空白のアプリ、Windows アプリケーション パッケージでパッケージ化 (デスクトップの WinUI 3)」を選択します。(パッケージ化するためのプロジェクトを分けてある構成)ただし、後述しますが初回ビルド時にエラーが発生し、SDK の追加インストールが必要になる恐れがあります。

近年は、MAUI や UNO などのクロスプラットフォーム向けフレームワークもあって、それぞれの特徴をつかむのは難しいですね。

プロジェクトの初期構成ファイル

プロジェクトを作成すると、プロジェクトは、つぎのような構成ファイルになっていますので、役割を整理します。

空のアプリ、パッケージ化(デスクトップの WinUI 3)の場合:

空白のアプリ、Windows アプリケーション パッケージでパッケージ化 (デスクトップの WinUI 3) の場合:

  1. app.manifest アプリケーションのマニフェストファイル。管理者権限を要求する設定であったり、DPI に影響する設定などがあります。
  2. App.xaml/App.xaml.cs アプリケーションのエントリーポイント(一番最初に実行されるところ)です。
  3. MainWindow.xaml/MainWindow.xaml.cs アプリケーションの起動時に表示されるウィンドウです。App.xaml.cs に記述された OnLaunched メソッドから Activate(表示)されています。
  4. Package.appxmanifest アプリケーションのマニフェストファイル。パッケージ化するため、アプリケーションのパッケージ情報、表示名や説明などの情報があります。
  5. Assets フォルダ インストール後に利用するアイコンなどのデフォルト画像が用意されています。
  6. Properties フォルダ コンパイルの設定を決める pubxml ファイルと、プロフラムの起動プロファイルを決める launchSettings.json ファイルが用意されています。

WPF では、Assets フォルダや Package.aapxmanifest ファイル はデフォルトで用意されていませんでした。また、Properties フォルダの pubxmllaunchSettings.json ファイルもありませんでした。(このあたりは UWP と似た構成です)

デバッグの実行テスト

ソリューション(プログラム)を作成できたら、はじめに、作成されたソリューションが正常に動作するかどうかをテストします。

「F5」キーを押下して、デバッグを実行します。

このタイミングで、OS を開発者向けの設定にしていない場合は、つぎのようなウィンドウがポップアップします。警告の内容を確認のうえ、問題がなければ開発者モードをオンにしましょう。(逆にいえば、開発者モードをセキュリティ等の都合でオンにできない理由がある場合は、開発環境が整っていません。先に OS 環境から整理したほうがいいと思います)

再度、「F5」キーを押下して、プログラムのウィンドウが表示されることを確認します。

「空白のアプリ、Windows アプリケーション パッケージでパッケージ化 (デスクトップの WinUI 3)」のプロジェクトを選択していた場合は、以下のエラーが発生することがあります。

このときは Windows SDK をインストールしてください。Visual Studio Installer から追加することもできますが、つぎのリンクから専用インストーラーを利用して追加することも可能です。

ウィンドウ画面の作成

WPF や UWP は、MainWindow.xaml (MainPage.xaml) を開くと、Visual Studio 上には、デザイナ+XAML の画面が表示されたと思います。しかし、Windows App SDK はデザイナーが無いです。(または、今後追加するのかも)

Visual Studio 2022 以前だと、デザイナが無いとさすがに機能不足を感じてしまうのですが、現在の Visual Studio 2022 には「XAML Live Preview」という機能があります。プログラム実行中に XAML を直接書き換えながら、デザインを調整します。

ちなみに初期状態の xaml は以下のような内容でした。

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

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
        <Button x:Name="myButton" Click="myButton_Click">Click Me</Button>
        <!-- Click Me の部分を Hello world に書き換え -->
    </StackPanel>
</Window>

ぱっと見て気づくのは、最初に xml 宣言のタグが追加されています。WPF と UWP から変更されている箇所ですね。window には5つの xml 名前空間 (xmlns = XML namespaces) が定義されています。この内容は WPF や UWP とまったく同じ url が指定されています。

x:Class 属性は、XAML で記述した画面のデザインと、ロジッククラス MainWindow.xaml.cs を結びつけるためのものです。(XAML を触ったことがあれば、馴染みの仕組みかもしれません)

XAML Live Preview」を利用して、中央のボタンの Content プロパティの内容を「Hello world」に書き換えると、つぎのようになります。(基本的な使い方は上述のリンク、または、YouTube を参照してください)

Button や StackPanel などのタグの間に挟まれる部分をコンテンツ構文 (content syntax) といいます。<Button>***</Button> の例だと *** の部分が該当していて、Button の場合は Content プロパティが指定されています。

すべてのコントールのコンテンツ構文が Content プロパティというわけではなくて、(各コントロールのクラスに対して)ContentPropertyAttribute 属性が設定されたプロパティにコンテンツ構文は割り当てられています。なので、StackPanel や Grid のコンテンツ構文は、コレクション型のプロパティに設定されているため、複数のタグを追加することができます。

Button は Click の値に myButton_Click を設定しています。これは MainWindow.xaml.cs ファイルのイベントと紐づいています。(デザインを担う .xaml とコーディングを担う .cs に分けることを code behind といって、今回の例では「code behind で対応するメソッド myButton_Click.xaml に定義してある」みたいな表現で説明されることもあります)

参考