Question

J'ai sous-classé un contrôle dans C # WinForms et le texte de dessin personnalisé dans mon gestionnaire OnPaint () . La police est définie sur Courier New à l'aide du code suivant dans mon formulaire:

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

Dans le contrôle même, la chaîne est stockée dans realText et j'utilise le code suivant pour le dessiner à l'écran:

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

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

Le résultat pour un exemple de texte aléatoire est le suivant: http://img219.imageshack.us/img219/1778/courier.png

Si vous effectuez un zoom avant, vous pouvez voir, par exemple, que l’espace entre les premiers "en tant que" est différent de celui entre les seconds "en" (1 pixel contre 2 pixels). Quelqu'un a-t-il une idée de ce qui pourrait causer cela ou de la façon dont je peux empêcher que cela se produise? Il y a beaucoup plus d'étranges similitudes dans l'espacement lorsque je dessine avec des polices différentes, mais je suppose qu'ils résultent tous du même problème.

Merci d'avance pour vos idées.

Était-ce utile?

La solution

Je suppose que c'est parce que vous utilisez Graphics.DrawString () au lieu de TextRenderer.DrawText () . Le premier peint le texte en utilisant GDI +, qui est en quelque sorte misérable et obsolète. Ce dernier utilise GDI qui est plus moderne (en termes de rendu de texte). Je crois que c’est la différence relevée dans la réponse précédente (WinForms et Windows).

Vous pouvez également essayer la surcharge de Graphics.DrawString () qui prend un StringFormat , spécifiez StringFormat.GenericTypographic . Cependant, il s’agit là d’un problème majeur. Si vous utilisez .NET 2.0 ou une version ultérieure, vous devriez utiliser la classe TextRenderer au lieu de la classe Graphics pour tous vos besoins de rendu de texte. Graphics.MeasureString () et Graphics.DrawString () existent uniquement pour la compatibilité ascendante avec .NET 1.0 et 1.1.

edit: Ah oui, et votre code laisse fuir un objet GDI à chaque cycle de peinture. Les objets de pinceau sont des encapsuleurs gérés autour de ressources non gérées. Ils doivent donc être explicitement supprimés.

Autres conseils

Je dois être honnête, mais cela ne m'est jamais arrivé auparavant. Toutefois, essayez de définir SmoothingMode sur Antialiasing:

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

Autre chose à part, assurez-vous que DoubleBuffer a la valeur true pour votre utilisation. Essayez également de ne pas créer un nouveau SolidBrush dans chaque appel OnPaint.

Mon expérience avec la peinture de texte dans des contrôles sous-classés utilisant WinForms est que le moteur de rendu de texte qu’il utilise (GDI +?) n’est pas aussi performant que le moteur de polices de Windows et donne des résultats différents même s’il fonctionne correctement.

Je suis l'auteur d'un complément Visual Studio ( http://entrian.com/source-search ) qui doit peindre les contrôles dans Visual Studio et pour que les polices aient le même aspect que les contrôles standard dans Visual Studio (listviews, arborescences, etc.), je dois contourner WinForms et peindre le texte à l'aide de Win32 API:

[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);

... et la famille.

Probablement pas ce que vous vouliez entendre, mais le voilà.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top