VB-Tec.de Visual Basic - Technik, FAQ, Tricks, BeispieleHome / Objekte / Controls / Fokus Nächstes Control in Tab-Reihenfolge finden |
In manchen Situationen ist es notwendig, das nächste Control in der Tab-Reihenfolge zu finden, z.B. wenn bei Druck auf Return auf das nächste Eingabefeld gesprungen werden soll. Oft wird in so einem Fall SendKeys benutzt, um ein Druck auf die Tabulator-Taste zu generieren, etwa so:
Private Sub txtEingabe_KeyPress(KeyAscii As Integer)
If KeyAscii = vbKeyReturn Then SendKeys "{Tab}"
End Sub
Dies hat jedoch einige Nachteile, z.B. wird u.U. der Status der Num-Taste geändert.
Mit den unten gezeigten Routinen ist es möglich, das Control zu bestimmen, welches als nächstes den Fokus erhalten soll. Dann reicht es im obigen Beispiel folgendes zu schreiben:
Private Sub txtEingabe_KeyPress(KeyAscii As Integer) If KeyAscii = vbKeyReturn Then JumpNextControl End Sub
Stört ein nervender Piepton oder soll der Tastendruck für das gesamte Formular gelten? Dann empfehle ich unbedingt folgenden Artikel: Bei Enter: Aktion statt Beep!
Die erste Funktion gibt für ein Control an, ob es überhaupt den Fokus via Tabulator erhalten kann. Dazu muss er u.a. sichtbar (Visible) und aktivierbar (Enabled) sein. Ausserdem darf er kein Container sein (wird via Error-Handler und ClipControls-Eigenschaft festgestellt):
Public Function IsFocusable( _
ByRef ctl As Control _
) As Boolean
On Error Resume Next
'Auf Fokussierbarkeit prüfen:
If Not ctl.TabStop Then Exit Function
If Not ctl.Visible Then Exit Function
If Not ctl.Enabled Then Exit Function
'Nur nicht-Container berücksichtigen:
If ctl.ClipControls <> ctl.ClipControls _
Then IsFocusable = True
On Error GoTo 0
End Function
Die folgende Funktion benutzt IsFocusable, um das nächste Control in der Tab-Reihenfolge zu finden. Es wird dabei genau das Control auf dem Formular frm gesucht, dessen TabIndex größer als TabMin ist, aber kleiner als alle anderen:
Public Function FindNextControl( _
ByRef frm As Form, _
ByVal TabMin As Long _
) As Control
Dim ctl As Control
Dim TabMax As Long
TabMax = 32767 'Maximaler TabIndex
For Each ctl In frm.Controls
With ctl
'Control auf Eignung als Kandidat prüfen:
If IsFocusable(ctl) Then
'TabIndex des Kandidaten checken:
Select Case .TabIndex
Case TabMin To TabMax
'Kandidat merken:
Set FindNextControl = ctl
TabMax = .TabIndex
End Select
End If 'IsFocusable(ctl)
End With 'ctl
Next ctl
End Function
Die eigentliche Haupt-Routine kann mit einem optionalen Parameter aufgerufen werden, der entweder das Formular oder Steuerelement angibt, wo die Suche gestartet werden soll. Wird ActiveObject nicht angegeben, so wird automatisch das aktuelle Control des aktuellen Formulars verwendet.
Public Sub JumpNextControl( _
Optional ByRef ActiveObject As Object _
)
Dim frm As Form
Dim ctl As Control
Dim ctlFokus As Control
'Aktuelles Control bestimmen:
If ActiveObject Is Nothing Then
Set frm = Screen.ActiveForm
Set ctl = frm.ActiveControl
ElseIf TypeOf ActiveObject Is Form Then
Set frm = ActiveObject
Set ctl = frm.ActiveControl
ElseIf TypeOf ActiveObject Is Control Then
Set ctl = ActiveObject
Set frm = ctl.Parent
Else
Err.Raise 5 'Invalid procedure call or argument
End If
'Nächst größeren TabIndex suchen:
Set ctlFokus = FindNextControl(frm, ctl.TabIndex + 1)
'Ggf. kleinsten TabIndex suchen:
If ctlFokus Is Nothing _
Then Set ctlFokus = FindNextControl(frm, 0)
'Bei Erfolg Fokus setzen:
If Not ctlFokus Is Nothing _
Then ctlFokus.SetFocus
End Sub
Man beachte, dass erst nach dem Control mit dem nächst größeren TabIndex gesucht wird. Falls kein solches Control existiert, wird der kleinste gültige TabIndex berücksichtigt. Das entsprechende Control erhält dann ggf. den Fokus.
© Jost Schwider, 19.03.2001-19.03.2001 - http://vb-tec.de/ctltab.htm