2

The below code block which throws

System.Runtime.InteropServices.ExternalException: 'A generic error occurred in GDI+.

exception when the string passed to draw is too long.

public partial class Form1 : Form
{
    string longString;
    public Form1()
    {
        InitializeComponent();

        for (int i = 0; i < 40000; i++)
            longString += "s";
    }


    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        e.Graphics.DrawString(longString, new Font("Segeo UI", 11, FontStyle.Regular), new SolidBrush(Color.Black), new RectangleF(0, 0, 100, 30),
            new StringFormat()
            {
                LineAlignment = StringAlignment.Center,
                Alignment = StringAlignment.Center,
                Trimming= StringTrimming.None,
                FormatFlags = StringFormatFlags.DirectionRightToLeft
            });
    }
}

How to resolve this exception when drawing long string with the specified format?

James Z
  • 12,209
  • 10
  • 24
  • 44
  • You probably don't have a Font from the `"Segeo UI"` FontFamily. You're also leaking graphics objects all over the place. You may also want to change the string construction in `longString = new string('s', 40000);` – Jimi Aug 03 '20 at 14:51
  • 1
    Looks like a limitation of the LayoutRectangle parameter. Obviously, figure out a way to break up your string into smaller chunks. – LarsTech Aug 03 '20 at 15:06
  • All right. The main problems are: the length of your string, the graphics you leak and setting `StringTrimming.None`, which implies that your string is rendered completely, even though only the section defined by the constraint you've set will be visible. If you set `StringTrimming.Character`, only the section the fits the *BlackBox* is rendered. But, the whole string is measured anyway and if it exceeds the bounds of current DC, GDI+ will complain and you'll probably see the *Red Cross* in the background of your From. – Jimi Aug 03 '20 at 15:46
  • The exception you get is generic, it can be any of the possible factors described. Or the piling up of all of them. If the string is too long, that will raise the exception first, of course. – Jimi Aug 03 '20 at 15:58

1 Answers1

0

I have experienced the same problem. It is not related to the font you are using, the graphics objects being leaked or the StringFormatFlags. It is caused by the length of your string. The exception condition is being triggered by unmanaged code, propagates to the .NET Framework, and ends up in your application. It occurs in both

Graphics.DrawString(...)

and

Graphics.MeasureString(...). 

There are a number of other posts on the web related to this issue. None offer a solution. They suggest that the problem occurs when string length exceeds about 40,000 characters. I can confirm that this problem occurs in my code for a string length just over 44,000 characters.

The solution? In my case I added code to detect "long" strings and truncate them, with appropriate notification to the user. It would seem that this is a Microsoft bug. It may predate .NET and exist in earlier MS native code, or in the COM wrapper MS uses to interop between .NET and their native code.

etcetera
  • 45
  • 3