Icons in a ComboBoxGadget()
Posted: Thu Mar 24, 2005 12:43 am
Any easy way to include icons into a ComboBoxGadget()? I want to build an icon selection combo, got any ideas where to start? 

http://www.purebasic.com
https://www.purebasic.fr/english/
Well ease of use depends on how much control you need. AFAIK, you'll have to use WIN32 API to create your own "ComboBoxEx" control. This is my first attempt, so clean it up and optimize at will.Kale wrote:Any easy way to include icons into a ComboBoxGadget()?
Code: Select all
;--> ComboBoxEx Constants
#CBEIF_DI_SETITEM = $10000000
#CBEIF_IMAGE = 2
#CBEIF_INDENT = $10
#CBEIF_LPARAM = $20
#CBEIF_OVERLAY = 8
#CBEIF_SELECTEDIMAGE = 4
#CBEIF_TEXT = 1
#CBEM_INSERTITEMA = #WM_USER + 1
#CBEM_SETIMAGELIST = #WM_USER + 2
;--> ComboBoxEx Structure for adding items
cbi.COMBOBOXEXITEM
cbi\mask = #CBEIF_TEXT | #CBEIF_IMAGE | #CBEIF_SELECTEDIMAGE
;--> Create our 4 images
Dim images(3)
images(0) = CreateImage(0, 16, 16)
StartDrawing(ImageOutput())
Box(0, 0, 16, 16, RGB(255, 0, 0))
StopDrawing()
images(1) = CreateImage(1, 16, 16)
StartDrawing(ImageOutput())
Box(0, 0, 16, 16, RGB(0, 255, 0))
StopDrawing()
images(2) = CreateImage(2, 16, 16)
StartDrawing(ImageOutput())
Box(0, 0, 16, 16, RGB(0, 0, 255))
StopDrawing()
images(3) = CreateImage(3, 16, 16)
StartDrawing(ImageOutput())
Box(0, 0, 16, 16, RGB(255, 255, 0))
StopDrawing()
If OpenWindow(0, 0, 0, 270, 140, #PB_Window_SystemMenu | #PB_Window_ScreenCentered, "ComboBoxEx") And CreateGadgetList(WindowID(0))
;--> Create ComboBoxEx
hCombo = CreateWindowEx_(0, "ComboBoxEx32", "", #WS_BORDER | #WS_CHILD | #WS_VISIBLE | #CBS_DROPDOWN, 10, 10, 200, 200, WindowID(), 0, GetModuleHandle_(0), 0)
;--> Create ImageList and add our 4 images
hComboIl= ImageList_Create_(16, 16, #ILC_COLOR24, 0, 50)
For i = 0 To 3
ImageList_Add_(hComboIl, images(i), 0)
FreeImage(i)
Next i
;--> Send ImageList to ComboBoxEx
SendMessage_(hCombo, #CBEM_SETIMAGELIST, 0, hComboIl)
;--> Add our items to ComboBoxEx
For i = 0 To 3
cbi\iItem = -1
itemText$ = "ComboBoxEx Item " + Str(i)
cbi\pszText = @itemText$
cbi\cchTextMax = Len(itemText$)
cbi\iImage = i
cbi\iSelectedImage = i
SendMessage_(hCombo, #CBEM_INSERTITEMA, 0, @cbi)
Next i
quit = #False
Repeat
event = WaitWindowEvent()
If event = #PB_Event_CloseWindow
ImageList_Destroy_(hComboIl)
quit = #True
EndIf
Until quit = #True
EndIf
Code: Select all
hImageList= ImageList_Create_(IconWidth, IconHeight, #ILC_COLOR24, 0, ArrayCount)
Code: Select all
hImageList= ImageList_Create_(IconWidth, IconHeight, #ILC_MASK, 0, ArrayCount)
Code: Select all
ImageList_Add_(hImageList, hCurrentImage, 0)
Code: Select all
ImageList_ReplaceIcon_(hImageList, -1, hCurrentImage)
Code: Select all
;===========================================================================
;-CONSTANTS
;===========================================================================
#APP_NAME = "Name"
#MAX_NUMBER_OF_COMBO_ITEMS = 20
;ComboBoxEx Constants
#CBEIF_DI_SETITEM = $10000000
#CBEIF_IMAGE = 2
#CBEIF_INDENT = $10
#CBEIF_LPARAM = $20
#CBEIF_OVERLAY = 8
#CBEIF_SELECTEDIMAGE = 4
#CBEIF_TEXT = 1
#CBEM_INSERTITEMA = #WM_USER + 1
#CBEM_SETIMAGELIST = #WM_USER + 2
#CBEM_GETIMAGELIST = #WM_USER + 3
Enumeration
#WINDOW_ROOT
EndEnumeration
;===========================================================================
;-GLOBAL FLAGS / VARIABLES / STRUCTURES / ARRAYS
;===========================================================================
Structure COMBOITEM
hImage.l
Text.s
EndStructure
Dim ComboContents.COMBOITEM(#MAX_NUMBER_OF_COMBO_ITEMS - 1)
ComboContents(0)\hImage = CatchImage(0, ?Image1)
ComboContents(0)\Text = "User"
ComboContents(1)\hImage = CatchImage(1, ?Image2)
ComboContents(1)\Text = "Headphones"
ComboContents(2)\hImage = CatchImage(2, ?Image3)
ComboContents(2)\Text = "Gameboy"
ComboContents(3)\hImage = CatchImage(3, ?Image4)
ComboContents(3)\Text = "Afro"
ComboContents(4)\hImage = CatchImage(4, ?Image5)
ComboContents(4)\Text = "Little Man"
;===========================================================================
;-PROCEDURES
;===========================================================================
;Handle an error
Procedure HandleError(Result, Text.s)
If Result = 0 : MessageRequester("Error", Text, #PB_MessageRequester_Ok) : End : EndIf
EndProcedure
;create a IconComboEx gadget
Procedure IconComboExGadget(WindowID, x, y, Width, Height)
hComboBox = CreateWindowEx_(0, "ComboBoxEx32", "", #WS_BORDER | #WS_CHILD | #WS_VISIBLE | #CBS_DROPDOWN, x, y, Width, Height, WindowID, 0, GetModuleHandle_(0), 0)
ProcedureReturn hComboBox
EndProcedure
;Assign contents to the IconComboEx gadget
Procedure AssignComboExContents(hComboBox, *ArrayOfImageHandles, IconWidth, IconHeight, ArrayCount)
;clear the current list in case it has already been filled
SendMessage_(hComboBox, #CB_RESETCONTENT, 0, 0)
;if an image list exists then destroy it before creating a new one
If hImageList
ImageList_Destroy_(hImageList)
EndIf
;create a new image list
hImageList = ImageList_Create_(IconWidth, IconHeight, #ILC_MASK, 0, ArrayCount)
;set up the structure for the combo text contents
ComboItem.COMBOBOXEXITEM
ComboItem\mask = #CBEIF_TEXT | #CBEIF_IMAGE | #CBEIF_SELECTEDIMAGE
For x = 0 To (ArrayCount - 1) * 8 Step 8
If PeekL(*ArrayOfImageHandles + x) And PeekS(PeekL((*ArrayOfImageHandles + x) + 4))
;get current values
hCurrentImage = PeekL(*ArrayOfImageHandles + x)
CurrentText.s = PeekS(PeekL((*ArrayOfImageHandles + x) + 4))
;add the current image to the image list
ImageList_ReplaceIcon_(hImageList, -1, hCurrentImage)
EndIf
Next x
;assign the image list to the combo
SendMessage_(hComboBox, #CBEM_SETIMAGELIST, 0, hImageList)
For x = 0 To (ArrayCount - 1) * 8 Step 8
If PeekL(*ArrayOfImageHandles + x) And PeekS(PeekL((*ArrayOfImageHandles + x) + 4))
;get current values
hCurrentImage = PeekL(*ArrayOfImageHandles + x)
CurrentText.s = PeekS(PeekL((*ArrayOfImageHandles + x) + 4))
;construct the combo text
ComboItem\iItem = -1
ComboItem\pszText = @CurrentText
ComboItem\cchTextMax = Len(CurrentText)
ComboItem\iImage = ImageNumber
ComboItem\iSelectedImage = ImageNumber
ImageNumber + 1
;assign the text to the combo
SendMessage_(hComboBox, #CBEM_INSERTITEMA, 0, @ComboItem)
EndIf
Next x
;set the top item to display in the list
SendMessage_(hComboBox, #CB_SETCURSEL, 0, 0)
EndProcedure
;===========================================================================
;-GEOMETRY
;===========================================================================
HandleError(OpenWindow(#WINDOW_ROOT, 0, 0, 300, 300, #PB_Window_SystemMenu | #PB_Window_ScreenCentered, #APP_NAME), "Main window could not be created.")
HandleError(CreateGadgetList(WindowID(#WINDOW_ROOT)), "Gadget list for the main window could not be created.")
hComboBox = IconComboExGadget(WindowID(#WINDOW_ROOT), 10, 10, 280, 200)
AssignComboExContents(hComboBox, @ComboContents(), 16, 16, #MAX_NUMBER_OF_COMBO_ITEMS)
ListIconGadget(1, 10, 50, 280, 200, "Icon Test", 240)
For x = 0 To #MAX_NUMBER_OF_COMBO_ITEMS - 1
If ComboContents(x)\Text And ComboContents(x)\hImage
AddGadgetItem(1, -1, ComboContents(x)\Text, ComboContents(x)\hImage)
EndIf
Next x
;===========================================================================
;-MAIN LOOP
;===========================================================================
Repeat
EventID.l = WaitWindowEvent()
Select EventID
Case #PB_Event_CloseWindow
ImageList_Destroy_(SendMessage_(hComboBox, #CBEM_GETIMAGELIST, 0, 0))
End
Case #PB_EventMenu
Select EventMenuID()
;Case #MENU
;Command
EndSelect
Case #PB_EventGadget
Select EventlParam()
Case hComboBox
CurrentIndex = SendMessage_(hComboBox, #CB_GETCURSEL, 0, 0)
Debug "Current Index: " + Str(CurrentIndex)
Debug "Current Index Text: " + ComboContents(CurrentIndex)\Text
Debug "Current Index Image Handle: " + Str(ComboContents(CurrentIndex)\hImage)
Debug ""
EndSelect
Select EventGadgetID()
;Case #GADGET
;Command
EndSelect
EndSelect
ForEver
End
;===========================================================================
;-BINARY INCLUDES
;===========================================================================
DataSection
Image1:
IncludeBinary "images\account1.ico"
Image2:
IncludeBinary "images\account2.ico"
Image3:
IncludeBinary "images\account3.ico"
Image4:
IncludeBinary "images\account4.ico"
Image5:
IncludeBinary "images\account5.ico"
EndDataSection