Windows Formアプリケーションのタイトルバーの色を変更したいと思ったことはありませんか?そうなんですよね。ずっと変更する方法を探していました。【C#】メニューにダークモードテーマを適用するの続きになります。
前回から、他の人が作ったタイトルバーを変更するコンポーネントを探しているのですが、やっぱり私が欲しいものは見つかりませんでした。
作成している方は圧倒的に海外の方が多いですね。しかも2、3年前に作成されています。私が欲しいのは従来のWindows Form アプリケーションにある、タイトルバー、メニューバー、ツールバーがあるダークモードです。
これだけダークモードが出てから時間が経っているのに無いってことはニーズが無いんでしょうか。それとも、そこまで色にこだわって作るアプリが無いってことでしょうか。業務アプリだと標準の色でも問題なさそうですもんね。
無いなら自作するしかありません。そこでダークモードに対応した従来のフォームを作ってみることにしました。
.NETでタイトルバーの色を変更する課題
今のところ問題になっているのはタイトルバーの色変更です。.NETだけではタイトルバーの色を変更することはできません。Windows10 は OS の設定でタイトルバーの色は変更可能ですが、OSの設定してまで変えるのはどうかなって思います。できればアプリで完結したいです。
また、Windows Apiを使ったり、独自にタイトルバーを描画したりする方法もあるようですが、これはこれで時間がかかりそうです。
対応方法
.NETで対応しようとするとタイトルバーを非表示にして、自前でタイトルバーを用意してやる方法しかありません。タイトルバーを消す方法は2つあります。
方法1の場合、フォームの移動やサイズ変更はできません。独自に実装する必要があります。方法2の場合、フォームのサイズ変更は可能です。ただ、Windows10だと、フォームの上の部分が何故か残ります。原因と回避策は現時点では不明です。 さすがに方法2は課題があるので、方法1を採用するしかありませんね。
方法1(フォームの外観を変更してタイトルバーを消す)
FormBorderStyle プロパティに FormBorderStyle.Noneを設定してタイトルバーを消します。
サンプルコード
this.FormBorderStyle = FormBorderStyle.None;
実行結果

方法2(境界線はそのままにタイトルバーを消す)
ControlBox プロパティに false を設定します。そして、Textプロパティに空文字を設定します。ただ、この方法の場合、少しタイトルバーらしきものが残ります。
サンプルコード
this.ControlBox = false;
this.Text = "";
実行結果

方法1で実装が必要なもの
タイトルバーを消す方法は決まりました。あとは実装しないといけない処理の洗い出しです。他にも出てくるとは思いますが、最低限必要な処理は以下です。
- 自作タイトルバーの実装
- フォームの移動とサイズ変更の実装
自作タイトルバーの実装
そもそも、最近のアプリというかエディタはタイトルバーとメニューが一体化になったものが多いです。これは少しでも作業領域を広げるためだと思うのですが、私はタイトルバーにメニューがあると、マウスでウィンドウを移動するときに、メニューが無い領域にマウスカーソルを持っていく必要があるので嫌いです。
タイトルバーとメニューが一体化されているエディタの代表としては VS 2019、VS Codeですね。他にも色々あると思います。ちなみに、VS 2017はタイトルバーとメニューは分離していました。ってことで、今回作成するのは VS 2017 スタイルで作成します。
話を戻して、タイトルバーをどうするかですね。描画するか、それっぽいコントロールを使うかですが、描画するとまた時間がかかるので、それっぽいコントロールの ToolStrip で代用します。
フォームの移動とサイズ変更の実装
こっちは独自に実装する必要がありますが、まずはフォームの移動で参考にしたのは以下です。


次に、フォームのサイズ変更で参考にしたのは以下です。
ダークモードの適用
色を調べるのが面倒なのですが、これは【C#】メニューにダークモードテーマを適用する方法で紹介している VS 2019 風のカラーテーブルを適用します。ようやく役に立つ時がきました。
実装イメージ
実装後のイメージです。タイトルバーは ToolStrip で作成しているため、ボタンなどのコントロールの追加が簡単にできます。 最小化、最大化、閉じるはそれぞれ「_」、「□」、「×」のラベルにしていますが、アイコンにすることも簡単にできます。
ライトモード
まず最初に通常のライトモードです。参考までにテキストボックスを貼り付けてみました。

ダークモード
次にVS2019風カラーテーブルを適用したメージです。それっぽいフォームになったので個人的に満足しています。

ハイコントラストモード
最後にハイコントラスト風カラーテーブルを適用したイメージです。配色は VS Code を参考にしました。

方法1で実装した場合の課題
今回もいつもみたいに時間がかかるだろうなぁって思ったんですが、意外と簡単に実装できました。一通り動作確認してみた感じだと、標準のタイトルバーとほぼ同等の機能が実装できたと思います。ただ、下記点については追加で実装する必要があります。
- ウィンドウを最大化すると全画面表示になる(フルスクリーン表示)
- タスクバーのアイコンをクリックしても最小化と最大化ができない
- タイトルバーを右クリックしてコンテキストメニューが表示できない。表示できてもサイズ変更がグレーアウトされる

Visual Studio は、タイトルバーのコンテキストメニューやオプション画面はダークモードは適用されないので、そこまでこだわる必要は無いかもしれませんね。
課題の解決方法
方法1の課題も独自に実装して解決しました。ただ、最終的にタイトルバーのカスタマイズはクライアント領域を広げる方法で実装しました。クライアント領域を広げる方法は下記記事で紹介しています。
ダウンロード
最終的にクライアント領域を広げたソースコードは BOOTH で販売しています。動作には .NET 8.0 が必要です。
おわりに
ダークモードフォームのバグやご要望などはフォーラムからお願いいたします。
コメント