6

コントロールをC#WinFormsでサブクラス化し、OnPaint()ハンドラーでテキストをカスタム描画しています。私のフォームで次のコードを使用して、フォントをCourierNewに設定します。

FontFamily family = new FontFamily("Courier New");
this.myControl.Font = new Font(family, 10);

コントロール自体では、文字列はに格納されておりrealText、次のコードを使用して画面に描画します。

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);

    e.Graphics.DrawString(realText, Font, new SolidBrush(ForeColor), ClientRectangle);
}

ランダムなサンプルテキストの結果は次のようになります:http: //img219.imageshack.us/img219/1778/courier.png

ズームインすると、たとえば、最初の「as」間のスペースが2番目の「as」間のスペースとは異なることがわかります(1ピクセルと2ピクセル)。何がこれを引き起こしているのか、またはどうすればそれが起こらないようにすることができるのか、誰かが知っていますか?異なるフォントで描くと、間隔に似たような奇妙さがたくさんありますが、それらはすべて同じ問題の結果であると思います。

あなたが持っているかもしれないどんな考えにも前もって感謝します。

4

3 に答える 3

6

Graphics.DrawString()の代わりにを使用しているためだと思いますTextRenderer.DrawText()。前者はGDI+を使用してテキストをペイントしますが、これは一種のくだらない時代遅れです。後者は、より最新のGDIを使用します(テキストレンダリングの観点から)。これは、前の回答(WinFormsとWindows)で指摘された違いだと思います。

Graphics.DrawString()また、StringFormatオブジェクトを取得してを指定するオーバーロードを試すこともできますStringFormat.GenericTypographic。ただし、これは実際には問題を回避するためのちょっとしたハックです。.NET 2.0以降を使用している場合は、テキストレンダリングのすべてのニーズに対応するため TextRendererに、安っぽいクラスではなくクラスを使用する必要があります。.NET1.0および1.1との下位互換性のために厳密に存在します。GraphicsGraphics.MeasureString()Graphics.DrawString()

編集:そうそう、あなたのコードはペイントサイクルごとにGDIオブジェクトをリークします。ブラシオブジェクトは、アンマネージリソースのマネージラッパーであるため、明示的に破棄する必要があります。

于 2009-05-08T00:26:57.070 に答える
0

正直に言うと、これまで私には起こりませんでした。ただし、SmoothingModeをアンチエイリアスに設定してみてください。

e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

別のことはさておき、使用からのがDoubleBufferがtrueに設定されていることを確認してください。また、すべてのOnPaint呼び出しで新しいSolidBrushを作成しないようにしてください。

于 2009-05-07T23:55:11.970 に答える
0

WinFormsを使用してサブクラス化されたコントロールにテキストをペイントした私の経験では、使用するテキストレンダリングエンジン(GDI +?)は、Windows独自のフォントエンジンほど良くなく、うまく機能していても確かに異なる結果をもたらします。

私はVisualStudioアドイン(http://entrian.com/source-search)の作成者であり、Visual Studio内でコントロールをペイントする必要があり、フォントをVisual Studioの標準コントロールと同じように見せるために(リストビュー、ツリービューなど)WinFormsをバイパスし、Win32APIを使用してテキストをペイントする必要があります。

[DllImport("gdi32.dll")]
public static extern bool ExtTextOut(IntPtr hdc, int X, int Y,
   uint fuOptions, [In] ref RECT lprc, string lpString, uint cbCount,
   [In] int[] lpDx);

...と家族。

おそらくあなたが聞きたかったものではないでしょうが、それはあります。

于 2009-05-08T00:22:39.530 に答える