What's New
Q & A
Tip Jar
C# Helper...
Follow VBHelper on Twitter
MSDN Visual Basic Community
TitleExpand ComboBox choices while typing
KeywordsComboBox, combo, expand, autoexpand
By Paul Noble.

Use API calls to set the ComboBox's list index while avoiding unwanted Click events. This program uses a cComboHelper class. When a ComboBox gets focus, the program attachs one of these objects to it.

Private moCombo As cComboHelper

Private Sub cboFlintstones_GotFocus()
  moCombo.AttachTo cboFlintstones
End Sub

Private Sub cboSimpsons_GotFocus()
  moCombo.AttachTo cboSimpsons
End Sub
The class watches for ComboBox events. When the user presses a key, the program calls the SearchOn subroutine. That routine looks for a matching string and uses the SendMessageByString API function to set the ComboBox's index without raising a new Click event.
Private Sub moCombo_KeyPress(KeyAscii As Integer)

  'Remarks : 1. When the user types something into the text
  ' portion, move to the first
  '             list entry which begins with the displayed
  ' text.
  '          2. Not all keys trigger this event. In
  ' particular -
  '               {Delete}    ... triggers KeyDown but not
  ' KeyPress
  '               {BackSpace} ... triggers KeyPress but not
  ' KeyDown
  '          3. This code was originally in the Change()
  ' event, but confusing
  '             interactions kept occurring (list index was
  ' being set to -1 by Windows)
  Dim sSearchOn As String                                 _
      'current string to search on

  On Error Resume Next

  'These keys can trigger this event, but are of no
  ' interest to us ...
  If KeyAscii = vbKeyReturn Or KeyAscii = vbKeyTab Then
    GoTo Bye_moCombo_KeyPress                             _
        'we don't want to know
  End If

  'So a content-modifying key was entered; decide what to
  ' search on...
  sSearchOn = ResultingText(KeyAscii)
  'Perform the search; if it resulted in a move, cancel the
  ' key input...
  If KeyAscii = vbKeyBack Then                            _
      'prevent re-finding original !
    If SearchOn(sSearchOn, CB_FINDSTRINGEXACT) = True Then _
        KeyAscii = 0
    If SearchOn(sSearchOn, CB_FINDSTRING) = True Then _
        KeyAscii = 0
  End If
  Exit Sub

End Sub

Private Function SearchOn(ByVal sStartText$, ByVal _
    iMatchType%) As Boolean

  'Purpose : Searches the combo and relocates if a match is
  ' found
  'Returns : Whether a move occurred - True or False
  'Remarks :
  Dim mOriginalIndex As Long
  Dim mNewIndex As Long
  Dim yMoveOccurred As Boolean
  On Error Resume Next
  mOriginalIndex = moCombo.ListIndex
  yMoveOccurred = False
  'Determine our start index for searching...
  mOriginalIndex = mOriginalIndex - 1
  If mOriginalIndex < -1 Then mOriginalIndex = -1
  'Perform our search...
  With moCombo
    If Len(sStartText) > 0 Then                           _
        'if it contains any text
      mNewIndex = MatchingRow(sStartText, mOriginalIndex, _
      If mNewIndex <> -1 Then                             _
          'match found
        SendMessageByString .hwnd, CB_SETCURSEL, mNewIndex, _
            0    'set list index
        .SelStart = Len(sStartText)
        .SelLength = Len(.Text) - Len(sStartText)         _
            'select the bit AFTER the match
        yMoveOccurred = True
      End If
    Else                                                  _
        'contains no text
      SendMessageByString .hwnd, CB_SETCURSEL, -1, 0      _
          'set list index to -1
      If mOriginalIndex <> -1 Then yMoveOccurred = True
    End If
  End With
  SearchOn = yMoveOccurred

End Function
Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.