Windows フォームでの自動スケーリング

自動スケーリングによって、特定のディスプレイの解像度またはシステムのフォントを持つマシンに合わせて設計されたフォームとコントロールを、ディスプレイの別の解像度やシステム フォントを持つ別のマシンで適切に表示することができます。 フォームとコントロールが、ユーザーとその他の開発者のマシンのネイティブ ウィンドウとその他のアプリケーションで、一貫性を持つよう適切にサイズ変更され、 自動スケーリングと視覚スタイルに対する .NET Framework のサポートにより、各ユーザーのマシンのネイティブの Windows アプリケーションと比較した場合、.NET Framework アプリケーションが一貫したルック アンド フィールを維持することができます。

.NET Framework バージョン 2.0 以降では、ほとんどの場合、自動スケーリングは正常に機能します。 ただし、フォント パターンの変更が問題になる可能性があります。 これを解決する方法の例については、「方法: Windows フォーム アプリケーションのフォント パターンの変更に応答する」を参照してください。

自動スケーリングの必要性

自動スケーリングがないと、1 つのディスプレイの解像度やフォントのために設計されたアプリケーションは、その解像度やフォントが変更されたときに、表示が小さすぎたり大きすぎたりします。 たとえば、アプリケーションが基準として Tahoma の 9 ポイントを使用して設計されている場合、調整なしでは、システム フォントが Tahoma の 12 ポイントのマシンで実行すると、表示が小さすぎます。 タイトル、メニュー、テキスト ボックスの内容などのテキストの要素は、他のアプリケーションより小さく表示されます。 さらに、タイトル バー、メニューや、多数のコントロールのテキストを含むユーザー インターフェイス (UI) 要素のサイズは、使用されるフォントに依存します。 この例では、これらの要素は比較的小さく表示されます。

類似する状況は、アプリケーションがディスプレイの特定の解像度のために設計されている場合にも発生します。 最も一般的な表示解像度は 96 ドット/インチ (DPI) (100% のディスプレイ スケーリングに相当) ですが、125%、150%、200% (それぞれ 120、144、192 DPI に相当) 以上をサポートするより高解像度なディスプレイも普及し始めています。 調整なしだと、特にグラフィックスに基づくアプリケーションで、ある解像度のために設計されたものが、別の解像度で実行したときに、表示が大きすぎたり小さすぎたりします。

自動スケーリングは、相対的なフォント サイズやディスプレイ解像度に従ってフォームと子コントロールを自動でサイズ変更することで、これらの問題を改善しようとしています。 Windows オペレーティング システムは、ダイアログ単位と呼ばれるは、相対的な測定単位を使用して、ダイアログ ボックスの自動スケーリングをサポートします。 ダイアログ単位は、システム フォントに基づいており、ピクセルとの関係は、Win32 SDK 関数 GetDialogBaseUnits によって決定できます。 ユーザーが Windows によって使用されるテーマを変更すると、すべてのダイアログ ボックスがそれに合わせて自動的に調整されます。 さらに、.NET Framework は、既定のシステム フォントまたはディスプレイの解像度のいずれかに応じて自動スケーリングをサポートしています。 必要に応じて、アプリケーションで自動スケーリングを無効化できます。

自動スケーリングの元のサポート

.NET Framework のバージョン 1.0 および 1.1 は、Windows の UI に使用される (Win32 SDK 値 DEFAULT_GUI_FONT で表す) 既定のフォントに依存した、簡単な方法で自動スケーリングをサポートしていました。 このフォントは、通常、ディスプレイの解像度が変更されたときにのみ変更されました。 自動スケーリングを実装するために、次のメカニズムが使用されていました。

  1. デザイン時は、AutoScaleBaseSize プロパティ (これは現在非推奨とされます) が、開発者のマシンの既定のシステム フォントの高さと幅に設定されていました。

  2. 実行時は、ユーザーのマシンの既定のシステム フォントが Form クラスの Font プロパティを初期化するために使用されていました。

  3. フォームを表示する前に、フォームのスケーリングのため、ApplyAutoScaling メソッドが呼び出されました。 このメソッドは、AutoScaleBaseSizeFont から相対スケール サイズを計算し、Scale メソッドを呼び出してフォームとその子を実際にスケーリングしました。

  4. ApplyAutoScaling への後続の呼び出しがフォームを段階的にサイズ変更することがないよう、AutoScaleBaseSize の値が更新されました。

このメカニズムは、ほとんどの目的では十分ですが、次の制限がありました。

  • AutoScaleBaseSize プロパティはベースラインのフォント サイズを整数値として表すため、フォームが複数の解像度を循環した場合、エラーの丸めが発生します。

  • 自動スケーリングは Form クラスでのみ実装されており、ContainerControl クラスでは実装されていませんでした。 その結果、ユーザー コントロールは、それがフォームと同じ解像度で設計されていて、かつデザイン時にそのユーザー コントロールがそのフォームに配置された場合にのみ、正しくスケーリングされるということになっていました。

  • フォームとその子コントロールの設計作業を複数の開発者によって並行して進めることができたのは、マシンの解像度が同じ場合に限られていました。 同じように、フォームの継承は、親フォームに関連付けられている解像度に依存していました。

  • FlowLayoutPanelTableLayoutPanel など、.NET Framework バージョン 2.0 で導入された新しいレイアウト マネージャーと互換性がありません。

  • .NET Compact Framework への互換性に必要なディスプレイの解像度に直接基づくスケーリングをサポートしていませんでした。

このメカニズムは、.NET Framework バージョン 2.0 で後方互換性のために保持されますが、次に説明するより堅牢なスケーリング メカニズムによって置き換えられました。 その結果、AutoScaleApplyAutoScalingAutoScaleBaseSize、および特定の Scale のオーバーロードは廃止マークが付けられています。

注意

従来のコードを .NET Framework バージョン 2.0 にアップグレードする際、これらのメンバーへの参照を削除して問題ありません。

自動スケーリングの現在のサポート

.NET Framework バージョン 2.0 は、Windows フォームの自動規スケーリングに次の変更を導入することで、以前の制限を解消しています。

  • スケーリングの基本サポートは ContainerControl クラスに移動し、フォーム、ネイティブの複合コントロールおよびユーザー コントロールは、すべて統一されたスケーリングのサポートを受け取ります。 新しいメンバー AutoScaleFactorAutoScaleDimensionsAutoScaleMode、および PerformAutoScale が追加されました。

  • Control クラスにも、スケーリングに参加して同じフォームでのスケーリングの混在をサポートできる新しいメンバーがいくつかあります。 具体的には、ScaleScaleChildren、および GetScaledBounds メンバーが、スケーリングをサポートします。

  • 画面の解像度に基づくスケーリングのサポートが追加され、AutoScaleMode の列挙型により定義されるように、システム フォントのサポートを補完します。 このモードは、アプリケーションの移行を容易にする .NET Compact Framework によりサポートされる、自動スケーリングと互換性があります。

  • FlowLayoutPanelTableLayoutPanel などのレイアウト マネージャーの互換性が、自動スケーリングの実装に追加されています。

  • スケール ファクターが、通常は SizeF 構造を使用する浮動小数点値として表され、エラーの丸めが事実上解決されています。

注意事項

DPI とフォントのスケーリング モードの任意の混在はサポートされません。 1 つのモード (DPI など) を使用してユーザー コントロールのスケールを調整し、別のモード (フォント) を使用してフォームに配置して問題が発生しない場合でも、基底フォームはあるモード、派生フォームは別のモードというように混在させると、予期しない結果が発生することがあります。

動作中の自動スケーリング

Windows フォームは、次のロジックを使用して、フォームとそのコンテンツを自動的にスケール調整します。

  1. デザイン時に、各 ContainerControlAutoScaleModeAutoScaleDimensions にそれぞれスケーリング モードと現在の解像度を記録します。

  2. 実行時に、実際の解像度は CurrentAutoScaleDimensions プロパティに格納されます。 AutoScaleFactor プロパティは、実行時と設計時のスケーリング解像度の比率を動的に計算します。

  3. フォームが読み込まれたときに、CurrentAutoScaleDimensionsAutoScaleDimensions の値が異なる場合は、PerformAutoScale メソッドが呼び出されてコントロールと子のスケールを調整します。 このメソッドはレイアウトを中断し、Scale メソッドを呼び出して実際のスケーリングを実行します。 その後、AutoScaleDimensions の値がプログレッシブ スケーリングを避けるために更新されます。

  4. また、PerformAutoScale は次のような状況でも自動的に呼び出されます。

    • スケーリング モードが Font の場合の OnFontChanged イベントへの応答。

    • コンテナー コントロールのレイアウトが再開され、AutoScaleDimensions プロパティまたは AutoScaleMode プロパティで変更が検出されたとき。

    • 上記に示すように、親の ContainerControl がスケーリングされたとき。 各コンテナー コントロールは、親コンテナーからのスケーリング ファクターではなく、独自のスケーリング ファクターを使用してその子のスケーリングを担当します。

  5. 子コントロールは、いくつかの方法で、そのスケーリングの動作を変更できます。

    • ScaleChildren プロパティをオーバーライドして、子コントロールをスケーリングすべきかどうかを決定することができます。

    • GetScaledBounds メソッドをオーバーライドして、スケーリングのロジックではなく、コントロールがスケーリングされる両機にを調整することができます。

    • ScaleControl メソッドをオーバーライドして、現在のコントロールのスケーリングのロジックを変更することができます。

関連項目