モノトーンの伝説日記

OBS Studio と Blackmagic Design が大好き。

Windows 10 Build 14986 (Insider/Creators) から “Mixed Mode” な DPI Scaling が追加されるらしい

 お久しぶりです。

 技術系の話題はめちゃくちゃ久々なんですが,このブログでよく扱う High DPI 的な話題の最新記事です。High DPI も周りにありふれてて,日常的に 4K ディスプレイに触れる生活をしているのですが,やっぱそれを見ていると,High DPI 対応も進んできたな,って思う次第であります。

 今日は,“Mixed-Mode” と呼ばれることについて軽いお話や API の追加についてお話しようかと。

概要

  1. ネタ記事
  2. API の話
  3. まとめ

1. ネタ記事

 元ネタです。これ全部読んでください。というか読んだらわかります。俺もさっき斜め読みしてきたんですけど,まあくどいですね。

blogs.windows.com

 この記事,公開は 2016 年の 10 月 24 日なんですが,まあようやく私の手元にも振ってきたって感じです。Insider: Slow でメイン PC は使ってるもんで。

 ちなみに,14986 の変更点はこちら。

blogs.windows.com

2. API の話

 元ネタ読んでない人もいるんで,経緯も含めて API の説明を軽く。

 今までの DPI 設定って「1 プロセス」=「1 DPI 設定」しか扱えなかったんですね。だけど,例えば「フォント ダイアログ」とかあるじゃないですか,あれって別 DPI 設定で動いてたわけで。そういう経緯からわかると思うんですけど,サブプロセス DPI と言われるものを追加しましょう,と。

 これのメリットはプラグイン UI とかもそうなんですけど,セカンダリー UI 的なものだけ DPI Awareness にするとかできるわけで。

 で,これの登場。

SetThreadDpiAwarenessContext function

Set the DPI awareness for the current thread to the provided value.

Syntax:
DPI_AWARENESS_CONTEXT WINAPI SetThreadDpiAwarenessContext(
  _In_  DPI_AWARENESS_CONTEXT  dpiContext
);

SetThreadDpiAwarenessContext function (Windows)

 名前から見てわかる通りコンテクストごとに設定できますよ,って話。

 あともう一つ加わった改良として,非クライアント エリア (Non-client area)に対しても DPI 管理ができるようになりますよ,って話。

EnableNonClientDpiScaling function

In high-DPI displays, enables automatic display scaling of the non-client area portions of the specified top-level window. Must be called during the initialization of that window.

Syntax:
BOOL WINAPI EnableNonClientDpiScaling(
  _In_ HWND hwnd
);

EnableNonClientDpiScaling function (Windows)

 これで,400% のディスプレイ と 100% のディスプレイ が混在しても理論上は問題なく使えるようになるわけです(今までだと非クライアントエリア,つまりタイトルバー が小さくなりすぎて文字が小さすぎる問題があった,またはその逆。)

 ほかにもこの記事に書いてあるんですが,まあうちのブログ読むような変態さんは real position と virtual position あたりの話は知ってると思うので割愛。

3. まとめ

 ということで,斜め読みしただけで書いたので記事の正確性は知りません。

 といいつつ,サンプルがあったので今開けて検証してるんですが,あってるっぽいかな。サンプルの名前が DPIAwarenessPerWindow ってなってるんでまあここから見てもわかる通り,ウィンドウレベルで扱えるようになった,ってことですね。

Windows-classic-samples/Samples/DPIAwarenessPerWindow at master · Microsoft/Windows-classic-samples · GitHub

 動かしてみました。メイン PC で 150% スケーリングで表示した例。

f:id:mntone:20161220101315p:plain

 予想ですけど,ウィンドウを新たに作ってウィンドウ in ウィンドウ的なこともやれば 1 つのウィンドウと内側のウィンドウ別の DPI で扱えることかな? こちらは未検証ですが,変態さんやプラグイン UI とかあたりに利用できると考えられ,元記事でもプラグイン UI ってことが出てくることから,たぶんできると思います。断定はしませんが。

 雑な記事ですが,流れはつかめると思うのでこんなもんにしておきます。

 以上です。

// PS 個人的に WPF 熱が再発してきたのですが,UWP も Aniversary Update で割と開発しやすくはなったのかな,って思います。個人的に WPF 周りのオレオレライブラリー 開発でもしようかな,って思ったり。UWP は悪くないんですが,手間をかけても凝ったことはできないのがつらい。もし UWP でもタスクトレイにぶち込んだアプリとかそういう Shell integrated なアプリが作れるならいいんですけど,現状ウィンドウ位置が指定できなかったりとつらい。それが本音かな,って思います。