モノトーンの伝説日記

Apex Legends, Splatoon, Programming, and so on...

<mini> ウィンドウの境界線サイズの計算

 はっきり言ってこんなだるいのが謎。

 だるーすぎてだるい。

 まずレジストリーから。HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics というレジストリーに BorderWidth および PaddedBorderWidth が存在する。昔、通常では PaddedBorderWidthGUI ベースでいじれたんだと思う。

 ちなみに、1 単位が -15 という値になってて、デフォルト値はそれぞれ BorderWidth -15、PaddedBorderWidth -60 になっている。つまり、1 px、4 px となる。

 これはレジストリー意外に Windows API からもアクセスでき、

NONCLIENTMETRICS ncm = { 0 };
ncm.cbSize = sizeof(NONCLIENTMETRICS);
::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0);

とかで取得すればよい。

 しかしこの値、なぜこうなっているのかいまいちよくわからないんだよね。特にややこしい。そしてスケーリングが絡んでくるともっと厄介っぽい。

 とりあえず BorderWidth による太さを BW´、PaddedBorderWidth による太さを PBW´、スケーリング率を s とすると次のようになるっぽい (150%, 200%, 250% スケーリング環境でテスト済み)。

[境界線の太さ]=round(s × BW´) + round(s × PBW´) + 3

となっていた。これは実測からはかった値なので正しいとは限らない。う~ん、よくわからんですね… Windows はスケーリング率がでかくなるごとに要素の表示量を増やそうとしてこういうスケーリングしない値をちょいちょい入れてくるんだけど (スーパーバーのアイコン配置とかもそんな感じ)。

 今日はこれの調査のために時間かけすぎた感がある。今やってるプロジェクトに Ribbon 使いたいので気に食わないところを直してるわけだけど、思ったよりこの Border 問題、長年の悩みだったけどやっととけたみたい (いつもはクライアント領域変更しないので、GetWindowRect でクライアント領域を取得してそれでサイズ変更してる)。

 ということで以上。