| (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 |
 |
 |
 |
When the bugs get tough,
the tough get coding! |
|