?
Solved

current line and column in textbox

Posted on 2003-03-26
14
Medium Priority
?
346 Views
Last Modified: 2012-06-21
In my form, I have a multi-line textbox. I also have a status bar at the bottom. In the status bar, I want to display the current line and column that the blinking cursor is at in the textbox. I was trying to use txtTextBox.SelStart to find the location of the blinking cursor, but that just gives you the character number for the whole textbox. Anyone know how to do something like this?
0
Comment
Question by:vitanza
  • 6
  • 5
  • 3
14 Comments
 
LVL 11

Expert Comment

by:supunr
ID: 8214039
how about using a richtextbox instead.  Add "Microsoft Rich Texbox Control 6.0"

The richtextbox has a property called "GetLineFromChar" which you could use to get the line number.

e.g.

Private Sub RichTextBox1_Change()
    Dim RowNum as long
    Dim ColNum as long
    Dim i as long

    with RichTextbox1
        RowNum = .GetLineFromChar(.SelStart)

        for i = .SelStart to 1 Step -1
            if (.GetLineFromChar(i) < RowNum) then
               exit for
            end if
        next i
        ColNum = .SelStart - i
    end with
 
End Sub

' To get the row number in a textbox, it is bit of work. let me give you example for that as well....

Good Luck!
0
 
LVL 11

Expert Comment

by:supunr
ID: 8214078
Private Sub Text1_Change()
   Dim RowNum as long
   Dim ColNum as long
   Dim i as long
   Dim PrevCol as long

   with Text1
       RowNum = 0
       i = InStrRev(.Text, vbcrlf, .SelStart)
       PrevCol = i
       do while i > 0
           RowNum = RowNum + 1
           i = InStrRev(.Text, vbcrlf, i - 1)
       loop

       ColNum = .SelStart - PrevCol
   end with

End Sub
0
 
LVL 11

Expert Comment

by:supunr
ID: 8214150
actually correct the last code to...

Private Sub Text1_Change()
  Dim RowNum As Long
  Dim ColNum As Long
  Dim i As Long
  Dim PrevCol As Long

  With Text1
      RowNum = 0
      If (.SelStart <= 1) Then
        i = InStrRev(.Text, vbCrLf, 1)
      Else
        i = InStrRev(.Text, vbCrLf, .SelStart - 1)
      End If
      PrevCol = i
      Do While i > 0
          RowNum = RowNum + 1
          i = InStrRev(.Text, vbCrLf, i - 1)
      Loop

      ColNum = .SelStart - PrevCol
  End With
  Me.RichTextBox1.Text = RowNum & " : " & ColNum

End Sub
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 3

Accepted Solution

by:
emadat earned 150 total points
ID: 8214454
Declare the following:
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Const EM_LINEFROMCHAR = &HC9


and use this function:

Public Function GetLineNumber(txt As TextBox) As Long
    GetLineNumber = SendMessage(txt.hwnd, EM_LINEFROMCHAR, txt.SelStart, 0&)
End Function


It will return the line number (zero based)

Regards
0
 
LVL 3

Expert Comment

by:emadat
ID: 8214501
The other function:

Public Function GetCharNumber(txt As TextBox) As Long
Dim CharPos%
    CharPos = txt.SelStart - InStrRev(txt, vbCrLf, txt.SelStart)
End Function

Please note that the cursor have to be in the text box prior to calling the function or you will get an error

You can add error handling into both the functions.

Regards
0
 
LVL 3

Expert Comment

by:emadat
ID: 8214509
Sorry here is the correct function

Public Function GetCharNumber(txt As TextBox) As Long
   GetCharNumber = txt.SelStart - InStrRev(txt, vbCrLf, txt.SelStart)
End Function
0
 

Author Comment

by:vitanza
ID: 8215658
OK, I right-clicked on the Toolbox and clicked Components, but the "Microsoft Rich Textbox Control 6.0" is not in my list of controls. For some reason, I remember it being there before, though... Any clue as to why it's not listed or what DLL it's in?

Also, emadat, those functions work, but not really. Here is my code: (txtFile is my multi-line textbox)

Private Sub txtFile_KeyDown(KeyCode As Integer, Shift As Integer)
    Dim lineNum, charNum
    lineNum = GetLineNumber()
    charNum = GetCharNumber()
    StatusBar1.Panels.Item(1).Text = "Line " & lineNum & ", Char " & charNum
End Sub

I have the same code in the txtFile_Click() procedure. The status bar usually displays correctly, but sometimes it doesn't display right away; sometimes you have to press an arrow key twice for the status bar text to change.
0
 
LVL 3

Expert Comment

by:emadat
ID: 8218264
The call to each function have to take the text box name as a parameter. If your textbix name is MyTextBox then your function should look like:

Private Sub txtFile_KeyDown(KeyCode As Integer, Shift As Integer)
   Dim lineNum, charNum
   lineNum = GetLineNumber(MyTextBox)
   charNum = GetCharNumber(MyTextBox)
   StatusBar1.Panels.Item(1).Text = "Line " & lineNum & ", Char " & charNum
End Sub

However; as I mentioned; the cursor have to be in the text box. so try this function:

Private Sub txtFile_KeyDown(KeyCode As Integer, Shift As Integer)
Dim lineNum, charNum
   MyTextBox.SetFocus
   lineNum = GetLineNumber(MyTextBox)
   charNum = GetCharNumber(MyTextBox)
   StatusBar1.Panels.Item(1).Text = "Line " & lineNum & ", Char " & charNum
End Sub


Regards
0
 

Author Comment

by:vitanza
ID: 8219811
I forgot to mention that I modified the functions GetLineNumber and GetCharNumber so that it uses txtFile automatically:

Public Function GetLineNumber() As Long
    On Error Resume Next
    GetLineNumber = SendMessage(txtFile.hwnd, EM_LINEFROMCHAR, txtFile.SelStart, 0&)
End Function

Public Function GetCharNumber() As Long
    On Error Resume Next
    GetCharNumber = txtFile.SelStart - InStrRev(txtFile, vbCrLf, txtFile.SelStart)
End Function
0
 
LVL 3

Expert Comment

by:emadat
ID: 8219944
What is the problem with this code?
0
 

Author Comment

by:vitanza
ID: 8220371
Private Sub txtFile_KeyDown(KeyCode As Integer, Shift As Integer)
   Dim lineNum, charNum
   lineNum = GetLineNumber()
   charNum = GetCharNumber()
   StatusBar1.Panels.Item(1).Text = "Line " & lineNum & ", Char " & charNum
End Sub

I have the same code in the txtFile_Click() procedure. The status bar sometimes displays correctly, but sometimes it doesn't display right away; sometimes you have to press an arrow key twice for the status bar text to change. Also, it seems like it's always one character off.
0
 
LVL 3

Expert Comment

by:emadat
ID: 8220444
If it is ALWAYS one character away; then add 1 to the result of the function.

For the other problem; issue a refresh after updating the statusbar
0
 

Author Comment

by:vitanza
ID: 8220703
Thanks, but I want to capture the < and > keys. How should I do this? Should I use MyControl_KeyPress() instead?
0
 

Author Comment

by:vitanza
ID: 8220710
Sorry, that comment was supposed to be for a different question :)
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction While answering a recent question (http://www.experts-exchange.com/Q_27402310.html) in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
Suggested Courses

621 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question