What's New
Q & A
Tip Jar
C# Helper...
Follow VBHelper on Twitter
MSDN Visual Basic Community
TitleExpand ComboBox choices while typing, version 2
DescriptionThis example shows how to expand ComboBox choices while typing in Visual Basic 6.
KeywordsComboBox, combo, expand, autoexpand
CategoriesControls, API
This is based on a version by Paul Noble.

The program associates a ComboBox with an instance of the ComboExpander class. This object's Initialize method saves a WithEvents reference to the ComboBox it is watching.

The ProcessKey method takes a key that the user pressed and uses subroutine NewComboText to figure out what the ComboBox's new text will be. It then uses SendMessage to find a match in the list. If the user pressed backspace or delete, it sends the CB_FINDSTRINGEXACT message so the match must be exact. If the user pressed another key, it sends the CB_FINDSTRING message so it finds the first match in the ComboBox. The routine then selects the matched item if it found one.

' The ComboBox we are expanding.
Private WithEvents m_ComboBox As ComboBox

' Prepare to expand the ComboBox.
Public Sub Initialize(ByVal cbo As ComboBox)
    Set m_ComboBox = cbo
End Sub

' The user typed this key.
Private Sub ProcessKey(ByRef key_code As Integer)
Dim new_text As String
Dim row_found As Long

    ' See what the ComboBox's new text will be.
    new_text = NewComboText(key_code)

    ' Find the first row that matches this string.
    ' See if the character is Backspace or Delete.
    If key_code = vbKeyBack Or key_code = vbKeyDelete Then
        ' This is Backspace or Delete.
        ' Require an exact match.
        row_found = SendMessageString(m_ComboBox.hwnd, _
            CB_FINDSTRINGEXACT, 0, new_text)
        ' This is not Backspace or Delete.
        ' Require any match.
        row_found = SendMessageString(m_ComboBox.hwnd, _
            CB_FINDSTRING, 0, new_text)
    End If

    ' See if we found a row.
    If row_found <> -1 Then
        ' We found a row. Select the row.
        SendMessage m_ComboBox.hwnd, _
            CB_SETCURSEL, row_found, ByVal 0&

        ' Select the text.
        m_ComboBox.SelStart = Len(new_text)
        m_ComboBox.SelLength = Len(m_ComboBox.Text) - _

        ' Cancel the input character so the ComboBox
        ' doesn't try to use it.
        key_code = 0
    End If
End Sub
' Determine the text's new value based on the
' currently selected text and the character pressed.
Private Function NewComboText(ByVal key_asc As Integer) As _
Dim txt_left As String
Dim txt_selected As String
Dim txt_right As String
Dim result As String

    ' Get the pieces of the ComboBox's text.
    txt_left = Left$(m_ComboBox.Text, m_ComboBox.SelStart)
    txt_selected = Mid$(m_ComboBox.Text, _
        m_ComboBox.SelStart + 1, m_ComboBox.SelLength)
    txt_right = Mid$(m_ComboBox.Text, m_ComboBox.SelStart + _
        m_ComboBox.SelLength + 1)

    ' Take action based on the character.
    Select Case key_asc
        Case vbKeyBack  ' Backspace.
            ' See if any text is selected.
            If Len(txt_selected) > 0 Then
                ' Text is selected. Delete it.
                result = txt_left & txt_right
                ' No text is selected.
                ' Delete one character to the left.
                If Len(txt_left) > 0 Then
                    txt_left = Left$(txt_left, _
                        Len(txt_left) - 1)
                End If
                result = txt_left & txt_right
            End If

        Case vbKeyDelete    ' Delete.
            ' See if any text is selected.
            If Len(txt_selected) > 0 Then
                ' Text is selected. Delete it.
                result = txt_left & txt_right
                ' No text is selected.
                ' Delete one character to the right.
                txt_right = Mid$(txt_right, 2)
                result = txt_left & txt_right
            End If

        Case Else           ' Some other character.
            ' Replace the selected text with the character.
            result = txt_left & Chr$(key_asc) & txt_right
    End Select

    NewComboText = result
End Function

' Watch for the Delete key.
Private Sub m_ComboBox_KeyDown(KeyCode As Integer, Shift As _
    ' If it's a Delete key, process it.
    If KeyCode = vbKeyDelete Then ProcessKey KeyCode
End Sub

' Process printing keys and Backspace.
Private Sub m_ComboBox_KeyPress(KeyAscii As Integer)
Const ASC_SPACE As Integer = 32
Const ASC_TILDE As Integer = 126

    ' Ignore the key if it is non-printing
    ' and not Backspace.
    If (KeyAscii < ASC_SPACE Or KeyAscii > ASC_TILDE) _
        And KeyAscii <> vbKeyBack _
        ' The key is non-printing and not Backspace.
        Exit Sub
    End If

    ' Process the key.
    ProcessKey KeyAscii
End Sub
Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.