トップ回答者
dpiAware=Trueを設定したときに表示にゴミが出る

質問
-
Windows Formで、Windows7~10向けのアプリを作っています。
高DPI対応しようと思い、以下のようなmanifestファイルをプロジェクトに追加して、dpiAware=Trueの設定をしました。
<?xml version="1.0" encoding="utf-8"?> <asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <asmv3:application> <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings"> <dpiAware>true</dpiAware> </asmv3:windowsSettings> </asmv3:application> </asmv1:assembly>
Windows10で、ディスプレイの設定でサイズを150%以上に設定すると問題ないのですが、
125%と100%の設定では、フォームのサイズを変えた時に、下図のようにゴミ(複数の縦横の線)が出てしまい、困っています。なにか設定の仕方に問題等あるのでしょうか?
高DPI対応の正しい方法等ございましたらご指導ください。
YAMANEKO @ http://yamamaya.com/
- 編集済み YAMAMAYA 2016年10月2日 10:48 例の画像を差し替えました
回答
-
私の環境(Windows 10 x64)でも下記の手順で再現しました。
- Windowsのディスプレイ設定で「テキスト、アプリ、その他の項目のサイズ」 = 200 % でサインイン
- サインインした状態でWindowsのディスプレイ設定で「テキスト、アプリ、その他の項目のサイズ」 を 100 % に変更する
- マニフェストで「dpiAware = true」のWindows フォームアプリを起動して、フォームのサイズを変更する
→複数の縦横の黒い線が表示される
100%の状態で一度サインアウトしてサインインしなおすと、再現しなくなります。
Windows フォームの(dpiAware = true)のアプリは標準で拡大縮小の動的な変更に完全対応していないのかなと思いました。回避方法として、フォームのリサイズイベントに対して Invalidate() を呼び出すのはどうでしょうか?
private void Form1_Resize(object sender, EventArgs e) { Invalidate(); }
- 編集済み kenjinoteMVP 2016年10月3日 9:20
- 回答としてマーク YAMAMAYA 2016年10月3日 14:36
-
Writing DPI-Aware Desktop and Win32 Applications - High DPI Features in Windowsで少し説明されていますが、Windows 8.1からDPI virtualization of system-DPI aware applicationsおよびPer monitor-DPI awareというものが提供されています。
本来System-DPIの変更にはWindows 7以降ではログオフが必要です。しかしWindows 8.1以降ではSystem-DPIを変更した上でログオフするまでの間、DPI virtualization of system-DPI aware applicationsによってDPI変更を実現します。(アプリケーションはログオン時のSystem-DPI倍率で描画を行い、OSがログオン時のSystem-DPIから現在のDPIへの倍率を補正します。)
この機能はPer monitor-DPI awareでも使用され、System-DPIとは異なる倍率に設定されているモニターに対してはOSが倍率を補正します。
これらの場面において、質問の状況が発生するのだと思います。根本的にはSystem-DPI未対応とするか、Per monitor-DPIに対応する必要があります。
- 回答としてマーク YAMAMAYA 2016年10月4日 6:17
すべての返信
-
高DPIに対応したいFormの以下の値をDpiに設定されていますでしょうか?
また、以下のページにその辺について書いてありそうです。
http://8thway.blogspot.jp/2013/09/winforms-per-monitor-dpi.html
- 編集済み ryo1988 2016年10月3日 1:46
-
私の環境(Windows 10 x64)でも下記の手順で再現しました。
- Windowsのディスプレイ設定で「テキスト、アプリ、その他の項目のサイズ」 = 200 % でサインイン
- サインインした状態でWindowsのディスプレイ設定で「テキスト、アプリ、その他の項目のサイズ」 を 100 % に変更する
- マニフェストで「dpiAware = true」のWindows フォームアプリを起動して、フォームのサイズを変更する
→複数の縦横の黒い線が表示される
100%の状態で一度サインアウトしてサインインしなおすと、再現しなくなります。
Windows フォームの(dpiAware = true)のアプリは標準で拡大縮小の動的な変更に完全対応していないのかなと思いました。回避方法として、フォームのリサイズイベントに対して Invalidate() を呼び出すのはどうでしょうか?
private void Form1_Resize(object sender, EventArgs e) { Invalidate(); }
- 編集済み kenjinoteMVP 2016年10月3日 9:20
- 回答としてマーク YAMAMAYA 2016年10月3日 14:36
-
Writing DPI-Aware Desktop and Win32 Applications - High DPI Features in Windowsで少し説明されていますが、Windows 8.1からDPI virtualization of system-DPI aware applicationsおよびPer monitor-DPI awareというものが提供されています。
本来System-DPIの変更にはWindows 7以降ではログオフが必要です。しかしWindows 8.1以降ではSystem-DPIを変更した上でログオフするまでの間、DPI virtualization of system-DPI aware applicationsによってDPI変更を実現します。(アプリケーションはログオン時のSystem-DPI倍率で描画を行い、OSがログオン時のSystem-DPIから現在のDPIへの倍率を補正します。)
この機能はPer monitor-DPI awareでも使用され、System-DPIとは異なる倍率に設定されているモニターに対してはOSが倍率を補正します。
これらの場面において、質問の状況が発生するのだと思います。根本的にはSystem-DPI未対応とするか、Per monitor-DPIに対応する必要があります。
- 回答としてマーク YAMAMAYA 2016年10月4日 6:17