A combo box is a dropdown selector. Each item can carry a hidden tag (a stable key) alongside its display text, and the control raises events when the list is opened and when the selection changes.
![A colour combo box with Green selected, showing 'Picked idx=2 text=[Green] tag=[G]'.](images/combobox-demo.png)
Verified by execution on KCML 06.00.88 (KClient direct mode).
.Add(text$, tag$) in Enter().SetSelection(0).Click() event (selection changed) and DropDown() event (list opened).GetTag$(.Index).01000 REM test_combobox - single combobox with tagged items
: DIM result, msg$80, tag$10
01010 - DEFFORM ComboTest()=\
{.form,.form$,.Style=0x50c000c4,.Width=300,.Height=160,.Text$="Combo Test",.Id=1024},\
{.lblInfo,.static$,.Style=0x50000000,.Left=10,.Top=10,.Width=280,.Height=10,.Text$="Pick a colour from the list.",.Id=2000,.Font=.SegoeCtl},\
{.cboColour,.combobox$,.Style=0x50210003,.Left=10,.Top=25,.Width=160,.Height=120,.Id=2001,.Font=.SegoeCtl},\
{.lblPicked,.static$,.Style=0x50000000,.Left=10,.Top=50,.Width=280,.Height=10,.Text$="(nothing picked yet)",.Id=2002,.Font=.SegoeCtl},\
{.btnClose,.button$,.Style=0x50010001,.Left=210,.Top=115,.Width=80,.Height=14,.Text$="Close",.Id=1,.Font=.SegoeCtl},\
{.paneStatus,.status$,.Width=300,.Style=0x50000000,.Text$="Ready"},\
{.SegoeCtl,.dlgfont$,.Name$="Segoe UI",.Size=10}
: + DEFEVENT ComboTest.Enter()
: .cboColour.Add("Red","R")
: .cboColour.Add("Green","G")
: .cboColour.Add("Blue","B")
: .cboColour.Add("Yellow","Y")
: .cboColour.SetSelection(0)
: END EVENT
: + DEFEVENT ComboTest.cboColour.Click()
: tag$ = RTRIM(.cboColour.GetTag$(.cboColour.Index))
: .lblPicked.Text$ = $PRINTF("Picked idx=%d text=[%s] tag=[%s]", .cboColour.Index, RTRIM(.cboColour.Text$), tag$)
: END EVENT
: + DEFEVENT ComboTest.cboColour.DropDown()
: .paneStatus.Text$ = "cboColour.DropDown fired"
: END EVENT
: FORM END ComboTest
01020 result = ComboTest.Open()
: $END
Tags vs text. .Add("Green", "G") shows Green but stores G. After a
selection, GetTag$(.Index) returns the tag — branch your logic on that stable
key, not the (possibly translated) display text.
Mind the index base — it is asymmetric. This is the single most common combo-box trap, verified by execution:
SetSelection(n) is 0-based — SetSelection(0) selects the first item..Index and GetTag$() are 1-based — selecting the 2nd item (Green)
reports .Index = 2, and GetTag$(2) returns Green's tag.The pattern GetTag$(.Index) is correct precisely because both sides are
1-based. Do not offset .Index before passing it to GetTag$().
Style. 0x50210003 is a drop-down with an editable field; 0x50210002 is a
drop-down list (no typing). The Click() event fires on every selection change,
keyboard or mouse.