Filterbare Dropdowns

  • Guten Tag,

    ich möchte hier meine Filterbaren Dropdowns vorstellen und gleichzeitig nach Feedback fragen.
    Sie laufen noch nicht ganz flüssig, nur finde ich den Fehler leider nicht.

    Was bringt der Code?
    Über ein Array werden die Werte in die Dropdowns gegeben.
    Diese können dann einfach mit einer Eingabe gefiltert werden.
    Dies geschieht Sofort ab der ersten Eingabe.
    Wenn das Feld wieder geleert wird, dann wird auch der Filter zurückgesetzt.
    Sobald man in eines der Felder schreibt, wird der Dropdown auch Automatisch geöffnet.
    Verlässt man das Feld, schließt sich der Dropdown auch wieder.

    Array im Beispiel:
    Hallo (1.2.3)
    Baum (2.3.4)
    Katze (6.6.6)
    Haus (2.2.3)

    Gibt man z.B. ,,H" ein, so erhält man nur noch die Einträge:
    Hallo (1.2.3)
    Haus (2.2.3)

    Gibt man ein ,,2.3" ein, so erhält man
    Hallo (1.2.3)
    Baum (2.3.4)
    Haus (2.2.3)

    Probleme:
    Ab und zu fügt er beim Filter eigene Zeichen ein.
    Dazu noch wollen sich die Zeichen teilweise nicht löschen lassen.
    Hier weiß ich leider (noch) nicht, wo dran das liegt.


    Es ist auch (noch) keine UDF! Kommt vielleicht später.

    "Der Quellcode"
    [autoit]


    #region ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_Compression=4
    #AutoIt3Wrapper_UseX64=n
    #endregion ;**** Directives created by AutoIt3Wrapper_GUI ****

    [/autoit] [autoit][/autoit] [autoit]

    #region # Includes and Options
    #include-once
    #include <ComboConstants.au3>
    #include <GuiComboBox.au3>
    #include <GuiComboBoxEx.au3>
    #include <GUIConstantsEx.au3>
    #include <WinAPI.au3>
    #include <WindowsConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    ;~ Opt("MustDeclareVars", 1)
    Opt("WinTitleMatchMode", 2) ; Option for the Window find function 1=start, 2=subStr, 3=exact, 4=advanced, -1 to -4=Nocase
    Opt("TCPTimeout", 100)
    #endregion # Includes and Options

    [/autoit] [autoit][/autoit] [autoit]

    #region # GUI
    ; Create the GUI
    $Form1 = GUICreate("Form1", 400, 300, 192, 124)
    ;~ $Form1 = _PMNewGUI($iGUIWidth, $iGUIHeight, $sGUITitle, $sGUITitle, $WS_POPUP, "", "", True) ; $WS_POPUP -> Without Microsoft Windows border

    [/autoit] [autoit][/autoit] [autoit]

    $h_input_1 = _GUICtrlComboBox_Create($Form1, "", 15, 30, 200, 21, $CBS_DROPDOWN)
    $h_input_2 = _GUICtrlComboBox_Create($Form1, "", 15, 60, 200, 21, $CBS_DROPDOWN)
    $h_input_3 = _GUICtrlComboBox_Create($Form1, "", 15, 90, 200, 21, $CBS_DROPDOWN)

    [/autoit] [autoit][/autoit] [autoit]

    ; Set fonts
    $h_GUI_ZielendpunktComboFont = _WinAPI_CreateFont(12, "", "", "", 800, 0, 0, 0, "", "", "", "", "", "")
    _WinAPI_SetFont($h_input_1, $h_GUI_ZielendpunktComboFont, False)
    _WinAPI_SetFont($h_input_2, $h_GUI_ZielendpunktComboFont, False)
    _WinAPI_SetFont($h_input_3, $h_GUI_ZielendpunktComboFont, False)

    [/autoit] [autoit][/autoit] [autoit]

    Local $a_iwas[5] = ["4", "Hallo (1.2.3)", "Baum (2.3.4)", "Katze (6.6.6)", "Haus (2.2.3)"]

    [/autoit] [autoit][/autoit] [autoit]

    _GUICtrlComboBox_BeginUpdate($h_input_1)
    _GUICtrlComboBox_BeginUpdate($h_input_2)
    _GUICtrlComboBox_BeginUpdate($h_input_3)

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $a_iwas[0] Step 1
    _GUICtrlComboBox_AddString($h_input_1, $a_iwas[$i])
    _GUICtrlComboBox_AddString($h_input_2, $a_iwas[$i])
    _GUICtrlComboBox_AddString($h_input_3, $a_iwas[$i])
    Next

    [/autoit] [autoit][/autoit] [autoit]

    _GUICtrlComboBox_EndUpdate($h_input_1)
    _GUICtrlComboBox_EndUpdate($h_input_2)
    _GUICtrlComboBox_EndUpdate($h_input_3)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState(@SW_SHOW)
    #endregion # GUI

    [/autoit] [autoit][/autoit] [autoit]

    #region # programm

    [/autoit] [autoit][/autoit] [autoit]

    ; Register functions
    GUIRegisterMsg($WM_COMMAND, "_Dropdown_Change") ; Filteroption for the Location Dropdowns

    [/autoit] [autoit][/autoit] [autoit]

    Local $wait_loop = 0
    Local $last_code = 0
    Local $last_last_code = 0
    Local $last_last_last_code = 0
    Local $last_hwnd = 0
    Local $last_last_hwnd = 0

    [/autoit] [autoit][/autoit] [autoit]

    While True
    If (($last_hwnd == $last_last_hwnd And (($last_hwnd == $h_input_2 Or $last_hwnd == $h_input_3) Or $last_hwnd == $h_input_1)) Or $wait_loop > 0) Then
    ; $CBN_SETFOCUS = 3
    ; $CBN_SELENDOK = 9
    ; $CBN_CLOSEUP = 8
    ; $CBN_SELENDCANCEL = 10
    ; $CBN_KILLFOCUS = 4
    If ($last_last_last_code == $CBN_SETFOCUS And $last_last_code == $CBN_SELENDOK And $last_code == $CBN_CLOSEUP) Then
    ; Click on the dropdown arrow
    $last_last_last_code = 0
    $last_last_code = 0
    $last_code = 0
    $last_hwnd = 0
    $last_last_hwnd = 0
    If _GUICtrlComboBoxEx_GetDroppedState($h_input_1) = False Then _GUICtrlComboBox_ShowDropDown($last_hwnd, True) ; Focus on Combo 1, open Dropdown
    If _GUICtrlComboBoxEx_GetDroppedState($h_input_2) = False Then _GUICtrlComboBox_ShowDropDown($last_hwnd, True) ; Focus on Combo 1, open Dropdown
    If _GUICtrlComboBoxEx_GetDroppedState($h_input_3) = False Then _GUICtrlComboBox_ShowDropDown($last_hwnd, True) ; Focus on Combo 1, open Dropdown
    ElseIf $last_code == $CBN_SETFOCUS Then
    If $wait_loop == 1 Then
    If _GUICtrlComboBoxEx_GetDroppedState($h_input_1) = False Then _GUICtrlComboBox_ShowDropDown($last_hwnd, True)
    If _GUICtrlComboBoxEx_GetDroppedState($h_input_2) = False Then _GUICtrlComboBox_ShowDropDown($last_hwnd, True)
    If _GUICtrlComboBoxEx_GetDroppedState($h_input_3) = False Then _GUICtrlComboBox_ShowDropDown($last_hwnd, True)
    Else
    $wait_loop = $wait_loop - 1
    EndIf
    EndIf
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit

    [/autoit] [autoit][/autoit] [autoit]

    EndSwitch

    [/autoit] [autoit][/autoit] [autoit]

    Sleep(10)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Exit
    #endregion # programm

    [/autoit] [autoit][/autoit] [autoit]

    #region # functions

    [/autoit] [autoit][/autoit] [autoit]

    Func _Dropdown_Change($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg
    Local $hWndFrom, $iIDFrom, $iCode
    $hWndFrom = $ilParam
    $iIDFrom = BitAND($iwParam, 0xFFFF) ; Low Word
    $iCode = BitShift($iwParam, 16) ; Hi Word

    [/autoit] [autoit][/autoit] [autoit]

    $last_last_last_code = $last_last_code
    $last_last_code = $last_code
    $last_code = $iCode
    $last_last_hwnd = $last_hwnd
    $last_hwnd = $hWndFrom

    [/autoit] [autoit][/autoit] [autoit]

    If $hWndFrom == $h_input_1 And $iCode == $CBN_EDITCHANGE Then _Edit_Changed($h_input_1) ; Edit in Combo 1
    If $hWndFrom == $h_input_1 And $iCode == $CBN_SETFOCUS Then $wait_loop = 3 ; Set wait loop to 3. Use for display the dropdown 1
    If $hWndFrom == $h_input_1 And $iCode == $CBN_KILLFOCUS Then _GUICtrlComboBox_ShowDropDown($h_input_1, False) ; Kill focus on Combo 1, close Dropdown

    [/autoit] [autoit][/autoit] [autoit]

    If $hWndFrom == $h_input_2 And $iCode == $CBN_EDITCHANGE Then _Edit_Changed($h_input_2) ; Edit in Combo 2
    If $hWndFrom == $h_input_2 And $iCode == $CBN_SETFOCUS Then $wait_loop = 3 ; Set wait loop to 3. Use for display the dropdown 2
    If $hWndFrom == $h_input_2 And $iCode == $CBN_KILLFOCUS Then _GUICtrlComboBox_ShowDropDown($h_input_2, False) ; Kill focus on Combo 2, close Dropdown

    [/autoit] [autoit][/autoit] [autoit]

    If $hWndFrom == $h_input_3 And $iCode == $CBN_EDITCHANGE Then _Edit_Changed($h_input_3) ; Edit in Combo 3
    If $hWndFrom == $h_input_3 And $iCode == $CBN_SETFOCUS Then $wait_loop = 3 ; Set wait loop to 3. Use for display the dropdown 3
    If $hWndFrom == $h_input_3 And $iCode == $CBN_KILLFOCUS Then _GUICtrlComboBox_ShowDropDown($h_input_3, False) ; Kill focus on Combo 3, close Dropdown
    EndFunc ;==>_Dropdown_Change

    [/autoit] [autoit][/autoit] [autoit]

    Func _Edit_Changed($ec_handle)
    $edit_input = _GUICtrlComboBox_GetEditText($ec_handle)

    [/autoit] [autoit][/autoit] [autoit]

    ; If Dropdown is closed, then open it
    If _GUICtrlComboBoxEx_GetDroppedState($ec_handle) = False Then
    _GUICtrlComboBox_ShowDropDown($ec_handle, True)
    _GUICtrlComboBox_SetEditText($ec_handle, $edit_input)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    If StringLen($edit_input) >= 3 Then ; Filtering if the String is longer then 3 characters
    Do ; Check if the user enter somethin in the dropdown. Wait until the user is ready.
    Sleep(100)
    $edit_input = _GUICtrlComboBox_GetEditText($ec_handle)
    Until StringTrimRight($edit_input, 1) = StringTrimRight(_GUICtrlComboBox_GetEditText($ec_handle), 1) Or $edit_input = StringTrimRight(_GUICtrlComboBox_GetEditText($ec_handle), 1) Or StringLen(_GUICtrlComboBox_GetEditText($ec_handle)) < 3

    [/autoit] [autoit][/autoit] [autoit]

    ; Reset the content of the dropdown and insert it new
    _GUICtrlComboBox_ResetContent($ec_handle)
    _GUICtrlComboBox_SetEditText($ec_handle, $edit_input)
    For $i = 1 To $a_iwas[0] Step 1
    ; If the search string is in the LocationArray, then add this string to the new dropdown.
    If StringInStr($a_iwas[$i], $edit_input) <> 0 Or $edit_input == "" Then _GUICtrlComboBox_AddString($ec_handle, $a_iwas[$i])
    Next
    Else
    If $edit_input == "" Then
    _GUICtrlComboBox_ResetContent($ec_handle)
    _GUICtrlComboBox_SetEditText($ec_handle, $edit_input)
    For $i = 1 To $a_iwas[0] Step 1
    _GUICtrlComboBox_AddString($ec_handle, $a_iwas[$i])
    Next
    EndIf
    EndIf
    EndFunc ;==>_Edit_Changed

    [/autoit] [autoit][/autoit] [autoit]

    #endregion # functions

    [/autoit]

    Danke schon einmal für Eure Aufmerksamkeit.
    Wenn Ihr Fehler findet, immer her damit.
    Verbesserungsvorschläge sind auch gern gesehen.
    Da kenne ich mich einfach nicht genug mit den Speziellen Funktionen von AutoIT aus ;)