
Icons in a ComboBoxGadget()
Icons in a ComboBoxGadget()
Any easy way to include icons into a ComboBoxGadget()? I want to build an icon selection combo, got any ideas where to start? 

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
What goes around comes around.
PB 5.21 LTS (x86) - Windows 8.1
PB 5.21 LTS (x86) - Windows 8.1
Try this...
replace
with
replace
with
replace
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)
What goes around comes around.
PB 5.21 LTS (x86) - Windows 8.1
PB 5.21 LTS (x86) - Windows 8.1
Ta for you help Sparkie, i think i have something i can work with now.
Click the link for updated code/images, etc. Download

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
Nice job Kale. Glad to help. 
It appears as though you can also use icons in a standard PB ComboBoxGadget, but it requires #CBS_OWNERDRAWFIXED where you do all the drawing. I haven't tried it yet, but if I get a chance later, I'll give it a go.

It appears as though you can also use icons in a standard PB ComboBoxGadget, but it requires #CBS_OWNERDRAWFIXED where you do all the drawing. I haven't tried it yet, but if I get a chance later, I'll give it a go.

What goes around comes around.
PB 5.21 LTS (x86) - Windows 8.1
PB 5.21 LTS (x86) - Windows 8.1