VBCE.com - The Premier Website For Visual Basic/CE Developers

 

*Dev Corner

Sample Code
Controls
Workarounds
Tips & Tricks
Q & A
Forums

*Goodies
Downloads
Software
Bookstore


*General
Home
What's New
General Info
Misc. Info


*News Worthy
News
Articles
Editorials
KB Articles
Reviews
Awards

*Miscellaneous
Web Links
Partners
Search
Feedback
Advertising

<% On Error Resume Next SiteStats() %>

Sponsors


More...


Make the Cursor Work in a TextBox
By mike@vbce.com

(Updated May 17, 1998, previous code did not work when text lines were automatically word wrapped.)

    One of the more irritating bugs in VBCE is the bug where the cursor keys don't work in a text box. Not only that, only the KeyUp event fires when one of the cursor keys is pressed, the KeyDown does not. This limits the routines below in that when the cursor key is held down to repeat the keypress, VBCE does not fire multiple KeyUps, as the key has not been let up yet. This means that the user will have to press the key again and again to make the cursor move multiple times.

    To use the 4 routines below (ArrowUp, ArrowDown, ArrowLeft, and ArrowRight) simply place the following code in the TextBox's KeyUp Event.

NOTE: This code below requires the VBCE Misc Utility control to operate.

Private Sub Text1_KeyUp(KeyCode, Shift)
  If Shift = 0 Then
    Select Case KeyCode
      Case 38: ArrowUp Text1
      Case 40: ArrowDown Text1
      Case 37: ArrowLeft Text1
      Case 39: ArrowRight Text1
    End Select
  End If
End Sub

    The Shift is checked because when the Shift Key, Ctrl Key, or Alt Key is also pressed with the cursor key, the cursor will move in the TextBox.

    Next, place the routines below in the form module or if you are using a standard module, you can place them there for better code reuse.

    The reason that we need the VBCE Misc Utility control is that SendMessage is the only way to determine what line we are on and how many charaters the previous or next line has.

Private Sub ArrowUp(TB)
    Dim CurLine
    Dim CharsPriorToLine
    Dim CursorPosOnLine
    Dim PrevLineLen
    Dim CharPos
    Dim CRLFOffSet
   
    On Error Resume Next
    CharPos = VBCEUtil1.SendMessageLong(TB.hWnd, EM_LINEINDEX, -1, 0)
    CurLine = VBCEUtil1.SendMessageLong(TB.hWnd, EM_LINEFROMCHAR, CharPos, 0)
    If CurLine = 0 Then Exit Sub
   
    CharsPriorToLine = VBCEUtil1.SendMessageLong(TB.hWnd, EM_LINEINDEX, CurLine, 0)
    CursorPosOnLine = TB.SelStart - CharsPriorToLine
    PrevLineLen = VBCEUtil1.SendMessageLong(TB.hWnd, EM_LINELENGTH, TB.SelStart - CursorPosOnLine - 2, 0)
   
    If Mid(TB.Text, CharsPriorToLine - 1, 2) = vbCrLf Then CRLFOffSet = 2
   
    If PrevLineLen < CursorPosOnLine Then
        TB.SelStart = CharsPriorToLine - CRLFOffSet
    Else
        TB.SelStart = CharsPriorToLine - (PrevLineLen - CursorPosOnLine) - CRLFOffSet
    End If
End Sub


Private Sub ArrowDown(TB)
    Dim CurLine
    Dim TotalLines
    Dim CharsPriorToLine
    Dim CursorPosOnLine
    Dim NextLineLen
    Dim CharPos
   
    On Error Resume Next
    TotalLines = VBCEUtil1.SendMessageLong(TB.hWnd, EM_GETLINECOUNT, 0, 0)
    CharPos = VBCEUtil1.SendMessageLong(TB.hWnd, EM_LINEINDEX, -1, 0)
    CurLine = VBCEUtil1.SendMessageLong(TB.hWnd, EM_LINEFROMCHAR, CharPos, 0)
   
    If CurLine = (TotalLines - 1) Then Exit Sub
   
    CharsPriorToLine = VBCEUtil1.SendMessageLong(TB.hWnd, EM_LINEINDEX, CurLine, 0)
    CursorPosOnLine = TB.SelStart - CharsPriorToLine
   
    CharsPriorToLine = VBCEUtil1.SendMessageLong(TB.hWnd, EM_LINEINDEX, CurLine + 1, 0)
   
    NextLineLen = VBCEUtil1.SendMessageLong(TB.hWnd, EM_LINELENGTH, CharsPriorToLine, 0)
   
    If CursorPosOnLine <= NextLineLen Then
        TB.SelStart = CharsPriorToLine + CursorPosOnLine
    Else
        TB.SelStart = CharsPriorToLine + NextLineLen
    End If
   
End Sub


Private Sub ArrowLeft(TB)
    Dim CurLine
    Dim CharsPriorToLine
    Dim CharPos


    On Error Resume Next
    If TB.SelStart = 0 Then Exit Sub
   
    CharPos = VBCEUtil1.SendMessageLong(TB.hWnd, EM_LINEINDEX, -1, 0)
    CurLine = VBCEUtil1.SendMessageLong(TB.hWnd, EM_LINEFROMCHAR, CharPos, 0)
    CharsPriorToLine = VBCEUtil1.SendMessageLong(TB.hWnd, EM_LINEINDEX, CurLine, 0)
   
    If TB.SelStart - CharsPriorToLine = 0 Then
        TB.SelStart = CharsPriorToLine - 2
    Else
        TB.SelStart = TB.SelStart - 1
    End If
End Sub


Private Sub ArrowRight(TB)
    Dim CurLine
    Dim TotalLines
    Dim CharsPriorToLine
    Dim CursorPosOnLine
    Dim LineLen
    Dim CharPos
   
    On Error Resume Next
    TotalLines = VBCEUtil1.SendMessageLong(TB.hWnd, EM_GETLINECOUNT, 0, 0)
    CharPos = VBCEUtil1.SendMessageLong(TB.hWnd, EM_LINEINDEX, -1, 0)
    CurLine = VBCEUtil1.SendMessageLong(TB.hWnd, EM_LINEFROMCHAR, CharPos, 0)
   
    If CurLine = (TotalLines - 1) Then
        If TB.SelStart < Len(TB.Text) Then TB.SelStart = TB.SelStart + 1
        Exit Sub
    End If
   
    CharsPriorToLine = VBCEUtil1.SendMessageLong(TB.hWnd, EM_LINEINDEX, CurLine, 0)
    CursorPosOnLine = TB.SelStart - CharsPriorToLine
    If CurLine = 0 Then
        LineLen = VBCEUtil1.SendMessageLong(TB.hWnd, EM_LINELENGTH, 0, 0)
    Else
        LineLen = VBCEUtil1.SendMessageLong(TB.hWnd, EM_LINELENGTH, CharsPriorToLine + 2, 0)
    End If
   
    If CursorPosOnLine < LineLen Then
        TB.SelStart = TB.SelStart + 1
    Else
        TB.SelStart = TB.SelStart + 2
    End If
   
End Sub

bug_word.jpg (1504 bytes)
bug_ant_1.gif (13248 bytes)
workaround.jpg (2931 bytes)

 

“When the bugs get tough,
the tough get coding!”

 



VBCE.com is DevX Winner!

Unless otherwise noted, all information on VBCE.com is Copyright 1998 - 2002
Windows, Windows CE, and Visual Basic are trademarks of the Microsoft Corporation.
VBCE.com is not responsible for content on external sites.
Send all feedback to webmaster@vbce.com
Webmasters - feel free to link to
VBCE.com - Premier Website for Visual Basic/CE Development

Buy Books!