DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

.NET Framework 2.0以降でも1.1と同じGDI+でコントロールの文字列を描画する
「Application.SetCompatibleTextRenderingDefault(false)」の意味は?

.NET Framework 1.1以前と2.0以降では、コントロールに文字列を描画する方法が異なります。.NET Framework 1.1以前では、GDI+を使って(つまり、Graphics.DrawStringメソッドを使って)文字列を描画しています。しかし.NET Framework 2.0以降では、GDIを使って(つまり、TextRenderer.DrawTextメソッドを使って)文字列を描画します。

補足:Graphics.DrawStringメソッドやTextRenderer.DrawTextメソッドについて詳しくは、「文字を描く」をご覧ください。

なぜこのような変更が行われたのかという理由について、MSDNの「Application.SetCompatibleTextRenderingDefault メソッド」では、「GDI+ にパフォーマンスとローカライズに関する問題があるから」と説明しています。

この2つの描画方法では、表示される文字列の大きさや位置などが異なります。下のGIFアニメは、ボタンコントロールの文字列をGDI+とGDIで描画した時にどのように変わるのかを表しています。

GDI+とGDIの違い

このような違いがあるため、.NET Framework 1.1以前でデザインされたアプリケーションが、2.0以降では思ったように表示されない可能性があります。

ここからは、.NET Framework 2.0以降で1.1以前との互換性を保つために、GDI+を使ってコントロールの文字列が描画されるようにする方法について説明します。

ただし、もし.NET Framework 1.1以前との互換性を重視する必要がないのであれば、そのままGDIを使って描画するようにしてください。

エントリポイントでApplication.SetCompatibleTextRenderingDefaultにTrueを渡す

Visual Studio 2005以降では、Windowsフォームアプリケーションのエントリポイントに「Application.SetCompatibleTextRenderingDefault(false)」という記述があります。このようにApplication.SetCompatibleTextRenderingDefaultメソッドに引数Falseを渡して呼び出すと、GDIを使った描画になります。SetCompatibleTextRenderingDefaultメソッドにTrueを渡すか、SetCompatibleTextRenderingDefaultメソッドを呼び出さなかった場合は、GDI+を使った描画になります。

よって、次のようにエントリポイントを書き換えることで、GDI+を使った描画にすることができます。なおエントリポイントについては、「アプリケーションのエントリポイントを自作する」をご覧ください。

VB.NET
コードを隠すコードを選択
''' <summary>
''' アプリケーションのメイン エントリ ポイントです。
''' </summary>
<STAThread()> _
Sub Main()
    Application.EnableVisualStyles()
    'Application.SetCompatibleTextRenderingDefaultにTrueを渡す
    Application.SetCompatibleTextRenderingDefault(True)

    Application.Run(New Form1())
End Sub
C#
コードを隠すコードを選択
/// <summary>
/// アプリケーションのメイン エントリ ポイントです。
/// </summary>
[STAThread]
private static void Main()
{
    Application.EnableVisualStyles();
    //Application.SetCompatibleTextRenderingDefaultにTrueを渡す
    Application.SetCompatibleTextRenderingDefault(true);

    Application.Run(new Form1());
}
補足:Application.SetCompatibleTextRenderingDefaultメソッドは必ず最初のウィンドウが作成される前に呼び出す必要があります。そうしないと、InvalidOperationExceptionがスローされます。もしどうしても後で変更したい場合は、後述するUseCompatibleTextRenderingメソッドを使って対象となるすべてのコントロールの描画方法を変更してください。

VB.NETでアプリケーションフレームワークを有効にしている時

VB.NETでアプリケーションフレームワークを有効にしている時は、エントリポイントを自由に変更できません。この場合は、WindowsFormsApplicationBase.UseCompatibleTextRenderingプロパティをTrueにします。その手順は、以下の通りです。

  1. プロジェクトのプロパティ画面を表示します。メニューの[プロジェクト]-[(アプリケーション名)のプロパティ]を選択すれば、表示できます。
  2. 左側のメニューで「アプリケーション」を選択します。
  3. 「Windowsアプリケーションフレームワークプロパティ」と書かれた箇所の右下にある「アプリケーションイベントの表示」というボタンをクリックします。
  4. ApplicationEvents.vbが表示されますので、そのMyApplicationクラス内に次のようなコードを記述して、保存します。
    VB.NET
    コードを隠すコードを選択
    Protected Overloads Shared ReadOnly Property UseCompatibleTextRendering() _
            As Boolean
        Get
            Return True
        End Get
    End Property
    

個々のコントロールのUseCompatibleTextRenderingプロパティをTrueにする

コントロールのUseCompatibleTextRenderingプロパティをTrueにすると、そのコントロールの文字列はGDI+で描画されます。Falseにすると、GDIで描画されます。

前述したApplication.SetCompatibleTextRenderingDefaultメソッドは、実はコントロールのUseCompatibleTextRenderingプロパティのデフォルトの値を設定するものです。よって、Application.SetCompatibleTextRenderingDefaultメソッドに何を渡したかにかかわらず、その後コントロールのUseCompatibleTextRenderingプロパティを設定すれば、その値が有効になります。

Visual Studioのフォームデザイナを使ってコントロールのUseCompatibleTextRenderingプロパティを変更する場合は、注意が必要です。SetCompatibleTextRenderingDefaultメソッドにFalseを渡し、コントロールのUseCompatibleTextRenderingプロパティをTrueにした場合は問題ありません。しかし、逆にSetCompatibleTextRenderingDefaultメソッドにTrueを渡し(もしくはSetCompatibleTextRenderingDefaultメソッドを呼び出さずに)、コントロールのUseCompatibleTextRenderingプロパティをFalseにしたい場合は、フォームデザイナではできません。なぜなら、コントロールのUseCompatibleTextRenderingプロパティをFalseにすると、そのコードはどこにも記述されなくなるからです。この場合は、UseCompatibleTextRenderingプロパティをFalseにするコードを自分で記述する必要があります。

以下の例では、SetCompatibleTextRenderingDefaultメソッドがどのように呼び出されているかにかかわらず、Button1をGDI+で、Button2をGDIで描画するようにしています。

VB.NET
コードを隠すコードを選択
'GDI+を使ってコントロールの文字列が描画されるようにする
Button1.UseCompatibleTextRendering = True
'GDIを使ってコントロールの文字列が描画されるようにする
Button2.UseCompatibleTextRendering = False
C#
コードを隠すコードを選択
//GDI+を使ってコントロールの文字列が描画されるようにする
Button1.UseCompatibleTextRendering = true;
//GDIを使ってコントロールの文字列が描画されるようにする
Button2.UseCompatibleTextRendering = false;

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • .NET Tipsをご利用いただく際は、注意事項をお守りください。