Windows フォームでの高 DPI のサポート

.NET Framework 4.7 以降の Windows フォームには、一般的な高 DPI と動的 DPI のシナリオのための機能強化が含まれています。 これには以下が含まれます。

  • MonthCalendar コントロールや CheckedListBox コントロールなど、多数の Windows フォーム コントロールの拡大縮小とレイアウトの機能強化。

  • シングルパスの拡大縮小。 .NET Framework 4.6 以前のバージョンでは、拡大縮小は複数のパスによって実行されており、一部のコントロールが必要以上に拡大縮小される原因になっていました。

  • Windows フォーム アプリケーションの開始後にユーザーが DPI またはスケール ファクターを変更する動的 DPI のシナリオのサポート。

.NET Framework 4.7 以降の .NET Framework のバージョンでは、強化された高 DPI のサポートはオプトイン機能です。 それを利用するようにアプリケーションを構成する必要があります。

高 DPI をサポートするための Windows フォーム アプリの構成

高 DPI の認識をサポートする Windows フォームの新しい機能は、.NET Framework 4.7 を対象とし、Windows 10 Creators Update 以降の Windows オペレーティング システムで実行されているアプリケーションでのみ使用できます。

さらに、Windows フォーム アプリケーションで高 DPI のサポートを構成するには、次の操作を行う必要があります。

  • Windows 10 との互換性を宣言します。

    これを行うには、マニフェスト ファイルに以下を追加します。

    <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
      <application>
        <!-- Windows 10 compatibility -->
        <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
      </application>
    </compatibility>
    
  • app.config ファイルでモニターごとの DPI 認識を有効にします。

    Windows フォームには、.NET Framework 4.7 以降で追加された新しい機能とカスタマイズをサポートするための新しい <System.Windows.Forms.ApplicationConfigurationSection> 要素が導入されています。 高 DPI をサポートする新機能を利用するには、アプリケーションの構成ファイルに以下を追加します。

    <configuration>
      <!-- ... other xml settings ... -->
    
      <System.Windows.Forms.ApplicationConfigurationSection>
        <add key="DpiAwareness" value="PerMonitorV2" />
      </System.Windows.Forms.ApplicationConfigurationSection>
    
    </configuration>
    

    重要

    以前のバージョンの .NET Framework では、マニフェストを使用して高 DPI のサポートを追加していました。 この方法は、app.config ファイルで定義されている設定が上書きされるため、推奨されなくなりました。

  • 静的メソッド EnableVisualStyles を呼び出します。

    アプリケーションのエントリ ポイントで、このメソッドを最初に呼び出す必要があります。 次に例を示します。

    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form2());
    }
    

個々の高 DPI 機能のオプトアウト

DpiAwareness の値を PerMonitorV2 に設定すると、.NET Framework 4.7 以降のバージョンの .NET Framework でサポートされているすべての高 DPI 認識機能が有効になります。 通常、これはほとんどの Windows フォーム アプリケーションに適しています。 ただし、1 つ以上の個別の機能を無効にすることもできます。 これを行う最も重要な理由は、既存のアプリケーションコードで既にその機能が処理されている場合です。 たとえば、アプリケーションで自動拡大縮小が処理されている場合は、次のようにして自動サイズ変更機能を無効にできます。

<configuration>
  <!-- ... other xml settings ... -->

  <System.Windows.Forms.ApplicationConfigurationSection>
    <add key="DpiAwareness" value="PerMonitorV2" />
    <add key="EnableWindowsFormsHighDpiAutoResizing" value="false" />
  </System.Windows.Forms.ApplicationConfigurationSection>

</configuration>

個々のキーとその値の一覧については、「Windows フォームの add 構成要素」をご覧ください。

新しい DPI 変更イベント

.NET Framework 4.7 以降では、3 つの新しいイベントを使用して、プログラムで動的な DPI の変更を処理できます。

  • DpiChangedAfterParent は、コントロールの DPI 設定がプログラムによって変更されたときに、親コントロールまたはフォームの DPI 変更イベントが発生した後で生成されます。
  • DpiChangedBeforeParent は、コントロールの DPI 設定がプログラムによって変更されたときに、親コントロールまたはフォームの DPI 変更イベントが発生する前に生成されます。
  • DpiChanged は、フォームが現在表示されているディスプレイ デバイスの DPI 設定が変更されたときに生成されます。

新しいヘルパー メソッドとプロパティ

また、.NET Framework 4.7 では、DPI スケールに関する情報を提供し、DPI スケールを実行できるようにする、新しいヘルパー メソッドとプロパティがいくつか追加されています。 これには以下が含まれます。

  • LogicalToDeviceUnits は、値を論理ピクセルからデバイスピクセルに変換します。

  • ScaleBitmapLogicalToDevice は、ビットマップ画像をデバイスの論理 DPI に拡大縮小します。

  • DeviceDpi は、現在のデバイスの DPI を返します。

バージョン管理に関する考慮事項

アプリケーションは、.NET Framework 4.7 と Windows 10 Creators Update で実行されるだけでなく、高 DPI の機能強化と互換性のない環境で実行される場合があります。 この場合、アプリケーション用のフォールバックを開発する必要があります。 拡大縮小を処理するカスタム描画を実行することで、これを行うことができます。

これを行うには、アプリが実行されているオペレーティング システムを特定する必要もあります。 そのためには、次のようなコードを使用します。

// Create a reference to the OS version of Windows 10 Creators Update.
Version OsMinVersion = new Version(10, 0, 15063, 0);

// Access the platform/version of the current OS.
Console.WriteLine(Environment.OSVersion.Platform.ToString());
Console.WriteLine(Environment.OSVersion.VersionString);

// Compare the current version to the minimum required version.
Console.WriteLine(Environment.OSVersion.Version.CompareTo(OsMinVersion));

アプリケーション マニフェストのサポートされるオペレーティング システムの一覧に含まれていなかった場合、アプリケーションで Windows 10 を正常に検出できないことに注意してください。

また、アプリケーションがビルドされた対象の .NET Framework のバージョンを確認することもできます。

Console.WriteLine(AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName);

関連項目