C#で簡単なWinformsアプリケーションを作成しました。高DPI設定(150%など)のマシンでアプリケーションを実行すると、アプリケーションが拡大されます。ここまでは順調ですね!ただし、フォントをより大きなフォントサイズでレンダリングする代わりに、すべてのテキストも拡大されます。もちろん、これは非常にぼやけたテキストにつながります(ボタンなどのすべてのコントロールで)。
ウィンドウはテキストを正しくレンダリングする必要はありませんか?たとえば、私のアプリケーションのタイトルバーは鮮明でクリアにレンダリングされます。
100%(または「XPスタイルのDPIスケーリング」チェックボックスをオンにして125%)を超えると、WindowsはデフォルトでUIのスケーリングを引き継ぎます。これは、アプリに出力をビットマップにレンダリングさせ、そのビットマップを画面に描画することにより行われます。そのビットマップの再スケーリングにより、必然的にテキストがあいまいになります。 「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>
Main()メソッドでSetProcessDPIAware()をpinvokeすることもできます。たとえば、ClickOnceを使用してデプロイする場合に必要です。
[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();
更新、VS2015 Update 1以降を使用する場合、この一般的なニーズは最終的に少し簡単になります。追加されたマニフェストには関連するディレクティブが既にあり、コメントを削除するだけです。
この投稿を見つけるための検索キーワード:dpiAware
アプリケーションは2つの異なるモードで開発できます。
最初の方法は、アプリケーションをDPI非対応として宣言することです(何も宣言しないと、これがデフォルトになります)。この場合、オペレーティングシステムは、期待される96 DPIの下でアプリケーションをレンダリングし、その後、前述のビットマップスケーリングを実行します。結果はぼやけたアプリケーションになりますが、正しいレイアウトになります。
2番目のオプションは、アプリケーションをDPI対応として宣言することです。この場合、OSはスケーリングを行わず、アプリケーションが画面の元のDPIに従ってレンダリングできるようにします。モニターごとのDPI環境の場合、アプリケーションはすべての画面の最高のDPIでレンダリングされ、このビットマップは各モニターの適切なサイズに縮小されます。ダウンスケーリングを行うと、アップスケーリングよりも優れた表示エクスペリエンスが得られますが、依然として多少の曖昧さに気付くかもしれません。
これを回避したい場合は、アプリケーションをモニターごとのDPI対応として宣言する必要があります。次に、アプリケーションが異なるモニター間でドラッグされたことを検出し、現在のモニターのDPIに従ってレンダリングする必要があります。
DPI認識の宣言は、マニフェストファイルで行われます。
次のリンクを参照してください stackoverflow
これらの提案はどれもうまくいきませんでしたが、Form.Font = new
をForm.Design.cs
から削除した後に何かが起こりました。フォームは適切に再スケーリングを開始しました。またはまったく。どうして?他の誰かが説明できるかもしれませんが、私が行った変更について話すことができ、それが私が取り組んでいたフォームの根本的な原因であることがわかりました。それが役に立てば幸い。
.NET Framework 4.7およびWindows 10 Creators Update以降を使用して、Windowsフォームアプリケーションの高DPIサポートを構成するには、次のことを行う必要があります。
Windows 10との互換性を宣言する
これを行うには、manifest
ファイルに次を追加します。
<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 Formsは、新しい System.Windows.Forms.ApplicationConfigurationSection 要素を導入して、.NET Framework 4.7以降で追加された新しい機能とカスタマイズをサポートします。高DPIをサポートする新機能を活用するには、アプリケーション構成ファイルに次を追加します。
<System.Windows.Forms.ApplicationConfigurationSection>
<add key="DpiAwareness" value="PerMonitorV2" />
</System.Windows.Forms.ApplicationConfigurationSection>
重要
.NET Frameworkの以前のバージョンでは、マニフェストを使用して高DPIサポートを追加しました。このアプローチはapp.configファイルで定義された設定を上書きするため、推奨されなくなりました。
静的なEnableVisualStylesメソッドを呼び出します。
これは、アプリケーションエントリポイントの最初のメソッド呼び出しである必要があります。例えば:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form2());
}
この利点は、Windowsフォームアプリケーションの起動後にユーザーがDPIまたはスケールファクターを変更する動的DPIシナリオをサポートしていることです。