WinUI3のウインドウの最大化ボタン無効化や、ウインドウサイズ変更をしたい

もくじ

https://tera1707.com/entry/2022/02/06/144447#WinUI3

やりたいこと

WinUI3で作っているアプリの、ウインドウの左上に出ている最大化ボタンを無効にしたり、ウインドウ起動時の大きさを変えたいが、WPFのように一番上のWindowクラスのプロパティをfalseにする、などで簡単にそれを設定することができなかった。

どうやるのかを調べたい。

前提

  • VisualStudio2022 Community 17.1.4
  • WinUI3
  • Windows App SDK 1.0

やり方

最大化ボタンの無効化のやり方

ウインドウハンドルからAppWindowクラスを取得する。

そのAppWindowクラスに、最大化ボタンを無効にするよう設定したAppWindowPresenterクラスをセットする。

という流れ。

※MSDocsによるとUWPではおなじみなやり方らしいが、ほぼWPFしかやったことない私にはなじみがなかった。

using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;

namespace App3
{
    public sealed partial class MainWindow : Window
    {
        public MainWindow()
        {
            this.InitializeComponent();

            // WinUI3のウインドウのハンドルを取得
            var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
            // そのウインドウのIDを取得
            Microsoft.UI.WindowId windowId = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(hWnd);
            // そこからAppWindowを取得する
            Microsoft.UI.Windowing.AppWindow appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId);
            // 標準タイプのウインドウ(OverlappedPresenter)に対して、好きな設定を行う
            var op = OverlappedPresenter.Create();
            op.IsMaximizable = false;
            op.IsMinimizable = true;
            op.IsResizable = false;
            op.IsAlwaysOnTop = false;
            appWindow.SetPresenter(op);
        }
    }
}

これを実行すると、下図のようになる。

最大化ボタンが無効になっている。
試した限り、無効化はできたが、最大化ボタンだけ非表示にはできなかった。 (最小化だけ非表示も同様)

IsMaximizableIsMinimize の両方をfalseにすると、最大化、最小化ボタンの両方が非表示になった。

AppWindowPresenterクラス

AppWindow.SetPresenter()にセットできるAppWindowPresenterから派生したクラスには、3種類あり、それぞれ下記の特徴がある様子。

この中のOverlappedが、最も標準的ウインドウのようで、持っているプロパティが一番多い。 おそらく、 OverlappedPresenterのプロパティを全画面用に設定したものがFullScreenPresenter、最前面かつ大きさ調整不可にしたものがCompactOverlayPresenterだと思われる。

OverlappedPresenterクラス

いわゆる普通のウインドウ。 こいつに対して各種プロパティ設定を行えば、ある程度好きなウインドウの動きをさせられる。

CompactOverlayPresenter

最大化最小化、ウインドウサイズの調整ができなくなる。 また常時最前面表示になる。
常時、なにかの操作を行うための操作盤的アプリ向けかも??

FullScreenPresenter

ディスプレイ上で最大化表示され、タイトルバーがなくなる。
ゲームなど、常時最前面表示にしたいアプリ向け??
※ただし、MainWindowクラスのコンストラクタでFullScreenPresenterをセットしても、起動時に最大化状態にはなってくれなかった。
ボタン押下時などで行うと、最大化する。
(最初から最大化状態、のアプリは作れない仕様なのかも。)

AppWindowPresenterKind 列挙子

上記は、AppWindowPresenterから派生したクラスをAppWindow.SetPresenter()にセットするやり方だったが、上の3種類のクラスの動きそのままでよい場合は、AppWindowPresenterKindenumの値をAppWindow.SetPresenter()にセットしてやれば早い。

using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;

namespace App3
{
    public sealed partial class MainWindow : Window
    {
        AppWindow appWindow;
        public MainWindow()
        {
            this.InitializeComponent();

            var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
            Microsoft.UI.WindowId windowId = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(hWnd);
            appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId);
            appWindow.SetPresenter(AppWindowPresenterKind.CompactOverlay);//★コレ!
        }
    }
}

起動時のウインドウサイズの変更について

これについては、別途やろうと思う。

MS公式サンプルの下記でやっていることをそのまま確認する感じ。 (プラス、タイトルバーのカスタムについてもやりたい)

https://github.com/microsoft/WindowsAppSDK-Samples/blob/d030cf6d182ff908575a7e985cbd5005a05bad6e/Samples/Windowing/cs-winui/MainWindow.xaml.cs#L30

下記でやってみた

tera1707.com

ウインドウサイズの変更の仕方が趣旨ではなく、それを少し通り越して、dpiをいろいろ設定変更したときのウインドウの移動とかリサイズの話の記事。
そこで移動とかリサイズもしてるので、やり方の参考にはなると思う。

参考

WindowsAppSDKでのウインドウの扱い方

https://docs.microsoft.com/en-us/windows/apps/windows-app-sdk/windowing/windowing-overview

ウインドウ管理のMS公式サンプル

https://github.com/microsoft/WindowsAppSDK-Samples/tree/main/Samples/Windowing/cs-winui

AppWindowクラス

https://docs.microsoft.com/ja-jp/windows/windows-app-sdk/api/winrt/microsoft.ui.windowing.appwindow?view=windows-app-sdk-1.0

AppWindowPresenterクラス

https://docs.microsoft.com/ja-jp/windows/windows-app-sdk/api/winrt/microsoft.ui.windowing.appwindowpresenter?view=windows-app-sdk-1.0

タイトルバーのカスタマイズ

https://docs.microsoft.com/en-us/windows/apps/develop/title-bar?tabs=winui3#full-customization

参考書

WinUI3

WinUI3でアプリを作ろうと思ったときのとっかかりによかった。 msdocsに書いてある情報を、体系的に、順番に読みたいな、というときによいかも。(ただし英語)
この本で分からなかった、かゆいところに手が届かなかった部分を私は記事にしてる感じ。

C#①

表紙に書いてある通り、教科書として最適。 これからC#を勉強したいけど、ネットだけで勉強するのは効率が悪いから体系的に学べる本が欲しいときや、 ちょっとC#を勉強してコード書けるようになったけど、もう少し広く深く知りたいなというときによいと思う。
私は仕事で触れるコードを軸に、基本ネットで断片的にC#を学んだので、その知識の隙間を埋めて枝葉を広げるためにとても分かりやすかった。

C#②

C#の文法的に色々できるのは分かったが、いざ実装するときに、わかったことを使ってどう実装すればいいのか?と悩んだときに指針になりそうな本。
「プロパティ等の名前の付け方、どうすればいい?」「情報をクラス外部に見せるときに、プロパティにすべき?メソッドにすべき?」「異常だと判定したいとき、どんなときにどんな例外をスローすべき?」などなど、勉強になる部分が山ほどあった。
私のように「コードは書くけどこれであってるのか自信がない、レビューで指摘されるのが嫌だ、実装時の(心の)よりどころが欲しい」という人に最適。