WinUIでアプリを作ると、「ウィンドウを画面中央に出したい」「前回のサイズ・位置を覚えておきたい」「最前面に持ってきたい」——そんな当たり前の要求が、素のAPIだと意外と面倒なことに気づきます。私も最初、ウィンドウ位置の保存を自前で書こうとして挫折しました。
この記事では、その解決策として定番の2つ、WinUIEx(高レベルなウィンドウ操作)と CsWin32(Win32 APIの直接呼び出し)を、役割分担とあわせて紹介します。どちらも入門記事のNuGet紹介で触れたライブラリです。独自URIでの起動を扱うプロトコルアクティベーション入門ともあわせてどうぞ。
Table of contents
Open Table of contents
WinUIの素のウィンドウ操作はなぜ手薄か
WinUIの Window や AppWindow でも、サイズ変更やタイトル設定など基本操作はできます。しかし、実アプリで欲しくなる次のような操作は、標準だと自分でHWND(ウィンドウハンドル)を触ったり、Win32を呼んだりする必要があり、途端に面倒になります。
- ウィンドウを画面中央に表示する
- 前回終了時のサイズ・位置を記憶して復元する
- 最小サイズを固定する/最前面に持ってくる
- タスクトレイに常駐する
これらを肩代わりしてくれるのが、次のWinUIExです。
WinUIEx:定番のウィンドウ操作を簡単に
WinUIEx は、WinUIのウィンドウまわりの「痒いところ」を埋める定番ライブラリです。NuGetで WinUIEx を追加して使います。
中央表示・サイズ指定 は、拡張メソッドで一行です。
using WinUIEx;
this.SetWindowSize(1024, 768); // サイズを指定
this.CenterOnScreen(); // 画面中央へ
ウィンドウの位置・サイズを記憶する(これが目玉)。WindowManager に PersistenceId を設定するだけで、次回起動時に前回の位置・サイズを自動で復元してくれます。自前でレジストリや設定ファイルに保存する必要はありません。
using WinUIEx;
var manager = WindowManager.Get(this);
manager.PersistenceId = "MainWindow"; // これだけで位置・サイズを保存&復元
manager.MinWidth = 400; // 最小サイズも指定できる
manager.MinHeight = 300;
このほか、Mica/Acrylicなどのバックドロップ、スプラッシュ画面、タスクトレイ常駐なども用意されています。「ウィンドウで困ったらまずWinUIEx」と覚えておくと近道です。
それでも足りないとき:CsWin32でWin32を直接呼ぶ
WinUIExがカバーしていない、もっと低レベルなWindows APIを呼びたい場面もあります。そんなときは CsWin32(Microsoft.Windows.CsWin32) の出番です。使いたいWin32 APIの名前を書くだけで、面倒な [DllImport] を自動生成してくれます。
導入は2ステップです。
- NuGetで
Microsoft.Windows.CsWin32を追加 - プロジェクトに
NativeMethods.txtを作り、使いたいAPI名を書く
SetForegroundWindow
WinUIでWin32を呼ぶときの鍵は、ウィンドウのHWNDを取得することです。これは WinRT.Interop.WindowNative.GetWindowHandle で取れます。あとは自動生成された PInvoke 経由でAPIを呼ぶだけです。
using WinRT.Interop;
using Windows.Win32;
using Windows.Win32.Foundation;
// このウィンドウのHWNDを取得
var hwnd = (HWND)WindowNative.GetWindowHandle(this);
// 生成されたP/Invokeで Win32 API を呼ぶ(例:最前面に持ってくる)
PInvoke.SetForegroundWindow(hwnd);
NativeMethods.txt に呼びたいAPI名を足していけば、構造体や定数もまとめて生成されます。
使い分けの指針
2つは競合ではなく、役割分担です。
| やりたいこと | 使うもの |
|---|---|
| 中央表示・サイズ記憶・トレイ常駐など定番のウィンドウ操作 | WinUIEx(高レベル・簡単) |
| WinUIExに無い低レベルなWin32 APIを呼ぶ | CsWin32(P/Invoke自動生成) |
まずWinUIExで済むか確認し、それでも届かない部分だけCsWin32で補う——この順番が、コード量も最小で済みます。
まとめ
WinUIの素のウィンドウ操作は手薄ですが、2つのライブラリで一気に楽になります。
- WinUIEx … 中央表示・サイズ記憶(
PersistenceId)・最小サイズ・トレイ常駐などを高レベルAPIで - CsWin32 … WinUIExで足りない低レベルWin32を、
NativeMethods.txtにAPI名を書くだけで呼び出し - 鍵はHWND …
WindowNative.GetWindowHandle(this)で取得してWin32へ渡す
まずはWinUIExで「サイズ記憶」を入れてみると、そのお手軽さが実感できます。ウィンドウまわりで手が止まったら、この2つを思い出してください。
