1. ホーム
  2. c#

[解決済み] DPIが高いマシン(例:150%)でアプリが正しく動作するように設定するにはどうすればよいですか?

2022-10-29 23:01:49

質問

C# で簡単な Winforms アプリケーションを作成しました。DPI 設定が高い (たとえば、150%) マシン上でアプリケーションを実行すると、アプリケーションが拡大表示されます。ここまではいい感じです。 しかし、フォントを高いフォントサイズでレンダリングする代わりに、すべてのテキストも拡大表示されます。もちろん、これは非常にぼやけたテキスト (ボタンなどのすべてのコントロール) につながります。

Windows はテキストを正しくレンダリングするように対処すべきではありませんか? たとえば、私のアプリケーションのタイトル バーは鮮明にレンダリングされます。

どのように解決するのですか?

100% (または "XP-style DPI scaling" チェックボックスをオンにした場合は 125%) を超えると、デフォルトで Windows が UI のスケーリングを引き継ぎます。 これは、アプリケーションが出力をビットマップにレンダリングし、そのビットマップを画面に描画することによって行われます。 このビットマップのスケールが変更されると、どうしてもテキストがぼやけて見えてしまいます。 DPI 仮想化と呼ばれる機能により、古いプログラムを高解像度モニターで使用できるように維持します。

より高い DPI 設定を扱うことができることを明示的に知らせるために <dpiAware> 要素をマニフェストに追加して、より高い DPI 設定を処理できることを明示的に知らせる必要があります。 MSDN のページ はここで がありますが、UACの設定が省略されているため完全ではありません。 プロジェクト] + [新規項目の追加] で、[アプリケーション マニフェスト ファイル] を選択します。 マニフェスト テキストを編集するか、これをコピー/貼り付けします。

<?xml version="1.0" encoding="utf-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
    <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
        <security>
            <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
                <requestedExecutionLevel level="asInvoker" uiAccess="false" />
            </requestedPrivileges>
        </security>
    </trustInfo>
    <asmv3:application>
        <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
            <dpiAware>true</dpiAware>
        </asmv3:windowsSettings>
    </asmv3:application>
</assembly>

ClickOnceでデプロイする場合などに必要なSetProcessDPIAware()をMain()メソッドでピン留めすることもできます。

    [STAThread]
    static void Main() {
        if (Environment.OSVersion.Version.Major >= 6) SetProcessDPIAware();
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());             // Edit as needed
    }

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern bool SetProcessDPIAware();


UPDATE、この共通のニーズは、VS2015 Update 1 以上を使用する場合、最終的に少し簡単になります。 追加されたマニフェストにはすでに関連するディレクティブがあり、コメントを削除するだけです。


この投稿を検索できるようにするための検索キーワード: dpiAware