|
In die Zukunft schauen zu können ist eine feine Sache. Nur ist dies ja in der Regel leider kaum (zuverlässig) möglich. Die TextBox in Visual Basic (und gleichermaßen das Eingabefeld einer ComboBox) geben Ihnen immerhin einen kleinen Ausblick auf die "Zukunft". Sie können mit nur wenigen Zeilen Code ermitteln, wie der Textinhalt nach der Bearbeitung per Tastatur aussehen wird - und zwar jeweils bevor (!) ein Tastendruck von VB verarbeitet und umgesetzt wird. Eine solche Vorausschau ist zwar eigentlich nicht vorgesehen. Doch anhand der Tasten- und Zeichen-Codes, die Ihnen in den Ereignissen KeyDown und KeyPress geliefert werden, können Sie das zu erwartende Ergebnis im Voraus konstruieren.
Beim KeyPress-Ereignis ist das noch am einfachsten. Die SelStart-Eigenschaft liefert Ihnen die Position für das einzufügende Zeichen. Und mit wenigen String-Operationen haben Sie dieses denn auch schon probeweise eingefügt und erhalten so die Vorausschau.
Die folgenden Funktionen rufen Sie im KeyPress-Ereignis einer TextBox bzw. einer ComboBox auf und übergeben das betreffende Steuerelement und den KeyAscii-Wert. Die Funktionen geben den zu erwartenden Text zurück, wenn dieser von der aktuellen Eingabe verändert werden würde. Würde er unverändert bleiben, geben sie einen Nullwert zurück, den Sie mittels der undokumentierten VB-Funktion StrPtr feststellen können. Diese Unterscheidung von einem lediglich leeren String ist notwendig, da eine Eingabe selbst ja auch zu einem leeren String führen könnte.
Public Function TextPreEditKeyPress(Text As TextBox, _
ByVal KeyAscii As Integer) As String
Dim nSelStart As Integer
With Text
Select Case KeyAscii
Case Is >= vbKeySpace
nSelStart = .SelStart
If nSelStart Then
TextPreEditKeyPress = Left$(.Text, nSelStart) _
& Chr$(KeyAscii) & Mid$(.Text, nSelStart + 1 + .SelLength)
Else
TextPreEditKeyPress = Chr$(KeyAscii) _
& Mid$(.Text, nSelStart + 1 + .SelLength)
End If
End Select
End With
End Function
Public Function ComboPreEditKeyPress(Combo As ComboBox, _
ByVal KeyAscii As Integer) As String
Dim nSelStart As Integer
With Combo
Select Case KeyAscii
Case Is >= vbKeySpace
nSelStart = .SelStart
If nSelStart Then
ComboPreEditKeyPress = Left$(.Text, nSelStart) _
& Chr$(KeyAscii) & Mid$(.Text, nSelStart + 1 + .SelLength)
Else
ComboPreEditKeyPress = Chr$(KeyAscii) _
& Mid$(.Text, nSelStart + 1 + .SelLength)
End If
End Select
End With
End Function
Diese beiden Funktionen unterscheiden sich lediglich in ihrer spezifischen Auslegung für eine TextBox bzw. eine ComboBox. Die Aufrufe in den Ereignis-Prozeduren könnten beispielsweise so aussehen:
Private Sub Text1_KeyPress(KeyAscii As Integer)
Dim nText As String
nText = TextPreEditKeyPress(Text1, KeyAscii)
If StrPtr(nText) Then
Debug.Print nText
End If
End Sub
Private Sub Combo1_KeyPress(KeyAscii As Integer)
Dim nText As String
nText = ComboPreEditKeyPress(Combo1, KeyAscii)
If StrPtr(nText) Then
Debug.Print nText
End If
End Sub
Beim KeyDown-Ereignis ist schon etwas mehr Aufwand notwendig. Denn hier können per Tastatur Einfügungen bzw. Löschungen (letzteres ja auch beim Ausschneiden) stattfinden. Der Mehraufwand liegt hier darin, die relevanten Tastenkombinationen herauszufiltern und den zu erwartenden Text entsprechend zusammenzubauen.
Die beiden Hilfsfunktionen hierzu verhalten sich wie die Funktionen für das KeyPress-Ereignis. Statt des KeyAscii-Wertes werden hier nun der KeyCode- und der Shift-Wert aus den Ereignis-Parametern übergeben. Würde der Text unverändert bleiben, geben auch diese Funktionen einen Nullwert zurück.
Public Function ComboPreEditKeyDown(Combo As ComboBox, _
ByVal KeyCode As Integer, ByVal Shift As Integer) As String
Dim nSelStart As Integer
Dim nSelLength As Integer
With Combo
nSelStart = .SelStart
nSelLength = .SelLength
Select Case KeyCode
Case vbKeyDelete
If nSelLength = 0 Then
nSelLength = 1
End If
If nSelStart Then
ComboPreEditKeyDown = Left$(.Text, nSelStart) _
& Mid$(.Text, nSelStart + 1 + nSelLength)
Else
ComboPreEditKeyDown = _
Mid$(.Text, nSelStart + 1 + nSelLength)
End If
Case vbKeyBack
If nSelLength > 0 Then
If nSelStart Then
ComboPreEditKeyDown = Left$(.Text, nSelStart) _
& Mid$(.Text, nSelStart + 1 + nSelLength)
Else
ComboPreEditKeyDown = _
Mid$(.Text, nSelStart + 1 + nSelLength)
End If
Else
If nSelStart > 0 Then
ComboPreEditKeyDown = Left$(.Text, nSelStart - 1) _
& Mid$(.Text, nSelStart + 1)
End If
End If
Case vbKeyX
If Shift = vbCtrlMask Then
If nSelLength = 0 Then
nSelLength = 1
End If
If nSelStart Then
ComboPreEditKeyDown = Left$(.Text, nSelStart) _
& Mid$(.Text, nSelStart + 1 + nSelLength)
Else
ComboPreEditKeyDown = _
Mid$(.Text, nSelStart + 1 + nSelLength)
End If
End If
Case vbKeyV
If Shift = vbCtrlMask Then
If Clipboard.GetFormat(vbCFText) Then
If nSelStart Then
ComboPreEditKeyDown = Left$(.Text, nSelStart) _
& Clipboard.GetText(vbCFText) _
& Mid$(.Text, nSelStart + 1 + nSelLength)
Else
If nSelLength Then
ComboPreEditKeyDown = Clipboard.GetText(vbCFText) _
& Mid$(.Text, nSelStart + nSelLength)
Else
ComboPreEditKeyDown = Clipboard.GetText(vbCFText)
End If
End If
End If
End If
Case vbKeyInsert
If Shift = vbShiftMask Then
If Clipboard.GetFormat(vbCFText) Then
If nSelStart Then
ComboPreEditKeyDown = Left$(.Text, nSelStart) _
& Clipboard.GetText(vbCFText) _
& Mid$(.Text, nSelStart + 1 + nSelLength)
Else
If nSelLength Then
ComboPreEditKeyDown = Clipboard.GetText(vbCFText) _
& Mid$(.Text, nSelStart + nSelLength)
Else
ComboPreEditKeyDown = Clipboard.GetText(vbCFText)
End If
End If
End If
End If
End Select
End With
End Function
Public Function TextPreEditKeyDown(Text As TextBox, _
ByVal KeyCode As Integer, ByVal Shift As Integer) As String
Dim nSelStart As Integer
Dim nSelLength As Integer
With Text
nSelStart = .SelStart
nSelLength = .SelLength
Select Case KeyCode
Case vbKeyDelete
If nSelLength = 0 Then
nSelLength = 1
End If
If nSelStart Then
TextPreEditKeyDown = Left$(.Text, nSelStart) _
& Mid$(.Text, nSelStart + 1 + nSelLength)
Else
TextPreEditKeyDown = _
Mid$(.Text, nSelStart + 1 + nSelLength)
End If
Case vbKeyBack
If nSelLength > 0 Then
If nSelStart Then
TextPreEditKeyDown = Left$(.Text, nSelStart) _
& Mid$(.Text, nSelStart + 1 + nSelLength)
Else
TextPreEditKeyDown = _
Mid$(.Text, nSelStart + 1 + nSelLength)
End If
Else
If nSelStart > 0 Then
TextPreEditKeyDown = Left$(.Text, nSelStart - 1) _
& Mid$(.Text, nSelStart + 1)
End If
End If
Case vbKeyX
If Shift = vbCtrlMask Then
If nSelLength = 0 Then
nSelLength = 1
End If
If nSelStart Then
TextPreEditKeyDown = Left$(.Text, nSelStart) _
& Mid$(.Text, nSelStart + 1 + nSelLength)
Else
TextPreEditKeyDown = _
Mid$(.Text, nSelStart + 1 + nSelLength)
End If
End If
Case vbKeyV
If Shift = vbCtrlMask Then
If Clipboard.GetFormat(vbCFText) Then
If nSelStart Then
TextPreEditKeyDown = Left$(.Text, nSelStart) _
& Clipboard.GetText(vbCFText) _
& Mid$(.Text, nSelStart + 1 + nSelLength)
Else
If nSelLength Then
TextPreEditKeyDown = Clipboard.GetText(vbCFText) _
& Mid$(.Text, nSelStart + nSelLength)
Else
TextPreEditKeyDown = Clipboard.GetText(vbCFText)
End If
End If
End If
End If
Case vbKeyInsert
If Shift = vbShiftMask Then
If Clipboard.GetFormat(vbCFText) Then
If nSelStart Then
TextPreEditKeyDown = Left$(.Text, nSelStart) _
& Clipboard.GetText(vbCFText) _
& Mid$(.Text, nSelStart + 1 + nSelLength)
Else
If nSelLength Then
TextPreEditKeyDown = Clipboard.GetText(vbCFText) _
& Mid$(.Text, nSelStart + nSelLength)
Else
TextPreEditKeyDown = Clipboard.GetText(vbCFText)
End If
End If
End If
End If
End Select
End With
End Function
Und auch hierzu wieder die entsprechenden Aufruf-Beispiele:
Private Sub Text1_KeyDown(KeyCode As Integer, Shift As Integer)
Dim nText As String
nText = TextPreEditKeyDown(Text1, KeyCode, Shift)
If StrPtr(nText) Then
Debug.Print nText
End If
End Sub
Private Sub Combo1_KeyDown(KeyCode As Integer, Shift As Integer)
Dim nText As String
nText = ComboPreEditKeyDown(Combo1, KeyCode, Shift)
If StrPtr(nText) Then
Debug.Print nText
End If
End Sub
Wie Sie die "Zukunft" interpretieren, bleibt Ihnen überlassen. So können Sie etwa den zu erwartenden Text auf Zulässigkeit hin prüfen - und zwar den ganzen Text, und nicht nur ein einzelnes eingegebenes Zeichen. Sie können bei einer ComboBox prüfen, ob der Text einem vorhandenen Eintrag in der Liste entsprechen wird und anderenfalls die Eingabe verwerfen (KeyAscii = 0 bzw. KeyCode = 0 zurückgeben).
|