Column limit in multiline text entry

CodeWizrd
CodeWizrd used Ask the Experts™
on

This may seem like an easy question, but it's been a real pain in my tookus.

I have an application, which has on one form, a multi-line text box.  My problem is a little complicated, yet fairly straight forward.

I need to be able to set a limit on how many characters can be on a line (80 characters, for example).  I am already using a fixed font, so the text is uniform in this respect.

I have tried using the RTF control, with it's ability to word-wrap.  The problem I have it that when it DOES a wordwrap, it does not insert a CRLF into the string where that wrap occurs.

I need to, when editing is finished, be able to read through the box and pull out the lines to be written to a target interface.

I need to be able to do this, with a CRLF being injected when the wordwrap occurs.

Do I need a Third Party control?

Also, the fixedsystem font is working well, but I need a smaller fontsize.  Anyone know of a smaller, fixed font?  How difficult is it to distribute and register this additional font with an application?  (Never done that before)

Thanks!

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
VK

Commented:
Hello CodeWizrd !

Suggestion:

1. Your multiline Textbox: txtMultiline
2. Your Label: lblOneLine
    a. lblOneLine.Font = txtMultiline.Font
    b. lblOneLine.Autosize=true
    c. lblOneLine.Visible=false
3. A Varaible tmpLine As String

4. After you begin a new line or begin the first line:
   tmpLine=""

5. txtMultiline_change:
   tmpLine= mid(txtMultiline,LastPosLineFeed+1)
   lblOneLine.Text=tmpLine
   if lblOneLine.width >= txtMultiline.width then
     ....
   end if

You understand ?

v.k.
VK

Commented:
P.S:

Sorry lblOneLine.Text has to be lblOneLine.caption.
But the principle isn't affected.

v.k.

Author

Commented:

Vk,

I thought about trying to track what is happening through the _change() event, but what happens with CUT and PASTE, or if the user inserts text in the middle of existing text?

What I could really use, is something like the ability of knowing exactly what column I was on in the current line (kinda kludgy, but I could write a buncha code to make it work) or that some sort of wordwrap that I would know a line was wordwrapped when I go to save the file.

See, the user has the ability to modify the look and feel, add and delete lines as well as blank lines for spacing and such.  What Im looking for is a way to take EXACTLY what they see on the screen and break it into individual lines.

I can do this right now with a multi-line text box, only I cannot stop the users from going more than "n" columsn, which I need.

HELP?!
Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Commented:
I would recommend using a different control to handle this.  Since each line represents a different entity, they should either be in one control for each line (multiple textboxes) or something like a grid.

If you use the textbox idea, there will obviously be issues with navigation between the lines.

With a grid, you could handle all of the editing through the keydown/up events.  Then, for dataentry, just allow users to enter up to 80 characters in a cell.

There may be additional issues since the MSFlexGrid was not really designed for data input.

The other choice, as mentioned, is to put all checks within the multi-line textbox, but this can be a nightmare if you start allowing user deletions and insertions, especially if done by pasting information.
<I need to, when editing is finished>  How will you know when editing is finished?  I assume that means that when the user presses a button or otherwise indicates that editing is finished.  In any case, you could insert the CRLFs yourself whether it's on the Change event or on a button.

Using the split function you can drop the lines into an array (I just love that split function).  Then cycle through the array one line at a time
If the line is less than 80 characters long, append it to a local string with a VBCRLF on the end.
If the line is > 80 characters, take the first 80 characters, append a vbcrlf, the next 80 append crlf, etc in a looping structure). and append it to your string.  When you are finished, put the local string back into the textbox.

If course this is a lot of overhead for the Change event, so maybe you do it when the user says "Done" by pressing a button.


VK

Commented:
CodeWizrd,

See this. Create a new Project with Form1, Text1(0), Text1(1) and Text1(1).Width remarkable wider than Text1(0).Witdh. Because

Private Function vbNewLineDelimitedStr(ByVal txtBox As TextBox) As String
    Static L As Integer
    Static R As Integer
    Static T As Integer
    Static i As Integer
    Dim Result As String
       
    T = Len(txtBox.Text)
   
    L = 1
   
    For i = 1 To T
        R = 1 + i - L
        lblTemp.Caption = Mid(txtBox.Text, L, R)
        If lblTemp.Width >= txtBox.Width Then
            Result = Result & Mid(txtBox.Text, L, R - 1) & vbNewLine
            L = i
            R = 1 + i - L
            lblTemp.Caption = Mid(txtBox.Text, L, R)
        End If
    Next
   
    If L < i Then
            Result = Result & Mid(txtBox.Text, L)
    End If
    vbNewLineDelimitedStr = Result
   
End Function

Private Sub Form_Load()
    Set lblTemp.Font = Text1(0).Font
    lblTemp.AutoSize = True
    lblTemp.Visible = False
End Sub

Private Sub Text1_Change(Index As Integer)

    Text1(1).Text = vbNewLineDelimitedStr(Text1(0))
End Sub
VK

Commented:
Sorry got the wrong key .. and my browser send it unfinished :-)

.. because Text1_Change(0) is fired even if you insert or remove text with CTRL+ this should work:

v.k.
VK

Commented:
Of Course, i forgot to tell that a label lblTemp has to placed on the form.
Design TextBox.ScrollBars = 2 - Vertical, and Size TextBox.Width just fit 80 char, so TextBox have a autowarp behavior when use input.
when editing is finished, use WarpText(TextBox.Text, 80) function to get a True warped text.

Function WarpText(ByVal text As String, ByVal LineWidth As Long) As String
    Dim saLines() As String
    Dim I As Long
    Dim sLine As String
   
    If text <> vbNullString Then
        saLines = Split(text, vbCrLf)
        For I = 0 To UBound(saLines)
            sLine = saLines(I)
           
            Do
                WarpText = WarpText & Left(sLine, LineWidth) & vbCrLf
                sLine = Mid(sLine, LineWidth + 1)
            Loop While sLine <> vbNullString
        Next
    End If
End Function
Typo
  "behavior when use input"
=>
  "behavior when user input"
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in Community Support that this question is:
- Split points between TigerZhao and VK
Please leave any comments here within the
next seven days.

Author

Commented:

I actually never got my question answered adequately, so I built a user control to do the job for me.  I tried the solutions that were posted, but none of them covered all of the bases.

Im fine with splitting the points, since you guys did try to answer it.  How would I go about doing so?  Dont think I have the option..
CodeWizrd,
If you did not use any of the suggestions here in building your usercontrol, then you are entitled to a full refund of the points.  If you did however, you should let us know whose code you chose.

Author

Commented:
twalgrave,

I subclassed the RTF control, and when wordwrapping occurred, I treated it as if the user hit return, so it put a crlf into the box at that point.  I also kept a reference of the CRLFs that I put in, so if editing caused things to change, I could readjust the CRLFs as needed.

I bundled all of this functionality into a user control for easy usage in my application.

Its kind of messy, but it was the only way to achieve exactly what I needed.
I'd say that a refund is in order.  Post a zero-point question in Community support titled please refund and close, then add the URL to this question into the comment area.  They will decide what to do.

http://www.experts-exchange.com/Programming/Programming_Languages/Visual_Basic/Q_20401260.html
Points refunded and placed in PAQ

Computer101
E-E Admin

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial