=====The extended combobox===== //by Richard Russell, January 2007//\\ \\ Ordinary comboboxes can be created using the routines provided in the [[http://www.bbcbasic.co.uk/bbcwin/manual/bbcwing.html#combobox|WINLIB2]] (for use in a dialogue box) and [[http://www.bbcbasic.co.uk/bbcwin/manual/bbcwing.html#fncombo|WINLIB5]] (for use on the main output window) libraries. However there is a different kind, the **extended combobox**, which allows for the inclusion of a **bitmap image** as well as a text string in each of the selections:\\ \\ {{cbex.gif}}\\ \\ This article explains how to incorporate extended comboboxes in your BBC BASIC programs.\\ \\ ===== Initialisation ===== \\ To start off with we need to include this initialisation code:\\ \\ DIM icex{dwSize%, dwICC%} ICC_USEREX_CLASSES = &200 icex.dwSize% = DIM(icex{}) icex.dwICC% = ICC_USEREX_CLASSES SYS "InitCommonControlsEx", icex{} \\ ===== Image lists ===== \\ The set of images to be used in the extended combobox must be supplied as an //image list//. The first step is to create an empty image list as follows:\\ \\ dx% = 16 dy% = 16 maximages% = 8 SYS "ImageList_Create", dx%, dy%, 0, maximages%, 0 TO himglist% IF himglist% = 0 ERROR 100, "Couldn't create image list" Here **dx%** and **dy%** are the width and height, respectively, of each image in pixels and **maximages%** is the maximum number of images that the image list will ever need to hold.\\ \\ The next step is to //populate// the image list with images. You can do that either from a set of individual bitmaps or from one or more image //strips// (or a mixture of the two). An image strip is a bitmap containing several identical-sized images side-by-side.\\ \\ For the purposes of this example I will use the bitmap file **WIDGETS.BMP** supplied with BBC BASIC for Windows; this contains five 24x24 images in a strip 120 pixels wide by 24 pixels high. Since these images are a little on the large size for use in a combobox the bitmap can be resized when it is loaded, thus:\\ \\ nimages% = 5 bmpfile$ = @lib$+"..\examples\windows\widgets.bmp" LR_LOADFROMFILE = 16 SYS "LoadImage", 0, bmpfile$, 0, dx%*nimages%, dy%, LR_LOADFROMFILE TO hbitmap% IF hbitmap% = 0 ERROR 100, "Couldn't load bitmap file" Now it is straightforward to populate the first five images in the image list from the bitmap:\\ \\ SYS "ImageList_Add", himglist%, hbitmap%, 0 SYS "DeleteObject", hbitmap% More images (or strips) can be added, up to the limit specified when the image list was created, using further calls to **ImageList_Add**.\\ \\ Now the image list is ready we can concentrate on creating the extended combobox itself. The process depends on whether you want to display the combobox in a dialogue box or directly on your program's main window.\\ \\ ===== Dialogue box ===== \\ As usual, we must install the appropriate library for working with dialogue boxes:\\ \\ INSTALL @lib$+"WINLIB2" (alternatively install **WINLIB2A** or **WINLIB2B** if you need the facilities they provide).\\ \\ Now we will create a simple dialogue box containing just a cancel button and the extended combobox:\\ \\ dlg% = FN_newdialog("Extended combobox", 250, 20, 150, 140, 8, 1000) PROC_pushbutton(dlg%, "Cancel", 2, 20, 120, 56, 14, 0) WS_VISIBLE = &10000000 WS_CHILD = &40000000 WS_VSCROLL = &200000 CBS_AUTOHSCROLL = &40 CBS_DROPDOWN = 2 cbid% = 101 PROC_dlgctrl(dlg%, "", cbid%, 20, 20, 90, 150, WS_VISIBLE OR WS_CHILD OR \ \ WS_VSCROLL OR CBS_AUTOHSCROLL OR CBS_DROPDOWN, \ \ "ComboBoxEx32") Note that the combobox has been allocated the ID number **101**. Refer to the documentation for [[http://www.bbcbasic.co.uk/bbcwin/manual/bbcwing.html#dlgitem|PROC_dlgitem]] for the meaning of the other parameters. \\ \\ The dialogue box is displayed in the usual way:\\ \\ PROC_showdialog(dlg%) We've now created the dialogue box and the extended combobox, but the combobox is still empty. The next step is to tell the combobox which image list to use:\\ \\ CBEM_SETIMAGELIST = &402 SYS "SendDlgItemMessage", !dlg%, cbid%, CBEM_SETIMAGELIST, 0, himglist% Note the use of the combobox's ID number **cbid%**.\\ \\ To add items to the combobox we first have to declare some constants and a data structure:\\ \\ CBEIF_TEXT = 1 CBEIF_IMAGE = 2 CBEIF_SELECTEDIMAGE = 4 CBEM_INSERTITEMA = &401 DIM cbxi{mask%, iItem%, pszText%, cchTextMax%, iImage%, iSelectedImage%, \ \ iOverlay%, iIndent%, lParam} Now we can define each item as follows:\\ \\ text$ = "Combobox item"+CHR$0 cbxi.mask% = CBEIF_TEXT OR CBEIF_IMAGE OR CBEIF_SELECTEDIMAGE cbxi.iItem% = itemno% cbxi.pszText% = !^text$ cbxi.iImage% = imageno% cbxi.iSelectedImage% = imageno% SYS "SendDlgItemMessage", !dlg%, cbid%, CBEM_INSERTITEMA, 0, cbxi{} Here **itemno%** is the item to define (starting at zero for the first item), **imageno%** is the image to display alongside the text (zero for the first image in the image list) and **text$** is the text for this item. Note particularly the **CHR$0** termination for the text string. You can set **itemno%** to the special value **-1**, which adds it at the end of the list.\\ \\ Note that is possible to use a different image for the currently selected item from that shown against the item in the drop-down list. If it's not convenient to define the text and image(s) at the same time, you can set the value of **cbxi.mask%** according to which you want to set.\\ \\ To test which item in the extended combobox is selected you can use exactly the same code as for a regular combobox:\\ \\ CB_GETCURSEL = &147 SYS "SendDlgItemMessage", !dlg%, cbid%, CB_GETCURSEL, 0, 0 TO selected% \\ ===== Main output window ===== \\ The process for creating an extended combobox on the main output window is very similar to that for creating one in a dialogue box. As usual, we must install the appropriate library for working with boxes and buttons:\\ \\ INSTALL @lib$+"WINLIB5" (alternatively install **WINLIB5A**, and remember to pass the parent window handle **@hwnd%** as the first parameter of **FN_createwindow**).\\ \\ The extended combobox is created as follows:\\ \\ WS_VSCROLL = &200000 CBS_AUTOHSCROLL = &40 CBS_DROPDOWN = 2 hcbex% = FN_createwindow("ComboBoxEx32", "", 200, 50, 140, 200, 0, \ \ WS_VSCROLL OR CBS_AUTOHSCROLL OR CBS_DROPDOWN, 0) Refer to the documentation for [[http://www.bbcbasic.co.uk/bbcwin/manual/bbcwing.html#fnwindow|FN_createwindow]] for the meaning of the parameters. \\ \\ The next step is to tell the combobox which image list to use:\\ \\ CBEM_SETIMAGELIST = &402 SYS "SendMessage", hcbex%, CBEM_SETIMAGELIST, 0, himglist% Note the use of the combobox's window handle **hcbex%**.\\ \\ We declare some constants and a data structure exactly as before:\\ \\ CBEIF_TEXT = 1 CBEIF_IMAGE = 2 CBEIF_SELECTEDIMAGE = 4 CBEM_INSERTITEMA = &401 DIM cbxi{mask%, iItem%, pszText%, cchTextMax%, iImage%, iSelectedImage%, \ \ iOverlay%, iIndent%, lParam} Now we can define each item as follows:\\ \\ text$ = "Combobox item"+CHR$0 cbxi.mask% = CBEIF_TEXT OR CBEIF_IMAGE OR CBEIF_SELECTEDIMAGE cbxi.iItem% = itemno% cbxi.pszText% = !^text$ cbxi.iImage% = imageno% cbxi.iSelectedImage% = imageno% SYS "SendMessage", hcbex%, CBEM_INSERTITEMA, 0, cbxi{} TO res% Here **itemno%** is the item to define (starting at zero for the first item), **imageno%** is the image to display alongside the text (zero for the first image in the image list) and **text$** is the text for this item. Note particularly the **CHR$0** termination for the text string. You can set **itemno%** to the special value **-1**, which adds it at the end of the list.\\ \\ Note that is possible to use a different image for the currently selected item from that shown against the item in the drop-down list. If it's not convenient to define the text and image(s) at the same time, you can set the value of **cbxi.mask%** according to which you want to set.\\ \\ To test which item in the extended combobox is selected you can use exactly the same code as for a regular combobox:\\ \\ CB_GETCURSEL = &147 SYS "SendMessage", hcbex%, CB_GETCURSEL, 0, 0 TO selected%