Visual Basic does not intrinsically support automatically moving to the
first matching item as the user enters data. It is possible to add this
by using the SendMessage API call to search the list. The following code
shows a simple example of providing this functionality. To use, start a
new project, add a listbox and a combobox to the form and add this code:
Option Explicit
Private Const LB_FINDSTRING = &H18F
Private Const CB_FINDSTRING = &H14C
Private Const LB_FINDSTRINGEXACT = &H1A2
Private Const CB_FINDSTRINGEXACT = &H158
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 PositionMe(KeyAscii As Integer)
Dim xCtl As Control
Dim strText As String
Dim lngIndex As Long
Dim lngCommand As Long
' find out what type of control we have
Set xCtl = Me.ActiveControl
If xCtl Is Nothing Then Exit Sub
If TypeOf xCtl Is ListBox Then
lngCommand = LB_FINDSTRING ' listbox!
ElseIf TypeOf xCtl Is ComboBox Then
lngCommand = CB_FINDSTRING ' combobox!
Else
Exit Sub
End If
strText = xCtl.Tag ' save search string in TAG
If KeyAscii = 8 Then
' the delete key was pressed so back off 1 character
If Len(strText) Then strText = Left$(strText, Len(strText) - 1)
ElseIf KeyAscii >= 32 And KeyAscii <= 127 Then
' some other key was pressed - add it to string
strText = strText & Chr$(KeyAscii)
End If
xCtl.Tag = strText ' save current search string
If Len(strText) < 1 Then
lngIndex = 0 ' no search necessary
Else
' find first match
lngIndex = SendMessage(xCtl.hwnd, lngCommand, 0, ByVal strText)
End If
If lngIndex < 0 Or lngIndex >= xCtl.ListCount Then
' item not found -- beep and reset search string
Beep
If Len(strText) > 0 Then
xCtl.Tag = Left$(strText, Len(strText) - 1)
End If
Exit Sub
End If
xCtl.ListIndex = lngIndex
End Sub
Private Sub Combo1_KeyPress(KeyAscii As Integer)
PositionMe KeyAscii
KeyAscii = 0
End Sub
Private Sub List1_KeyPress(KeyAscii As Integer)
PositionMe KeyAscii
KeyAscii = 0
End Sub
Private Sub Form_Load()
Dim x As Long
Dim y As Long
For x = 1 To 5
For y = 1 To 5
List1.AddItem Chr$(x + Asc("A")) & Chr$(y + Asc("A")) & "XYZ"
Combo1.AddItem Chr$(x + Asc("A")) & Chr$(y + Asc("A")) & "XYZ"
Next y
Next x
List1.ListIndex = 0
Combo1.ListIndex = 0
End Sub
Private Sub Form_Unload(Cancel As Integer)
Set Form1 = Nothing
End Sub