Solved

row/col positions in textbox?

Posted on 2001-08-17
11
400 Views
Last Modified: 2012-06-27
I need to display the row and column position of the cursor(caret) with a textbox or richtext box as the user moves(with the arrow keys) around within it. Also when the user places the cursor on a row I need to display that positon as well.

I am using VB.net beta 2, but a solution in VB6 will suffice.

Thank you
0
Comment
Question by:msdnman
11 Comments
 
LVL 75

Expert Comment

by:Anthony Perkins
ID: 6398400
Private Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Private Function GetCurrCol(hWnd As Long, ByVal Line As Long) As Long
Const EM_LINEINDEX = &HBB

' Zero based
GetCurrCol = SendMessageLong(hWnd, EM_LINEINDEX, Line, 0&)

End Function

Private Sub UpdatePos()
Dim CurrLine As Long
Dim CurrCol As Long

CurrLine = RichTextBox1.GetLineFromChar(RichTextBox1.SelStart)
CurrCol = RichTextBox1.SelStart - GetCurrCol(RichTextox1.hWnd, CurrLine) + 1
   
Debug.Print "Line " & CStr(CurrLine)
Debug.Print "Col " & CStr(CurrCol)

End Sub
0
 

Author Comment

by:msdnman
ID: 6398508
There is no equivelent, that I can find, to SelStart in the .net RichTextBox control. That said, a VB 6 example will not lead me in the right direction.

How is this done in VB.net or C#?
0
 
LVL 6

Expert Comment

by:sharmon
ID: 6398548
This is not a .Net solution, but something I was playing with after reading your question.  It may help you or give you some ideas.  If you have any questions let me know.


Option Explicit

Private Const EM_GETSEL = &HB0

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 Sub Text1_KeyUp(KeyCode As Integer, Shift As Integer)
    TestRowCol
End Sub

Private Sub Text1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    TestRowCol
End Sub

Private Sub TestRowCol()
    'Assume you have three textboxes
    'Text1 - Where the user types
    'txtRow - Return for the row information
    'txtCol - Return for the column information
    '
    Dim l As Long
    Dim lngEnd As Long
    Dim lngRow As Long
    Dim lngCol As Long
    Dim lngPosLastCrLf As Long

    lngRow = 1

    Call SendMessage(Text1.hwnd, EM_GETSEL, 0&, lngEnd)

    For l = 1 To lngEnd
        If Asc(Mid(Text1.Text, l, 1)) = Asc(vbCrLf) Then
            lngRow = lngRow + 1
            lngPosLastCrLf = l
        End If
    Next l

    lngCol = (lngEnd - lngPosLastCrLf)
    If lngRow = 1 Then lngCol = lngCol + 1

    txtRow.Text = lngRow
    txtCol.Text = lngCol
End Sub
0
 
LVL 28

Expert Comment

by:iboutchkine
ID: 6398597
' Form1
' To obtain cursor positions (expressed in terms of characters) in textbox

Option Explicit

Private Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" _
  (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Private Const EM_GETSEL = &HB0
Private Const EM_SETSEL = &HB1
Private Const EM_GETLINECOUNT = &HBA
Private Const EM_LINEINDEX = &HBB
Private Const EM_LINELENGTH = &HC1
Private Const EM_LINEFROMCHAR = &HC9
   


Private Sub command1_Click()
    Dim lineCount As Long
    Dim currLinePos As Long
    Dim overallCursorPos As Long
    Dim chrsBeforeCurrLine As Long
    Dim CurrLineCursorPos As Long
    Dim currLineLen As Long
   
    On Local Error Resume Next
   
     'total number of lines in the text box
    lineCount = SendMessageLong(Text1.hwnd, EM_GETLINECOUNT, 0, 0&)
    Label2.Caption = "No.of lines count (inc blank line if any) = " & CStr(lineCount)
   
     'cursor position in the text box
    overallCursorPos = SendMessageLong(Text1.hwnd, EM_GETSEL, 0, 0&) \ &H10000
    Label3.Caption = "Overall cursor pos (incl CR and LF if any) = " & CStr(overallCursorPos + 1)
   
    'current line pos (Note: zero-based)
    currLinePos = SendMessageLong(Text1.hwnd, EM_LINEFROMCHAR, overallCursorPos, 0&)
    Label4.Caption = "Current line = " & CStr(currLinePos + 1)
   
     'number of chrs upto but before start of the current line
    chrsBeforeCurrLine = SendMessageLong(Text1.hwnd, EM_LINEINDEX, currLinePos, 0&)
    Label5.Caption = "Chars before current line (incl CR and LF if any) = " & CStr(chrsBeforeCurrLine)

     'cursor position in terms of current line only (Note: zero-based)
    CurrLineCursorPos = overallCursorPos - chrsBeforeCurrLine
    Label6.Caption = "Char pos in current line = " & CStr(CurrLineCursorPos + 1)
   
    'number of characters in current line (Note: with EM_LINELENGTH, the value of the "wParam"
    'parameter specifies the char index of a char in the line. If this parameter is -1, the
    'function returns number of unselected characters on line. "lParam" not used and set to 0).
    currLineLen = SendMessageLong(Text1.hwnd, EM_LINELENGTH, -1, 0&)
    Label7.Caption = "No. of unselected chars in current line = " & CStr(currLineLen)
   
    Text1.SetFocus
End Sub

0
 

Author Comment

by:msdnman
ID: 6398746
Neither of the solutions seem to work in .net. It appears that the messages may have changed for the .net controls. If I can find the messages that they can accept I should be able to get one of the examples working.

Any idea where I can find them?

Thanks for your continued help!!!
0
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:msdnman
ID: 6398803
Neither of the solutions seem to work in .net. It appears that the messages may have changed for the .net controls. If I can find the messages that they can accept I should be able to get one of the examples working.

Any idea where I can find them?

Thanks for your continued help!!!
0
 
LVL 14

Expert Comment

by:wsh2
ID: 6399442
<ping>.. listening
0
 
LVL 3

Expert Comment

by:andysalih
ID: 6399776
not sure if this will work in vb.net,worth a try though

Public Declare Function SendMessageLong Lib "USER32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Public Const EM_GETSEL As Long = &HB0
    Public Const EM_SETSEL As Long = &HB1
    Public Const EM_GETLINECOUNT As Long = &HBA
    Public Const EM_LINEINDEX As Long = &HBB
    Public Const EM_LINELENGTH As Long = &HC1
    Public Const EM_LINEFROMCHAR As Long = &HC9
    Public Const EM_SCROLLCARET As Long = &HB7
    Public Const WM_SETREDRAW As Long = &HB

'**************************************
' Name: text object line info
' Description:The first function returns
'     usefull information about text box objec
'     ts. these include :
[Line count] = 0
[Cursor Position] = 1
[Current Line Number] = 2
[Current Line Start] = 3
[Current Line End] = 4
[Current Line Length] = 5
[Current Line Cursor Position] = 6
[Line Start] = 7
[Line End] = 8
[Line Length] = 9
The next function returns the text of a given line of a text box object.
' By: Damien McGivern
'
'
' Inputs:Public Enum LineInfo
[Line count] = 0
[Cursor Position] = 1
[Current Line Number] = 2
[Current Line Start] = 3
[Current Line End] = 4
[Current Line Length] = 5
[Current Line Cursor Position] = 6
[Line Start] = 7
[Line End] = 8
[Line Length] = 9
End Enum


Public Function getLineInfo(txtObj As Object, info As LineInfo, Optional lineNumber As Long) As Long


Public Function GetLineText(txtObj As Object, lineNumber As Long) As String
    '// If lineNumber = 0 then current line'
Option Explicit


Public Declare Function SendMessageLong Lib "USER32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Public Const EM_GETSEL As Long = &HB0
    Public Const EM_SETSEL As Long = &HB1
    Public Const EM_GETLINECOUNT As Long = &HBA
    Public Const EM_LINEINDEX As Long = &HBB
    Public Const EM_LINELENGTH As Long = &HC1
    Public Const EM_LINEFROMCHAR As Long = &HC9
    Public Const EM_SCROLLCARET As Long = &HB7
    Public Const WM_SETREDRAW As Long = &HB


Public Enum LineInfo
    [Line count] = 0
    [Cursor Position] = 1
    [Current Line Number] = 2
    [Current Line Start] = 3
    [Current Line End] = 4
    [Current Line Length] = 5
    [Current Line Cursor Position] = 6
    [Line Start] = 7
    [Line End] = 8
    [Line Length] = 9
End Enum


Public Function getLineInfo(txtObj As Object, info As LineInfo, Optional lineNumber As Long) As Long
    Dim cursorPoint As Long
    '//Record where the cursor is
    cursorPoint = txtObj.SelStart


    Select Case info
        Case Is = 0 ' = "lineCount"
        getLineInfo = SendMessageLong(txtObj.hWnd, EM_GETLINECOUNT, 0, 0&)
        Case Is = 1 ' = "cursorPosition"
        getLineInfo = (SendMessageLong(txtObj.hWnd, EM_GETSEL, 0, 0&) \ &H10000) + 1
        Case Is = 2 ' = "currentLineNumber"
        getLineInfo = (SendMessageLong(txtObj.hWnd, EM_LINEFROMCHAR, -1, 0&)) + 1
        Case Is = 3 ' = "currentLineStart"
        getLineInfo = SendMessageLong(txtObj.hWnd, EM_LINEINDEX, -1, 0&) + 1
        Case Is = 4 ' = "currentLineEnd"
        getLineInfo = SendMessageLong(txtObj.hWnd, EM_LINEINDEX, -1, 0&) + 1 + SendMessageLong(txtObj.hWnd, EM_LINELENGTH, -1, 0&)
        Case Is = 5 ' = "currentLineLength"
        getLineInfo = SendMessageLong(txtObj.hWnd, EM_LINELENGTH, -1, 0&)
        Case Is = 6 ' = "currentLineCursorPosition"
        getLineInfo = (SendMessageLong(txtObj.hWnd, EM_GETSEL, 0, 0&) \ &H10000) + 1 - SendMessageLong(txtObj.hWnd, EM_LINEINDEX, getLineInfo(txtObj, [Current Line Number]) - 1, 0&)
        Case Is = 7 ' = "lineStart"
        getLineInfo = (SendMessageLong(txtObj.hWnd, EM_LINEINDEX, (lineNumber - 1), 0&)) + 1
        Case Is = 8 ' = "lineEnd"
        getLineInfo = SendMessageLong(txtObj.hWnd, EM_LINEINDEX, (lineNumber - 1), 0&) + 1 + SendMessageLong(txtObj.hWnd, EM_LINELENGTH, (lineNumber - 1), 0&)
        Case Is = 9 ' = "lineLength"
        getLineInfo = (SendMessageLong(txtObj.hWnd, EM_LINEINDEX, lineNumber, 0&)) + 1 - (SendMessageLong(txtObj.hWnd, EM_LINEINDEX, (lineNumber - 1), 0&)) - 3
    End Select
End Function


Public Function GetLineText(txtObj As Object, lineNumber As Long) As String
    '// If lineNumber = 0 then current line'
    '     s text is given
    If lineNumber = 0 Then lineNumber = getLineInfo(txtObj, [Current Line Number])
    '// Select text
    Call SendMessageLong(txtObj.hWnd, EM_SETSEL, ((getLineInfo(txtObj, [Line Start], lineNumber)) - 1), ((getLineInfo(txtObj, [Line Start], lineNumber + 1)) - 1))
    GetLineText = txtObj.SelText
End Function


hope it helps
Andy
0
 

Author Comment

by:msdnman
ID: 6432613
Anyone have a .net solution for me??
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7202368
Hi msdnman,
It appears that you have forgotten this question. I will ask Community Support to close it unless you finalize it within 7 days. I will ask a Community Support Moderator to:

    Refund points and save as a 0-pt PAQ.

msdnman, Please DO NOT accept this comment as an answer.
EXPERTS: Post a comment if you are certain that an expert deserves credit.  Explain why.
==========
DanRollins -- EE database cleanup volunteer
0
 
LVL 5

Accepted Solution

by:
Netminder earned 0 total points
ID: 7216014
Per recommendation, points refunded and question closed.

Netminder
CS Moderator
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Introduction I needed to skip over some file processing within a For...Next loop in some old production code and wished that VB (classic) had a statement that would drop down to the end of the current iteration, bypassing the statements that were c…
When designing a form there are several BorderStyles to choose from, all of which can be classified as either 'Fixed' or 'Sizable' and I'd guess that 'Fixed Single' or one of the other fixed types is the most popular choice. I assume it's the most p…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
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…

760 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

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now