11

I have a Winforms app containing a RichTextBox.

How can I determine how many lines of text are displayed, currently visible?

Reason: I want to scroll the caret to the middle of the RichTextBox. I can use RichTextBox.ScrollToCaret(), but that puts the caret at the top of the RichTextBox. I figure, If I know how many lines are displayed, I could move the caret "back" n/2 lines, then call ScrollToCaret(), then restore the original caret position.

EDIT:

I found EM_GETLINECOUNT, which I thought was the answer, except the doc says: The EM_GETLINECOUNT message retrieves the total number of text lines, not just the number of lines that are currently visible.

Tantalizingly, there is also EM_GETFIRSTVISIBLELINE, which gets the first visible line, but I couldn't find a GETLASTVISIBLELINE. ??


Related:
How can I scroll the caret to the middle of the RichTextBox?

Community
  • 1
  • 1
Cheeso
  • 189,189
  • 101
  • 473
  • 713
  • Just interested - what are you going to do with this information? You do realise that this could be variable, because you can have different fonts and padding throughout the text. – Mark Bertenshaw Nov 20 '09 at 22:43
  • It went into building a custom RTB that displays line numbers: http://stackoverflow.com/questions/2567263/how-to-show-number-of-a-line-in-a-richtextbox-c/2668264#2668264 – Cheeso Apr 20 '10 at 14:32

2 Answers2

17

Well, this isn't pretty, but it works for me. Basically I'm checking a point just inside the upper-left corner of the richtextbox and a point just inside the lower left corner of the textbox. You may have to adjust the point coordinates depending on how your richtextbox is displayed. Then I get the character index that is closest to each of those two points, and retrieve the line that it is on.

Dim topIndex As Integer = RichTextBox1.GetCharIndexFromPosition(New Point(1, 1))
Dim bottomIndex As Integer = RichTextBox1.GetCharIndexFromPosition(New Point(1, RichTextBox1.Height - 1))

Dim topLine As Integer = RichTextBox1.GetLineFromCharIndex(topIndex)
Dim bottomLine As Integer = RichTextBox1.GetLineFromCharIndex(bottomIndex)

Dim numLinesDisplayed As Integer = bottomLine - topLine

I tested it for richtextboxes with multiple sizes of fonts displayed, and it seems to work. I suspect that the answer that is returned will be off (too small) by one line if the last line of displayed text has a lot of white space under it and the next line is almost ready to be displayed. If you have a very tall richtextbox, with many lines, this shouldn't be a problem.

Alex Essilfie
  • 12,339
  • 9
  • 70
  • 108
Stewbob
  • 16,759
  • 9
  • 63
  • 107
2

To display the number of lines that a RichTextBox is capable of displaying, even if there is no text there currently, try:

Dim s As SizeF = TextRenderer.MeasureText("A", rtb.Font, rtb.Size, TextFormatFlags.WordBreak)
Dim letterHeight As Integer = CInt(s.Height)
Dim displayableLines As Integer = rtb.Height / letterHeight

This uses the height of a test letter 'A' in the current font to find the line height in pixels.

Tim Makins
  • 394
  • 4
  • 12