Icons in a ComboBoxGadget()

Just starting out? Need help? Post your questions and find answers here.
Kale
PureBasic Expert
PureBasic Expert
Posts: 3000
Joined: Fri Apr 25, 2003 6:03 pm
Location: Lincoln, UK
Contact:

Icons in a ComboBoxGadget()

Post by Kale »

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

Image
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Kale wrote:Any easy way to include icons into a ComboBoxGadget()?
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. ;)

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
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Post by gnozal »

Thanks.
Sparkie, you are a living code archive :lol:
For free libraries and tools, visit my web site (also home of jaPBe V3 and PureFORM).
Kale
PureBasic Expert
PureBasic Expert
Posts: 3000
Joined: Fri Apr 25, 2003 6:03 pm
Location: Lincoln, UK
Contact:

Post by Kale »

Thanks Sparkie! :)
--Kale

Image
Kale
PureBasic Expert
PureBasic Expert
Posts: 3000
Joined: Fri Apr 25, 2003 6:03 pm
Location: Lincoln, UK
Contact:

Post by Kale »

See below...
Last edited by Kale on Fri Mar 25, 2005 9:34 pm, edited 1 time in total.
--Kale

Image
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

I'm at work now so not much time to debug. First thing I see is ImageList_Add_() is returning -1 (Failed), so I'd start there. :wink:

I can take a closer look later when I am at home. :)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Try this...
replace

Code: Select all

hImageList= ImageList_Create_(IconWidth, IconHeight, #ILC_COLOR24, 0, ArrayCount) 
with

Code: Select all

hImageList= ImageList_Create_(IconWidth, IconHeight, #ILC_MASK, 0, ArrayCount)
replace

Code: Select all

ImageList_Add_(hImageList, hCurrentImage, 0)
with

Code: Select all

ImageList_ReplaceIcon_(hImageList, -1, hCurrentImage)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
Kale
PureBasic Expert
PureBasic Expert
Posts: 3000
Joined: Fri Apr 25, 2003 6:03 pm
Location: Lincoln, UK
Contact:

Post by Kale »

Ta for you help Sparkie, i think i have something i can work with now. :)

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
Click the link for updated code/images, etc. Download
--Kale

Image
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

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. ;)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
Post Reply