次の方法で共有


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 フォームの構成要素の追加」を参照してください。

新しい 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);

関連項目