Mauiの先駆者として言いたいことがある。マイクロソフト、お前は俺をすごいプログラマーにしようと必死だな。絶対に俺が十分にすごくないと思って、わざと俺を怒らせようとしているんだろう。
さて、余談はここまでにして、Mauiもようやく正式リリースされた。これを使ってデスクトップアプリを作りたい。できればWindowsとMacに対応させたい(もちろんLinuxも欲しいが、マイクロソフトは許してくれない)。というわけで、作業を始めた。
公式チュートリアルに従って、最新のプレビュー版vs2022(Macも同様)をダウンロードしてインストールし、Maui関連のワークロードを選択、Mauiテンプレートプログラムを作成、そのままコンパイルして実行。一連の操作は流れるように進み、うまくいきそうな感じで順調そのもの。
OK、プログラムは完璧に動作。Macでも完璧。しかも同じコードがWindowsとMacでシームレスに動く。これはとてもniceだ。自信がみなぎってきた。
優秀なプログラマーとして、自分なりのアイデアを持ちたい。例えば、枠なしのデスクトップアプリを作りたい。これはとてもeasyなはずだ。windowstyleをnoneに変更するだけでいい(そう思っていた)。今までずっとそうしてきたから、そうしようとした。しかし、どこを探してもWindowクラスもMauiWinUIWindowもUIWindowも見つからない。
目がかすんでいるに違いない。もっと注意深く調べなければと自分に言い聞かせ、さらに30分かけて徹底的に探した。ついでにMauiのソースコードも少し見てみた(よくわからなかったが)。そう、間違いない。本当にない。まあ、考えが甘すぎた。クロスプラットフォームのプログラムは多くのプラットフォームを考慮しなければならない。これは簡単なことではない。そう自分を慰めた。
よし、この道は通じない。ならばMauiの公式チュートリアルを見てみよう。公式チュートリアルならきっとあるはずだ。かなり網羅的だろう。さらに30分かけてチュートリアルを確認したが、やはりない。うーん、これは非常に難しいことだ。何しろクロスプラットフォームだから、理解できる。では、WinUIの公式チュートリアルを探してみよう。何しろWinUI3を使っているのだから。
すぐに実行に移り、さっさと本題に突入した。努力は報われ、ついにタイトルバーの中に答えを見つけた。答えはあったが、それでも言いたい。マイクロソフト、お前の作ったこのクソみたいなものはmfcと何が違うんだ?ほとんどネイティブAPIの単なるラッパーじゃないか。さすがお前だ --- 我が巨硬(ここで絶叫)。
苦笑いしながら、MauiのWindowsデスクトッププログラムでタイトルバーを変更する葵花宝典(秘伝の書)を書き記した。そこにはびっしりと「ありえない」と書かれていた。
秘伝の書は以下の通り:
- 忍耐力が必要だ;
- 忍耐力が必要だ;
- 忍耐力が必要だ;
- この方法を使う前に、必ずWindowsのライフサイクル関数を登録すること。参考ドキュメント:アプリケーションライフサイクル - .NET MAUI | Microsoft Docs この方法を使わず、
appでOnCreate関数をオーバーライドしてもよい;
ライフサイクル関数を登録

OnCreateメソッドをオーバーライド


Maui Windowsに標準で付いているExtendsContentIntoTitleBarを必ずfalseに設定すること(これは非常に重要。また、Maui WindowクラスにはSetTitleBarがあるが、残念ながらそれは思っているのとは違う。変更しても効果がない。私がヘボすぎて方法を見つけられなかっただけかもしれない)Mauiのウィンドウハンドル(
Windowsプラットフォーム)を使ってAppWindowを取得し、AppWindowのTitleBarの関連プロパティを変更する。参考ドキュメント:タイトルバーのカスタマイズ - Windows apps | Microsoft Docs

上記の手順を完了すると、おめでとう。タイトルバーのないウィンドウを手に入れられる(実際にはタイトルバーはまだあるが、下のコンテンツと一体化している);
さて、上記の手順を完了したら、きっとウィンドウの初期化サイズを自由に制御したり、最大化機能を作ったりしたいと思うだろう。残念ながら、それは本当に難しい。余計なことは言わず、直接コードを載せる。参考ドキュメント:AppWindow Class (Microsoft.UI.Windowing) - Windows App SDK | Microsoft Docs
- ウィンドウの最大化には
Win32Apiを呼び出し、ウィンドウに最大化イベントを送信する必要がある(簡単にラップしたものがある。必要な人は私に連絡してほしい。他にも方法があるかもしれないが、私がバカなだけかも)

- ウィンドウサイズの変更には
AppWindowのMoveAndResizeを呼び出す。注意:この関数内部ではDpiスケーリングを考慮していないので、自分で対応する必要がある

- 全画面表示を有効にするには、
AppWindowPresenterを使用する。参考ドキュメント:AppWindowPresenter Class (Microsoft.UI.Windowing) - Windows App SDK | Microsoft Docs

ようやく、ウィンドウサイズ指定、最大化、枠なしのウィンドウが完成した。確かに簡単だ。涙があふれる(まだ問題もある。タイトルバーのドラッグがボタンのクリックに影響してクリックできなくなる)。
最後に、ただ無力に怒り狂うしかない。巨硬、次は私をバカ扱いしてくれても構わない。そうしてくれ。