Answer updated because the proposed method doesn't work. The '
why' of it not working is explained here for reference.
The
RichTextBox
control has two properties of interest,
.Text
and
.Rtf
.
I created a test document with two paragraphs of
Lorem Ipsum and an image in-between.
The
.Length
of the
.Text
property is 1231 characters.
The
.Length
of the
.Rtf
property is 525,357 characters.
The
.Rtf
property includes everything, all the escape codes and the image itself in
hex
format.
The
.Text
property includes only the two paragraphs of text and a about 2-3 characters which must be some kind of placeholder for the image.
The following code uses the
GetCharIndexFromPosition
method of the
RichTextBox
control, the value returned (for my test document) ranges from 0 to 1230. You will notice that 1230 is very similar to the
.Length
property of the
RichTextBox.Text
control property. I.e.
GetCharIndexFromPosition
is giving a position within the text represented by the
.Text
property (or some very similar property).
Private Sub RichTextBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles RichTextBox1.MouseMove
Dim position As Integer = RichTextBox1.GetCharIndexFromPosition(e.Location)
The code we use to find the location of the images in the document is shown further below. It uses the
.Rtf
property as we can see in this example :
Dim currentImageStart As Integer = RichTextBox1.Rtf.IndexOf(startTag, 0)
However, and here's the problem, analysing the
.Rtf
property gives a start and end position (in my test document) of 924 and 525,357 respectively whereas
GetCharIndexFromPosition
gives values of 597 and 598 whilst hovering the mouse over different parts of the image.
Hence checking to see if 597 or 598 are in the range 924 to 525,357 is never going to work.
Here's the full method to get the
start,end
position pairs for all images in the doucement using
"{\pict"
to define where the image starts (
please do not throw exceptions the way I have, this was just to thrown together to find out what was going on) :
Private imageLocations As List(Of Tuple(Of Integer, Integer))
Private Function FindImageLocations() As Boolean
imageLocations.Clear()
Dim startTag As String = "{\pict"
Dim openBrace As Char = "{"c
Dim closeBrace As Char = "}"c
Dim braceCount As Integer
Dim currentPosition As Integer
Dim nextOpenBrace As Integer
Dim nextCloseBrace As Integer
Dim currentImageStart As Integer = RichTextBox1.Rtf.IndexOf(startTag, 0)
If currentImageStart = -1 Then Return False
While currentImageStart <> -1
braceCount = 1
currentPosition = currentImageStart + startTag.Length
While braceCount <> 0
nextOpenBrace = RichTextBox1.Rtf.IndexOf(openBrace, currentPosition)
nextCloseBrace = RichTextBox1.Rtf.IndexOf(closeBrace, currentPosition)
If nextOpenBrace <> -1 Then
currentPosition = Math.Min(nextOpenBrace, nextCloseBrace)
Else
currentPosition = nextCloseBrace
End If
If RichTextBox1.Rtf.Chars(currentPosition) = openBrace Then
braceCount += 1
ElseIf RichTextBox1.Rtf.Chars(currentPosition) = closeBrace Then
braceCount -= 1
Else
Throw New Exception("Unexpected error")
End If
currentPosition += 1
End While
imageLocations.Add(Tuple.Create(currentImageStart, currentPosition))
ToolStripStatusLabel2.Text = "Start, " & currentImageStart.ToString()
ToolStripStatusLabel3.Text = "End, " & currentPosition.ToString()
currentImageStart = RichTextBox1.Rtf.IndexOf(startTag, currentPosition)
End While
Return True
End Function