proc combobox {w args} { if [winfo exists $w] { error "window $w already exists" } frame $w ## Entry Widget, it gets all the args eval entry $w.e $args pack $w.e -side left -fill x -expand 1 ## Button. With the symbol font, it should be a down arrow button $w.b -text ß -font -*-symbol-medium-r-normal-*-*-140-75-75-* \ -command "combobox_popup $w" -padx 0 -pady 0 pack $w.b -side right -fill y ## Removable List Box toplevel $w.btm -cursor arrow wm withdraw $w.btm wm overrideredirect $w.btm 1 wm transient $w.btm [winfo toplevel $w] listbox $w.btm.lbox -bd 2 -relief sunken -width 5 -height 5 \ -yscrollcommand "$w.btm.vs set" -selectmode single scrollbar $w.btm.vs -orient vertical -command "$w.btm.lbox yview" pack $w.btm.lbox -side left -fill both -expand 1 bind $w.e "+ set i 0; set tmp \[%W get] foreach item \[$w.btm.lbox get 0 end] { if {!\[string compare \$item \$tmp]} { incr i; break } } if {!\$i} { $w.btm.lbox insert end \$tmp } wm withdraw $w.btm " bind $w.e "combobox_popup $w" bind $w.e " set found 0; set tmp \[%W get] foreach item \[$w.btm.lbox get 0 end] { if {\[regexp ^\$tmp \$item]} { incr found; set match \$item } } if {\$found == 1} { $w.e delete 0 end; $w.e insert end \$match } elseif {\$found} {bell} break " bind $w.e "combobox_popup $w" bind $w.btm.lbox "combobox_popup $w" bind $w.btm.lbox " if \[%W size] { $w.e delete 0 end $w.e insert end \[%W get \[%W nearest %y]] } wm withdraw $w.btm " return $w } proc combobox_popup w { if [winfo ismapped $w.btm] { wm withdraw $w.btm } else { wm geometry $w.btm [winfo width $w.e]x[winfo reqheight $w.btm]+[winfo \ rootx $w]+[expr [winfo rooty $w]+[winfo reqheight $w]] if {[$w.btm.lbox size] > 5} { pack $w.btm.vs -side right -fill y } wm deiconify $w.btm raise $w.btm } }