Windows フォームにおける自動スケーリング

更新 : 2007 年 11 月

自動スケーリングによって、あるマシンで特定の表示解像度やシステム フォントを使用するようにデザインされているフォームとそのコントロールが、別のマシンで異なる表示解像度やシステム フォントを使って適切に表示されます。フォームとそのコントロールは、ネイティブなウィンドウ、およびユーザーのマシンと開発者のマシン上の他のアプリケーションと一貫性を持つように、適切にサイズが変更されます。.NET Framework における自動スケーリングと visual スタイルのサポートによって、各ユーザー マシン上のネイティブな Windows アプリケーションと比べて、.NET Framework アプリケーションは一貫した外観と操作性を維持できます。

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

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

アプリケーションが特定の表示解像度に合わせてデザインされている場合も、同様の状態が起こります。最も一般的な表示解像度は 96 dpi (dots per inch) ですが、120、133、170、およびそれ以上をサポートする高解像度の表示が、一般的になりつつあります。ある解像度に合わせてデザインされているアプリケーションは、特にグラフィック ベースのアプリケーションは、調整が行われないと、別の解像度で実行すると大きく表示されるか、小さく表示されてしまいます。

自動スケーリングは、相対的なフォント サイズや表示解像度に従ってフォームとその子コントロールのサイズを自動的に変更することによって、このような問題を改善しようとするものです。Windows オペレーティング システムでは、ダイアログ単位と呼ばれる相対的な長さの単位を使って、ダイアログ ボックスの自動スケーリングをサポートしています。ダイアログ単位はシステム フォントに基づいており、ピクセルとの関係は、Win32 SDK 関数の GetDialogBaseUnits を通じて決定できます。Windows が使用するテーマが変更されると、すべてのダイアログ ボックスはそれに従って自動的に調整されます。また、次の点に注意してください。

.NET Framework は、既定のシステム フォントまたは表示解像度に従って自動スケーリングをサポートします。アプリケーション内で自動スケーリングを無効にすることもできます。

これまでの自動スケーリングのサポート

.NET Framework のバージョン 1.0 および 1.1 では、Win32 SDK 値の DEFAULT_GUI_FONT で表される、UI 用の Windows の既定フォントに依存するという単純な方法で、自動スケーリングがサポートされていました。通常、表示解像度が変更されるときのみ、このフォントは変更されます。自動スケーリングを実装するには、次の機構が使用されていました。

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

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

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

  4. AutoScaleBaseSize の値が更新され、ApplyAutoScaling を呼び出しても、フォームは続けてサイズ変更されません。

この機構はほとんどの場合に有効でしたが、次のような制限がありました。

  • AutoScaleBaseSize プロパティはベースラインのフォント サイズを整数値で表すため、フォームに複数の解像度を繰り返し適用すると、明らかな丸めエラーが発生します。

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

  • 複数の開発者がフォームとその子コントロールを同時にデザインできるのは、マシンの解像度が同じ場合だけです。同様に、フォームの継承も、親フォームに関連する解像度に依存します。

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

  • .NET Compact Framework との互換性で要求される、表示解像度に直接基づくスケーリングはサポートされませんでした。

この機構は、下位互換性を維持するために .NET Framework バージョン 2.0 に残されていますが、以下で説明する信頼性の高いスケーリング機構に取って代わられました。結果として、AutoScaleApplyAutoScalingAutoScaleBaseSize、および特定の Scale オーバーロードに旧式のマークが付けられています。

ms229605.alert_note(ja-jp,VS.90).gifメモ :

レガシ コードを .NET Framework Version 2.0 にアップグレードすると、これらのメンバへの参照を安全に削除できます。

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

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

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

  • Control クラスにもさまざまな新しいメンバが追加されて、スケーリングに関係したり、同じフォーム上での混合スケーリングをサポートできるようになりました。特に、ScaleScaleChildren、および GetScaledBounds の各メンバがスケーリングをサポートします。

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

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

  • スケール ファクタは、通常は SizeF 構造体を使って浮動小数点値で表されるようになったため、丸めエラーがほとんどなくなりました。

ms229605.alert_caution(ja-jp,VS.90).gif注意 :

DPI モードとフォント スケーリング モードの混在はサポートされません。あるモード (たとえば DPI) を使ってユーザー コントロールをスケーリングし、別のモード (フォント) を使ってそのユーザー コントロールを問題なくフォームに配置できる場合もありますが、あるモードのベース フォームと別のモードの派生フォームを混在させると、予期しない結果が生じることがあります。

自動スケーリングの動作

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

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

  2. 実行時には、実際の解像度が CurrentAutoScaleDimensions プロパティに保存されます。AutoScaleFactor プロパティは、実行時とデザイン時のスケーリング解像度の比を動的に計算します。

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

  4. PerformAutoScale は、次の状況でも自動的に起動されます。

    • スケーリング モードが Font で、OnFontChanged イベントに応答する場合。

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

    • 上に示したように、親の ContainerControl がスケーリングされる場合。各コンテナ コントロールは、親コンテナのスケール ファクタではなく、各自のスケール ファクタを使って、子のスケーリングを行います。

  5. 子コントロールは、さまざまな方法を通じて、そのスケーリング動作を変更できます。

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

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

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

参照

処理手順

方法 : Windows XP の Visual スタイルを有効にする

方法 : 自動スケーリングを解除してパフォーマンスを向上させる

概念

visual スタイルが使用されているコントロールのレンダリング

参照

AutoScaleMode

Scale

PerformAutoScale

AutoScaleDimensions