0

I'm using custom drawing to draw a string in a WinForms application. The classic Graphics.DrawString method is used for that:

g.DrawString(text, font, brush, rect, stringFormat);

The output string text can be clipped by the rectangle rect, and I need to count the number of characters fully visible in rect. How to do that using the .NET Framework built-in tools?

Please, don't suggest using other methods to output text. I need to solve this task for GDI+ Graphics.DrawString.


UPDATE: Yes, sure, I can use Graphics.MeasureString in a loop in which I sum the width of every character from the beginning of the string, but I need something more efficient like the DT_MODIFYSTRING flag in the WinAPI DrawText function.

Add to this that Graphics.MeasureString does not calculate the required width properly. Fore more info, see this article:

http://www.codeproject.com/Articles/2118/Bypass-Graphics-MeasureString-limitations

TecMan
  • 2,743
  • 2
  • 30
  • 64
  • Are you familiar with Graphics.MeasureString? https://msdn.microsoft.com/en-us/library/6xe5hazb(v=vs.110).aspx – Biscuits Dec 08 '15 at 17:40
  • @Biscuits, are you familiar with the problems related to Graphics.MeasureString? See, for instance, [this](http://www.codeproject.com/Articles/2118/Bypass-Graphics-MeasureString-limitations). It seems, we need to use [StringFormat.SetMeasurableCharacterRanges](https://msdn.microsoft.com/en-us/library/system.drawing.stringformat.setmeasurablecharacterranges(v=vs.110).aspx) for more precise calculations. – TecMan Dec 09 '15 at 08:25

1 Answers1

-1

You are going to have to loop, character by character, through the string, measuring each one using Graphics.MeasureString until it goes beyond the rectangle, then back off by one character.

It becomes more complex if it's a multi-line textbox, because then you have to figure out proper word breaks. You may end up backing off multiple characters if you break on whole words.

Bradley Uffner
  • 16,641
  • 3
  • 39
  • 76
  • 5
    You could do that. Or use the MeasureString overload that has the *charactersFitted* argument, that's a lot easier. No point in mentioning textbox btw, it doesn't use DrawString. – Hans Passant Dec 08 '15 at 18:09
  • 1
    Well sure, if you want to do it the easy way... (I wasn't aware of that overload, thanks!) – Bradley Uffner Dec 08 '15 at 18:11
  • This is not efficient. I've updated my question, read the UPDATE section. – TecMan Dec 09 '15 at 08:33
  • @HansPassant, it seems, the overloaded version of [MeasureString with charactersFitted](https://msdn.microsoft.com/en-us/library/957webty(v=vs.110).aspx) could be the answer to my question - though the calculation is still not "quite correct" as MeasureString adds some extra pixels to the result. What can you say about using StringFormat.SetMeasurableCharacterRanges in a loop? Is it a precise solution? – TecMan Dec 09 '15 at 08:39