2014/08/01

WPFのクローム部分におけるPer-Monitor DPI対応

Per-Monitor DPI対応のラストピースともいうべき、ウィンドウのクローム部分における対応について。

1. 背景

Per-Monitor DPI対応のためにウィンドウを拡大/縮小するとき、アプリ自身からスケーリングできるのは基本的に内側のクライアント領域の部分だけで、外側のクローム部分(枠部分)はOSのコントロール下にあり、Per-Monitor DPI対応を宣言したアプリのウィンドウをOSはスケーリングしないため、結果的にクローム部分だけスケーリングから取り残されるということが起きます。

これを避けるにはクローム部分もアプリ側でコントロールすればいいわけですが、WPFの場合はWindowChromeクラスを使うことで比較的容易にこれが実現できます。これについてはぐらばくさんが基本的な説明をされています。
あえて付け足すとすれば、CaptionHeightで設定される領域はダブルクリックによる最大化の機能も担っているので、0にするより設定した方が標準ウィンドウの機能を失わずに済みます。なお、CaptionHeightの起点とウィンドウ上端の間にはResizeBorderThickness.Topが挟まるので(0でなければ)、計算するときは注意を。

2. デモ

Per-Monitor DPI対応のためのライブラリに、ビヘイビアによるもの、添付プロパティによるものに加え、WindowChromeを使ったものを"ExtendedWindow"として加えて再構成しました。Per-Monitor DPI対応の機能は共通なので、リサイズ時の問題への対策もされています。
初期設定ではWindows 8の標準ウィンドウとほとんど同じ外観です。

ここでPer-Monitor DPIを変えると、クローム部分もスケーリングされます。

どうせなのでサンプルテーマも用意してみました。

大体の項目はプロパティを通しても設定できますが、キャプションボタンのマウスオーバー時とクリック時の色は直接ResourceDictionaryを作成してThemeUriに設定する以外の方法は用意していません。といっても、実際にアプリを作ろうとすると色々手を加えないといけないと思いますが。

ちなみに、デモアプリの"Rain"をクリックするとアニメーションが表示されます。

クローム部分(のように作ってある部分)もアプリ側からコントロールできることが分かると思います。

3. まとめ

というわけで、Per-Monitor DPIに完全対応を果たしつつ、ウィンドウの全てを自由にデザインできるので、アイデア次第で魅力的なUIを作り上げることができると思います。

0 コメント :