msdnman
asked on
row/col positions in textbox?
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
I am using VB.net beta 2, but a solution in VB6 will suffice.
Thank you
ASKER
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#?
How is this done in VB.net or C#?
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
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
' 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
' 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
Label2.Caption = "No.of lines count (inc blank line if any) = " & CStr(lineCount)
'cursor position in the text box
overallCursorPos = SendMessageLong(Text1.hwnd
Label3.Caption = "Overall cursor pos (incl CR and LF if any) = " & CStr(overallCursorPos + 1)
'current line pos (Note: zero-based)
currLinePos = SendMessageLong(Text1.hwnd
Label4.Caption = "Current line = " & CStr(currLinePos + 1)
'number of chrs upto but before start of the current line
chrsBeforeCurrLine = SendMessageLong(Text1.hwnd
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
Label7.Caption = "No. of unselected chars in current line = " & CStr(currLineLen)
Text1.SetFocus
End Sub
ASKER
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!!!
Any idea where I can find them?
Thanks for your continued help!!!
ASKER
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!!!
Any idea where I can find them?
Thanks for your continued help!!!
<ping>.. listening
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.hWn d, EM_GETLINECOUNT, 0, 0&)
Case Is = 1 ' = "cursorPosition"
getLineInfo = (SendMessageLong(txtObj.hW nd, EM_GETSEL, 0, 0&) \ &H10000) + 1
Case Is = 2 ' = "currentLineNumber"
getLineInfo = (SendMessageLong(txtObj.hW nd, EM_LINEFROMCHAR, -1, 0&)) + 1
Case Is = 3 ' = "currentLineStart"
getLineInfo = SendMessageLong(txtObj.hWn d, EM_LINEINDEX, -1, 0&) + 1
Case Is = 4 ' = "currentLineEnd"
getLineInfo = SendMessageLong(txtObj.hWn d, EM_LINEINDEX, -1, 0&) + 1 + SendMessageLong(txtObj.hWn d, EM_LINELENGTH, -1, 0&)
Case Is = 5 ' = "currentLineLength"
getLineInfo = SendMessageLong(txtObj.hWn d, EM_LINELENGTH, -1, 0&)
Case Is = 6 ' = "currentLineCursorPosition "
getLineInfo = (SendMessageLong(txtObj.hW nd, EM_GETSEL, 0, 0&) \ &H10000) + 1 - SendMessageLong(txtObj.hWn d, EM_LINEINDEX, getLineInfo(txtObj, [Current Line Number]) - 1, 0&)
Case Is = 7 ' = "lineStart"
getLineInfo = (SendMessageLong(txtObj.hW nd, EM_LINEINDEX, (lineNumber - 1), 0&)) + 1
Case Is = 8 ' = "lineEnd"
getLineInfo = SendMessageLong(txtObj.hWn d, EM_LINEINDEX, (lineNumber - 1), 0&) + 1 + SendMessageLong(txtObj.hWn d, EM_LINELENGTH, (lineNumber - 1), 0&)
Case Is = 9 ' = "lineLength"
getLineInfo = (SendMessageLong(txtObj.hW nd, EM_LINEINDEX, lineNumber, 0&)) + 1 - (SendMessageLong(txtObj.hW nd, 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.hWn d, EM_SETSEL, ((getLineInfo(txtObj, [Line Start], lineNumber)) - 1), ((getLineInfo(txtObj, [Line Start], lineNumber + 1)) - 1))
GetLineText = txtObj.SelText
End Function
hope it helps
Andy
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.hWn
Case Is = 1 ' = "cursorPosition"
getLineInfo = (SendMessageLong(txtObj.hW
Case Is = 2 ' = "currentLineNumber"
getLineInfo = (SendMessageLong(txtObj.hW
Case Is = 3 ' = "currentLineStart"
getLineInfo = SendMessageLong(txtObj.hWn
Case Is = 4 ' = "currentLineEnd"
getLineInfo = SendMessageLong(txtObj.hWn
Case Is = 5 ' = "currentLineLength"
getLineInfo = SendMessageLong(txtObj.hWn
Case Is = 6 ' = "currentLineCursorPosition
getLineInfo = (SendMessageLong(txtObj.hW
Case Is = 7 ' = "lineStart"
getLineInfo = (SendMessageLong(txtObj.hW
Case Is = 8 ' = "lineEnd"
getLineInfo = SendMessageLong(txtObj.hWn
Case Is = 9 ' = "lineLength"
getLineInfo = (SendMessageLong(txtObj.hW
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.hWn
GetLineText = txtObj.SelText
End Function
hope it helps
Andy
ASKER
Anyone have a .net solution for me??
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
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
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.GetLineFromCh
CurrCol = RichTextBox1.SelStart - GetCurrCol(RichTextox1.hWn
Debug.Print "Line " & CStr(CurrLine)
Debug.Print "Col " & CStr(CurrCol)
End Sub