.Net Framework 4.7のアプリケーションをターゲットにして、Windows 10 v1703(Creators Update Build 15063)で実行します。Windows 10(v1703)での.Net 4.7により、MSはDPIを大幅に改善しました。
.NET Framework 4.7以降、Windowsフォームには、一般的な高DPIおよび動的DPIシナリオの機能強化が含まれています。これらには以下が含まれます:
MonthCalendarコントロールやCheckedListBoxコントロールなど、多数のWindowsフォームコントロールのスケーリングとレイアウトの改善。
シングルパススケーリング。.NET Framework 4.6以前のバージョンでは、スケーリングが複数のパスを介して実行されていたため、一部のコントロールが必要以上にスケーリングされていました。
Windowsフォームアプリケーションの起動後にユーザーがDPIまたはスケール係数を変更する動的DPIシナリオのサポート。
これをサポートするには、アプリケーションマニフェストをアプリケーションに追加し、アプリケーションがWindows 10をサポートしていることを通知します。
<compatibility xmlns="urn:schemas-microsoft.comn:compatibility.v1">
<application>
<!-- Windows 10 compatibility -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
次に、を追加app.config
し、アプリをモニターごとに宣言します。これは今はapp.configで行われ、以前のようにマニフェストでは行われません!
<System.Windows.Forms.ApplicationConfigurationSection>
<add key="DpiAwareness" value="PerMonitorV2" />
</System.Windows.Forms.ApplicationConfigurationSection>
このPerMonitorV2は、Windows 10 Creators Updateから新しく追加されました。
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
Per Monitor v2とも呼ばれます。元のモニターごとのDPI認識モードに対する進歩。これにより、アプリケーションはトップレベルウィンドウごとに新しいDPI関連のスケーリング動作にアクセスできます。
子ウィンドウのDPI変更通知 -モニターごとのv2コンテキストでは、ウィンドウツリー全体に、発生したDPI変更が通知されます。
非クライアント領域のスケーリング -すべてのウィンドウは、非クライアント領域をDPIセンシティブな方法で自動的に描画します。EnableNonClientDpiScalingの呼び出しは不要です。
S のWin32メニューのcaling -パーモニタv2のコンテキストで作成されたすべてのNTUSERメニューごとのモニター方法でスケーリングされます。
ダイアログのスケーリング -モニターごとのv2コンテキストで作成されたWin32ダイアログは、DPIの変更に自動的に応答します。
comctl32コントロールのスケーリングの向上 -さまざまなcomctl32コントロールにより、モニターごとのv2コンテキストでのDPIスケーリング動作が向上しています。
テーマ設定の動作の改善 -モニターごとのv2ウィンドウのコンテキストで開かれたUxThemeハンドルは、そのウィンドウに関連付けられたDPIに関して動作します。
これで、3つの新しいイベントをサブスクライブして、DPIの変更について通知を受けることができます。
Control.DpiChangedAfterParent、これは発生します親コントロールまたはフォームのDPI変更イベントが発生した後に、コントロールのDPI設定がプログラムによって変更されたときに発生します。
Control.DpiChangedBeforeParent。コントロールのDPI設定が、その親コントロールまたはフォームのDPI変更イベントが発生する前にプログラムで変更されたときに発生します。
Form.DpiChangedは、フォームが現在表示されているディスプレイデバイスでDPI設定が変更されたときに発生します。
また、DPIの処理/スケーリングに関する3つのヘルパーメソッドがあります。
Control.LogicalToDeviceUnitsは、値を論理ピクセルからデバイスピクセルに変換します。
Control.ScaleBitmapLogicalToDevice、ビットマップイメージをデバイスの論理DPIにスケーリングします。
Control.DeviceDpiは、現在のデバイスのDPIを返します。
それでも問題が解決しない場合は、app.configエントリからDPIの改善をオプトアウトできます。
ソースコードにアクセスできない場合は、Windowsエクスプローラーのアプリケーションプロパティに移動し、互換性に移動して、 System (Enhanced)
GDIスケーリングをアクティブにし、DPI処理も改善します。
GDIベースのアプリケーションの場合、WindowsはこれらをモニターごとにDPIスケーリングできるようになりました。つまり、これらのアプリケーションは、魔法のように、モニターごとのDPI対応になります。
これらの手順をすべて実行すると、WinFormsアプリケーションのDPIエクスペリエンスが向上します。ただし、アプリのターゲットを.net 4.7にする必要があり、少なくともWindows 10 Build 15063(Creators Update)が必要です。次のWindows 10 Update 1709では、さらに改善される可能性があります。
NumericUpDown
また、Margin
適切にスケーリングされません。マージンは2倍に拡大されているようです。1回縮小すると、見栄えが良くなります。