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

参考

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