• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 418
  • Last Modified:

Insert sentences at curser location richtextbox

Hi experts
Heres what i have:
A list of sentences in RTB
A combo box that add sentences to end of RTB written like this:
With myrtf1
.SelStart = Len(myrtf1.Text)    
.SelText = vbCrLf & Combo1.List(i)
This works good so far
I want to modify this to give a user the option of adding sentences to the middle of the list of sentences based on the curser
location. If the user  places the curser at the end of a sentence the above with statement will work leaving out the
 .selstart This creates a new line and inserts the text into the new line. This is fine also.
Heres where i need help:
If the user creates a blank line by pressing enter at the end of an existing line then i need to be able to insert the combo
text into this  blank line. How can this be accomplished?
Thank you
  • 4
  • 2
  • 2
2 Solutions
Couldn't you just leave out the carriage return line feed?

.SelText = Combo1.List(i)
isnoend2001Author Commented:
Yes , but if the curser is at the end of an existing line it will be added to the end of that line.
isnoend2001Author Commented:
I guess what i need is to be able to tell if the curser is on a blank line with text on the line below and the line above.
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

How about setting a boolean after an enter key.

' in declarations area
Dim LastKey As Boolean

Private Sub Command1_Click()

With RichTextBox1

    Select Case LastKey
        Case True
            .SelText = Combo1.List(i)
            .SelStart = .SelStart + Len(Combo1.List(i))
        Case Else
            .SelText = vbCrLf & Combo1.List(i)
            .SelStart = .SelStart + Len(Combo1.List(i))
    End Select
End With

End Sub

Private Sub RichTextBox1_KeyPress(KeyAscii As Integer)
If KeyAscii = vbKeyReturn Then
    LastKey = True
    LastKey = False
End If
End Sub
isnoend2001Author Commented:
Thanks vinnyd79
I tested that and can add lastkey=false at the end of case true if they move to the end of the list.
Still testing,like if they delete a line without pressing enter
Robberbaron (robr)Commented:
If cursor is at the beginning of a new blank line, then there should be a crlf before the current position and a crlf after.

this seems to work for me  ( i used text1 to test)

With myRTF1

'about to enter text
If Len(.Text) > 0 Then
      If Mid(.Text, .SelStart - 1, 2) = vbCrLf And Mid(.Text, .SelStart + 1, 2) = vbCrLf Then
         'on a blank line
        'insert text
        .SelText = Text1.Text
        'add to end      'or search for next crlf
     .SelStart = Len(myRTF1.Text)
     .SelText = vbCrLf & Text1.Text
    End If
   'RTF is empty so add to end
     .SelStart = Len(myRTF1.Text)
     .SelText = vbCrLf & Text1.Text
End If
End With
Robberbaron (robr)Commented:
 'search for crlf
  for i=.selstart to len(myRTF1.text)
     if Mid(.Text, .SelStart + 1, 2) = vbcrlf then
          'have found end of sentance          'works for adding to end but slow....
          .selstart = i
          .seltext = vbcrlf & Text1.txt
          exit for
    end if
 next i
isnoend2001Author Commented:
Thanks guys both your solutations work, but i have decided to use some code i found at Planet.
 Not just for this 1 problem i have yet to code 5 more rtb's and this function seems to make coding a rtb easier;
Heres the code

In a module
Public Declare Function SendMessage Lib _
    "user32" Alias "SendMessageA" _
    (ByVal hwnd As Long, _
     ByVal wMsg As Long, _
     ByVal wParam As Long, _
     lParam As Any) As Long
Public Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
    End Type
    Public Const SB_VERT = 1

Public Const EM_GETRECT = &HB2
Public Const EM_GETSEL = &HB0
Public Const EM_LINEINDEX = &HBB
Public Const EM_LINELENGTH = &HC1
Public Const EM_SCROLLCARET = &HB7
Public Const EM_UNDO = &HC7
Public Const EM_GETLINE = &HC4

Public Enum RichInfo
RichVisibleLines = 1
RichFirstVisibleLine = 2
RichCurrentLineNo = 3
RichCursorPosition = 4
RichCurrentLineFirstChar = 5
RichCurrentLineLength = 6
RichLineCount = 7
RichLineText = 8
End Enum
Public Function visiblelinescount(incontrol As RichTextBox)
    Dim FirstVisibleLine As Long
    Dim r As RECT
    Dim numberOfLines As Long
    Dim numberOfVisibleLines As Long
    Dim rectHeight As Long
    Dim lineHeight As Long

    FirstVisibleLine = SendMessage(incontrol.hwnd, EM_GETFIRSTVISIBLELINE, 0, 0)
        numberOfLines = SendMessage(incontrol.hwnd, EM_GETLINECOUNT, 0, 0)
        SendMessage incontrol.hwnd, EM_GETRECT, 0, r
        rectHeight = r.Bottom - r.Top
        lineHeight = incontrol.Parent.TextHeight("W") / Screen.TwipsPerPixelY
        numberOfVisibleLines = rectHeight / lineHeight
        If numberOfVisibleLines > numberOfLines Then
        numberOfVisibleLines = numberOfLines
        End If

    visiblelinescount = numberOfVisibleLines - 1
End Function

Public Function GetRichData(Rich As RichTextBox, Getdata As RichInfo)

Dim FirstVisibleLine As Long
Dim VislibleLines As Long
Dim CurrentLine As Long
Dim CursorPos As Long
Dim nLine As Long
Dim FirstChar As Long
Dim RowLength As Long
Dim Buffer() As Byte
Dim LineText As String
Dim Lines() As String
Dim numberOfLines As Long

VisibleLines = visiblelinescount(Rich)
FirstVisibleLine = SendMessage(Rich.hwnd, EM_GETFIRSTVISIBLELINE, 0, 0)
CursorPos = SendMessage(Rich.hwnd, EM_GETSEL, 0, ByVal 0&) \ 65536
nLine = SendMessage(Rich.hwnd, EM_LINEFROMCHAR, CursorPos, ByVal 0&)
FirstChar = SendMessage(Rich.hwnd, EM_LINEINDEX, nLine, ByVal 0&)
RowLength = SendMessage(Rich.hwnd, EM_LINELENGTH, FirstChar, ByVal 0&)
numberOfLines = SendMessage(Rich.hwnd, EM_GETLINECOUNT, 0, 0)

ReDim Buffer(RowLength + 1)
Buffer(0) = RowLength + 1

SendMessage Rich.hwnd, EM_GETLINE, nLine, Buffer(0)
LineText = Left$(StrConv(Buffer, vbUnicode), RowLength)

Select Case Getdata

Case 1
GetRichData = VisibleLines
Case 2
GetRichData = FirstVisibleLine
Case 3
GetRichData = nLine
Case 4
GetRichData = CursorPos
Case 5
GetRichData = FirstChar
Case 6
GetRichData = RowLength
Case 7
GetRichData = numberOfLines
Case 8
GetRichData = LineText
Case Else
GetRichData = "This should not happen!! Try Again!!"
End Select

End Function

I call it like this:
lineFirstChar = GetRichData(myrtf1, RichCurrentLineFirstChar)
LineLength = GetRichData(myrtf1, RichCurrentLineLength)

If LineLength = 0 Then
         .SelStart = lineFirstChar
         .SelText = Combo1.List(i)

Can you guys see anything wrong with this?
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

  • 4
  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now