Jump to content

Dynamic Combobox


Recommended Posts

I need to make a combobox that will adjust the items shown dynamically as the user inputs text. Here is the section of code that I was trying to make work:

$s_vendor = GUICtrlRead($cmb_vendor)    
If $s_vendor = "" OR $s_vendor <> $s_old_vendor Then 
                If $s_vendor <> "" And Not _GUICtrlComboBox_GetDroppedState($cmb_vendor) Then _GUICtrlComboBox_ShowDropDown($cmb_vendor,True)
    If $s_vendor = "" And _GUICtrlComboBox_GetDroppedState($cmb_vendor) Then _GUICtrlComboBox_ShowDropDown($cmb_vendor,False)
    $a_test = _GUICtrlComboBox_GetEditSel($cmb_vendor)
    $a_list_vendor = _TableToArray($s_dbname, "VENDOR", "Vendor", $o_Con)
    $list_vendor = ""
    For $i = 1 to $a_list_vendor[0]
        If StringInStr($a_list_vendor[$i],$s_vendor) AND StringInStr($list_vendor,$a_list_vendor[$i]) = 0 Then $list_vendor = $list_vendor & $a_list_vendor[$i] & "|"
        If $s_vendor = "" Then $list_vendor = $list_vendor & $a_list_vendor[$i] & "|"
    Next
    If StringRight($list_vendor,1) = "|" Then $list_vendor = StringTrimRight($list_vendor,1)
    GUICtrlSetData($cmb_vendor, "")
    GUICtrlSetData($cmb_vendor,$list_vendor)
    Send($s_vendor)
    If IsArray($a_test) Then _GUICtrlComboBox_SetEditSel($cmb_vendor,-1,$a_test[0])
    $s_old_vendor = $s_vendor
EndIf

This was called each time the combobox text changed. It really doesnt work, at least not smoothly like I need it to. Can anyone help me think of a different way to approach this?

Link to comment
Share on other sites

MagnumXL

You should post more of your code for a question like this, but perhaps just as helpful is taking more time to explain what your code is supposed to do.

This looks strange - Send($s_vendor)

And why are you using _GUICtrlComboBox_SetEditSel ?

Das Häschen benutzt Radar

Link to comment
Share on other sites

MagnumXL

You should post more of your code for a question like this, but perhaps just as helpful is taking more time to explain what your code is supposed to do.

This looks strange - Send($s_vendor)

And why are you using _GUICtrlComboBox_SetEditSel ?

Or comment it better perhaps, Right now my code is over 2000 lines not to mention custom UDF's. and I cant post all of it because some of it is sensitive to the company I work for. ^_^

Send($s_vendor) puts the users input back in the combobox after the list updates.

_GUICtrlComboBox_SetEditSel places the cursor back at the position they had it at.

Hope this helps. Thanks for your response Squirrely1

Maybe if someone could just point me in the right direction of how they would go about making a dynamic combobox?

Link to comment
Share on other sites

  • Moderators

MagnumXL,

Perhaps this is close to what you are looking for:

#include <GUIConstantsEx.au3>

$hGUI = GUICreate("Test", 500, 500)

GUICtrlCreateLabel("Enter a new item here", 10, 10)
$hCombo = GUICtrlCreateCombo("", 10, 30, 200, 20)

$hButton = GUICtrlCreateButton("Add", 10, 90, 80, 30)

GUISetState()

$sCombo_List = "|"

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $hButton
            $sCurrent = GUICtrlRead($hCombo)
            If StringinStr($sCombo_List, $sCurrent) = 0 Then
                $sCombo_List &= GUICtrlRead($hCombo) & "|"
                GUICtrlSetData($hCombo, $sCombo_List)
            EndIf
    EndSwitch

WEnd

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

actually no, but you did point out that I need to explain myself more clearly. thanks ^_^

A dynamic combobox would draw from a list of possible items. In my example its an access database hence the _TableToArray() Function. As the user starts typing in the combo box the "list" starts changing only showing items that have the typed text in them. For example:

The combobox data is initially drawn includes the following items "dog|doggy|cat|kittens"

While the combobox is blank its list contains all four items.

As soon as the user inputs a "d" the list changes to only show "dog" and "doggy"

If s/he then backspaces it goes back to all 4 items.

upon inputting just a "k" only the "kitten" is listed.

Pressing enter or left clicking "kitten" inputs the complete word in the combobox entry area.

I hope this makes more sense.

Link to comment
Share on other sites

  • Moderators

MagnumXL,

Although it does not exactly match what you described, I think this "AutoComplete" combobox script is pretty close:

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiComboBox.au3>

Dim $sString = "Hello|world|AutoIt|rules|and|more|some|data"

$hGUI = GUICreate("AutoComplete Combo Demo", 300, 200)

$hCombo = GUICtrlCreateCombo("", 70, 75, 170, 20)
GUICtrlSetData(-1, $sString, "Hello")

GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

GUISetState()

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    Local $iIDFrom = BitAND($wParam, 0x0000FFFF)
    Local $iCode = BitShift($wParam, 16)
    
    Switch $iIDFrom
        Case $hCombo
            Switch $iCode
                Case $CBN_EDITCHANGE
                    _GUICtrlComboBox_AutoComplete($hCombo)
            EndSwitch
    EndSwitch
    
    Return $GUI_RUNDEFMSG
EndFunc  ;==>WM_COMMAND

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Thank you for your sincere effort Melba23. I really appreciate your time. The autocomplete function is a great one for me too keep in mind, but i dont see anyway to modify your posted script to get it to not list the uneeded items. For now I am going to try to "fake" it with seperate input and list boxs.

Link to comment
Share on other sites

  • Moderators

MagnumXL,

This is as close as I can get at the moment. The only problem is that the edit box selects the first matching item as soon as you open the drop-down list. :-(

I will keep at it - but it might be worth opening a new thread to see if one of the real experts can help. ;-)

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <GuiComboBox.au3>
#include <ComboConstants.au3>


$sInitial_Data = "dog|doggy|dodger|kittens"

$aInitial_Array = StringSplit($sInitial_Data, "|")

$hGUI = GUICreate("Test", 500, 500)

$hCombo = GUICtrlCreateCombo("", 10, 30, 200, 20)
GUICtrlSetData(-1, $sInitial_Data)

GUISetState()

Global $sCurrent_ComboText = ""

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
    
    $sActual_ComboText = _GUICtrlComboBox_GetEditText($hCombo)
    If $sActual_ComboText <> $sCurrent_ComboText Then
    
        Local $sCurrent_Data = ""
        For $i = 1 To $aInitial_Array[0]
            If StringInStr($aInitial_Array[$i], $sActual_ComboText) Then
                $sCurrent_Data &= "|" & $aInitial_Array[$i]
            EndIf
        Next
    
        GUICtrlSetData($hCombo, $sCurrent_Data)
        _GUICtrlComboBox_SetEditText($hCombo, $sActual_ComboText)
        
        $sCurrent_ComboText = $sActual_ComboText
        
    EndIf
        
WEnd

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • Moderators

MagnumXL,

I think this is as far as I can get with the concept. There is a readonly combo and an input below it. Entering text in the input changes the contents of the combo. As soon as a selection is made in the combo, the input vanishes and you are returned to the original list in the combo:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <GuiComboBox.au3>
#include <ComboConstants.au3>


$sInitial_Data = "dog|doggy|dodger|dogfish|dogrose|kittens"

$aInitial_Array = StringSplit($sInitial_Data, "|")

$hGUI = GUICreate("Test", 500, 500)

$hCombo = GUICtrlCreateCombo("", 10, 50, 200, 20, $CBS_DROPDOWNLIST)
    GUICtrlSetData(-1, $sInitial_Data)
$hInput = GUICtrlCreateInput("", 10, 70, 200, 20)
    GUICtrlSetState(-1, $GUI_FOCUS)

GUISetState()

Global $sCurrent_InputText = ""
Global $iDropped_State = 0
Global $iFilled_State = 0

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch

    If GUICtrlRead($hCombo) = "" Then
        
        $sActual_InputText = GUICtrlRead($hInput)
        If $sActual_InputText <> $sCurrent_InputText Then
            
            Local $sCurrent_Data = ""
            For $i = 1 To $aInitial_Array[0]
                If StringInStr($aInitial_Array[$i], $sActual_InputText) Then
                    $sCurrent_Data &= "|" & $aInitial_Array[$i]
                EndIf
            Next
        
            GUICtrlSetData($hCombo, $sCurrent_Data)
            
            $sCurrent_InputText = $sActual_InputText
            
        EndIf
        
    Else
        
        If $iFilled_State = 0 And $iDropped_State = 0 Then
            
            $sChosen = GUICtrlRead($hCombo)
            GUICtrlDelete($hInput)
            GUICtrlSetData($hCombo, "|" & $sInitial_Data)
            GUICtrlSetData($hCombo, $sChosen)
            $iFilled_State = 1
        EndIf

    EndIf
    
    If _GUICtrlComboBox_GetDroppedState($hCombo) = True Then
        $iDropped_State = 1
    Else
        If $iDropped_State = 1 Then
            $iDropped_State = 0
            GUICtrlSetState($hInput, $GUI_FOCUS)
            ControlSend($hGUI, "", $hInput, "{END}")
        EndIf
    EndIf
        
WEnd

I hope this helps. It was fun, but ultimately a bit frustrating. :-(

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Perhaps this is easier not to use a Combo. I've seen other examples where the input is just an edit control and a list control is created underneath. This is by no means a completed script but something along these lines might be a more interesting avenue to pursue:

#include <GuiEdit.au3>
#include <GUIListBox.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <GuiConstantsEx.au3>

Opt('MustDeclareVars', 1)

Global $hEdit, $hList = 0, $tRECT, $iHeight
Global $aValid[10] = ["Bruce Wayne", "Bruce Banner", "Brian Damage", "Peter Parker", "Polly Pocket", "Hugh Janus", "Zachary Quack", "Zebedee", "Billy Hunt", "Jackson Pollock"]

_Main()

Exit

Func _Main()
    Local $hGUI = GUICreate("Daisywheel Combo", 512, 512)
    $hEdit = GUICtrlCreateInput("", 8, 8, 496)
    $hList = GUICtrlCreateList("", 8, 32, 496, 24, $LBS_SORT + $WS_VSCROLL)
    GUICtrlSetOnEvent($hList, "_OnListClick")
    GUICtrlSetState($hList, $GUI_HIDE)
    GUISetState()
    
    $tRECT = _WinAPI_GetWindowRect(GUICtrlGetHandle($hEdit))
    $iHeight = DllStructGetData($tRECT, "Bottom") - DllStructGetData($tRECT, "Top")

    GUIRegisterMsg($WM_COMMAND, "_OnMessage")

    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    GUIDelete()
EndFunc   ;==>_Main

Func _OnMessage($hWnd, $iMsg, $wParam, $lParam)
    Local $hWndFrom = $lParam, $iIDFrom = _WinAPI_LoWord($wParam), $iCode = _WinAPI_HiWord($wParam)
    Switch $iMsg
        Case $WM_COMMAND
            Switch $hWndFrom
                Case GUICtrlGetHandle($hEdit)
                    Switch $iCode
                        Case $EN_CHANGE
                            _ShowList()
                    EndSwitch
                Case GUICtrlGetHandle($hList)
                    Switch $iCode
                        Case $LBN_SELCHANGE
                            _OnListClick()
                        Case $LBN_DBLCLK, $LBN_KILLFOCUS
                            GUICtrlSetState($hList, $GUI_HIDE)
                            If $iCode = $LBN_DBLCLK Then GUICtrlSetState($hEdit, $GUI_FOCUS)
                    EndSwitch
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>_OnMessage

Func _ShowList()
    Local $sText = GUICtrlRead($hEdit), $i, $j = 0, $sContents = ""
    If $sText <> "" Then
        For $i = 0 To 9
            If StringRegExp($aValid[$i], "^" & $sText & ".*") Then
                $sContents &= "|" & $aValid[$i]
                $j += 1
            EndIf
        Next
    EndIf
    If $sContents <> "" Then
        ConsoleWrite($j & " " & $iHeight * $j & @CRLF)
        GUICtrlSetPos($hList, 8, 8 + $iHeight, 496, $iHeight * $j)
        GUICtrlSetData($hList, $sContents)
        GUICtrlSetState($hList, $GUI_SHOW)
    Else
        GUICtrlSetState($hList, $GUI_HIDE)
    EndIf
EndFunc   ;==>_ShowList

Func _OnListClick()
    ConsoleWrite(GUICtrlRead($hList) & @CRLF)
    GUICtrlSetData($hEdit, GUICtrlRead($hList))
EndFunc   ;==>_OnListClick

WBD

Link to comment
Share on other sites

Wow for once I asked a question that didn't have a simple (as in I feel like a retard) answer!

@M23 Thanks for putting some time into this. We both came up with essentially the same thing. Still I got some good pointers from your script. Thank you!

@WBD That is what I have been working on, seems to be going much better! But I see that you are doing alot of different stuff in your script. Thats a great thing, thank you!

@nicky40 awesome, can't wait to see it! Thank you!

Link to comment
Share on other sites

  • Moderators

MagnumXL,

My take on the Input/List combo (if you will pardon the pun!):

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <WinAPI.au3>

$sInitial_Data = "dog|doggy|dodger|dogfish|dogrose|kittens"

$aInitial_Array = StringSplit($sInitial_Data, "|")

$hGUI = GUICreate("Test", 500, 500)

$hInput = GUICtrlCreateInput("", 10, 20, 200, 20)
    GUICtrlSetState(-1, $GUI_FOCUS)
$hInput_Wnd = ControlGetHandle ($hGUI, "", $hInput)

$hList = GUICtrlCreateList("", 10, 40, 200, 170)
    GUICtrlSetData(-1, $sInitial_Data)

GUISetState()

Global $sCurrent_InputText = ""
Global $iChosen_State = 0

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch

    If GUICtrlRead($hList) = "" Then
        
        $sActual_InputText = GUICtrlRead($hInput)
        If $sActual_InputText <> $sCurrent_InputText Then
            
            
            $iChosen_State = 0
            
            Local $sCurrent_Data = ""
            For $i = 1 To $aInitial_Array[0]
                If StringInStr($aInitial_Array[$i], $sActual_InputText) Then
                    $sCurrent_Data &= "|" & $aInitial_Array[$i]
                EndIf
            Next
            
            If $sCurrent_Data = "" Then $sCurrent_Data = "|" & $sInitial_Data
        
            GUICtrlSetData($hList, $sCurrent_Data)
            $sCurrent_InputText = $sActual_InputText
            
        EndIf
        
        If _WinAPI_GetFocus() <> $hInput_Wnd Then
            GUICtrlSetState($hInput, $GUI_FOCUS)
            ControlSend($hGUI, "", $hInput, "{END}")
        EndIf

    Else
        
        If $iChosen_State = 0 Then
            GUICtrlSetData($hInput, GUICtrlRead($hList))
            $sCurrent_InputText = GUICtrlRead($hList)
            GUICtrlSetData($hList, "|" & $sInitial_Data)
            GUICtrlSetState($hInput, $GUI_FOCUS)
            ControlSend($hGUI, "", $hInput, "{END}")
            $iChosen_State = 1
        EndIf
        
    EndIf
    
WEnd

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...