はじめに
Windowsフォームアプリをなるべく簡単に高DPI(Hi-DPI)対応させるコツをまとめました。
Windowsフォームの自動スケーリング機能を活用します。
今回やらないこと
下記機能が.NET Framework 4.7でサポートされましたが、実装コストが高いので対応はしません。
- 起動中のDPI変更サポート (Dynamic DPI)
- モニタ別のDPIサポート (Per monitor DPI)
対応方法
アプリケーションマニフェストの設定をする
プロジェクトにアプリケーションマニフェストファイルapp.manifest
を追加し、下記の設定を記入します。
この設定でWindowsが高DPIサポート済と認識してくれるので、表示がぼやけることが無くなります。
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>
フォームに高DPI対応のための一連の設定をする
フォームのデザイン時にはVisual StudioをDPI 100%モードで起動する
高DPI環境下で開発をしている場合、フォームデザイナを開いたとき、下記のような表示が出ます。
必ず毎回「100% のスケールでVisual Studio を再起動します」を選択してください。
でないと、コントロールの配置が高DPI前提となり、DPI 100%環境で表示が崩れてしまいます。
※DPI 100%環境で開発している場合には何もしなくてOKです
AutoScaleModeプロパティをDpiモードにする
フォームのAutoScaleMode
プロパティをDpi
モードに変更しておきます。
AutoScaleMode
プロパティは、Windowsフォームに備わっている自動スケーリング機能の挙動を制御するものです。
デフォルトのFont
モードでは、DPIの比率ではなくフォントの大きさを基準にスケーリングが行われます。
ピクセル単位の座標を扱う処理がある場合、Font
モードは不適です。
デザイナの挙動にも変な影響があり(後述)、使わないほうがよいです。
フォームのFontはYu Gothic UIかMeiryo UIにする
MS UI Gothic、MS Pゴシック等、ビットマップ部分を含むフォントは高DPI環境下でレイアウトが崩れる原因になります。
Yu Gothic UI、Meiryo UIのようなビットマップ部分を含まないフォントを使いましょう。
フォントを変更する際、AutoScaleMode
がFont
のままだと、フォーム全体のサイズが変わってしまうのでご注意ください。
ピクセル単位の操作をする箇所には係数をかける
ここまでの設定で、殆どのコントロールは自動でDPIの制御してくれますが、一部のコントロール(DataGridViewの列幅等)や、描画処理では個別に高DPI対応をする必要があります。
下記のようなコードで96dpiに対する現在のDPI比率を宣言しておき、補正が必要な個所で乗算します。
対応個所を洗い出すには、トライアンドエラーが必要になるかもしれません。
static readonly float DpiScale = ((new System.Windows.Forms.Form()).CreateGraphics().DpiX) / 96;
まとめ
Windowsフォームアプリは高DPI非対応と見なされることが多いですが、
コツをつかめば標準機能任せでも、いい感じに対応できることが分かりました。
拙作SsidWallpaperChangerは本手法で高DPI対応を行っており、ソースを公開しています。
https://github.com/mono1729/SsidWallpaperChanger