Window ListIconGadget With Owner Data (Very Fast)
Posted: Sun Dec 28, 2025 7:49 pm
After writing a tool for files, I find the Windows ListIconGadget far too slow for displaying thousands of items.
However, you can manage this yourself with the MS-ListView flags #LVS_OWNERDATA.
This applies to all created ListIconGadgets.
1. SetGadgetItemState only supports the flag #PB_ListIcon_Checked.
2. After AddGadgetItem, SetGadgetItemState or SetGadetItemColor, the ListIconGadget must be updated with UpdateListIconGadget.
3. WinCallback must be used to process the ListIconGadget events.
Since a mouse click on the check box of ListIconGadget does not respond, it had to be evaluated separately. (Took a long time to find, Window bug)
I also changed the behaviour here.
Example for testing with 100,000 items, colors and font
File: ListIconGadgetEx.pb
Update v1.02.1
- Added Compiler Option #USE_GLOBAL_LISTICON_OWNER_DATA
- Added FreeListIconGadget to release list icon data
- Optimize code
Update v1.03.1
- Bugfix CheckBox and Multi Selection
- Added EventType #PB_EventType_StatusChange for CheckBox Changed
- Added Item Colors
Update v1.04.2
- Added Column Colors
- Change WinCallback
Update v1.04.3
- Added Gadget Color
Update v1.04.4
- Bugfix: Add and RemoveGadgetColumns the column colors
- Optimize: Change from PB Array to Static Array for columns
Update v1.04.6
- Bugfix: Column text must not be a zero, otherwise no column color
Update v1.04.7
- Changed max columns count to auto column count
Update v1.05.1
- Added Item Images Support
- Bugfix AddGadgetColumn
Update v1.06.2
- Added Header Color Support
- Added Compiler Option #USE_LISTICON_HEADER_COLOR
- Bugfix delete brush object
Update v1.06.4
- Remove Compiler Option #USE_LISTICON_HEADER_COLOR
- Automatically initializes the ListIcon Header Color Callback
Update v1.06.1
- Bugfix one brush release
Update v1.07.1
- Added Special Function SortListIconGadgetEx
Update v1.07.2
- Some bug fixed
However, you can manage this yourself with the MS-ListView flags #LVS_OWNERDATA.
This applies to all created ListIconGadgets.
1. SetGadgetItemState only supports the flag #PB_ListIcon_Checked.
2. After AddGadgetItem, SetGadgetItemState or SetGadetItemColor, the ListIconGadget must be updated with UpdateListIconGadget.
3. WinCallback must be used to process the ListIconGadget events.
Since a mouse click on the check box of ListIconGadget does not respond, it had to be evaluated separately. (Took a long time to find, Window bug)
I also changed the behaviour here.
Example for testing with 100,000 items, colors and font
File: ListIconGadgetEx.pb
Update v1.02.1
- Added Compiler Option #USE_GLOBAL_LISTICON_OWNER_DATA
- Added FreeListIconGadget to release list icon data
- Optimize code
Update v1.03.1
- Bugfix CheckBox and Multi Selection
- Added EventType #PB_EventType_StatusChange for CheckBox Changed
- Added Item Colors
Update v1.04.2
- Added Column Colors
- Change WinCallback
Update v1.04.3
- Added Gadget Color
Update v1.04.4
- Bugfix: Add and RemoveGadgetColumns the column colors
- Optimize: Change from PB Array to Static Array for columns
Update v1.04.6
- Bugfix: Column text must not be a zero, otherwise no column color
Update v1.04.7
- Changed max columns count to auto column count
Update v1.05.1
- Added Item Images Support
- Bugfix AddGadgetColumn
Update v1.06.2
- Added Header Color Support
- Added Compiler Option #USE_LISTICON_HEADER_COLOR
- Bugfix delete brush object
Update v1.06.4
- Remove Compiler Option #USE_LISTICON_HEADER_COLOR
- Automatically initializes the ListIcon Header Color Callback
Update v1.06.1
- Bugfix one brush release
Update v1.07.1
- Added Special Function SortListIconGadgetEx
Update v1.07.2
- Some bug fixed
Code: Select all
;-TOP
; Comment : Windows ListIconGadget Owner Data
; Author : mk-soft
; Version : v1.07.4
; Create : 26.12.2025
; Update : 11.01.2026
; Description
; - Call UpdateListIconGadget after AddGadgetItem, SetGadgetItemState, SetGadgetItemColor, SetGadgetItemImage
; - Call FreeListIconGadget to release gadget data
;
; EventType:
; The check box sends an EventType #PB_EventType_StatusChange. EventData receives the item.
;
EnableExplicit
Import ""
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
SetWindowSubclass_(hWnd, *fnSubclass, uIdSubclass, dwRefData) As "SetWindowSubclass"
GetWindowSubclass_(hWnd, *fnSubclass, uIdSubclass, *dwRefData) As "GetWindowSubclass"
RemoveWindowSubclass_(hWnd, *fnSubclass, uIdSubclass) As "RemoveWindowSubclass"
DefSubclassProc_(hWnd, uMsg, wParam, lParam) As "DefSubclassProc"
CompilerElse
SetWindowSubclass_(hWnd, *fnSubclass, uIdSubclass, dwRefData) As "_SetWindowSubclass@16"
GetWindowSubclass_(hWnd, *fnSubclass, uIdSubclass, *dwRefData) As "_GetWindowSubclass@16"
RemoveWindowSubclass_(hWnd, *fnSubclass, uIdSubclass) As "_RemoveWindowSubclass@12"
DefSubclassProc_(hWnd, uMsg, wParam, lParam) As "_DefSubclassProc@16"
CompilerEndIf
EndImport
;- Configuration
#USE_GLOBAL_LISTICON_OWNER_DATA = #True
;- Define
#LISTICON_COLUMN_SIZE = 20
#LVIS_UNCHECKED = $1000;
#LVIS_CHECKED = $2000 ;
#ILC_COLOR32 = $00000020
Structure udtListIconItem
State.l
ItemColor.l
ItemColorBk.l
ItemImage.l
UserData.i
Array Column.s(#LISTICON_COLUMN_SIZE)
Array ColumnColor.l(#LISTICON_COLUMN_SIZE)
Array ColumnColorBk.l(#LISTICON_COLUMN_SIZE)
*Reference
EndStructure
Structure udtListIconData
ExStyle.l
; Items
CountItems.l
CountColumns.l
List Items.udtListIconItem()
; Images
hImageList.i
Map ImageList.l()
; Header Colors
IsHeaderColor.l
HeaderColor.l
HeaderColorBk.i
HeaderColorSelect.l
HeaderColorSelectBk.i
Array HeaderColumnColor.l(#LISTICON_COLUMN_SIZE)
Array HeaderColumnColorBk.i(#LISTICON_COLUMN_SIZE)
Text.s{256}
Null.u
EndStructure
Global NewMap ListIconData.udtListIconData()
Global CheckBoxSize = DesktopScaledX(16)
Global HeaderLineColor = GetSysColorBrush_(#COLOR_3DFACE)
; ----
;- Private
Procedure LvnGetDispInfoCB(*Data.NMLVDISPINFO)
Protected gadget, *items.udtListIconData
With *Data
gadget = \hdr\idFrom
If Not FindMapElement(ListIconData(), Str(gadget))
ProcedureReturn #False
EndIf
*items = @ListIconData()
If \item\iItem >= *items\CountItems
ProcedureReturn #False
EndIf
SelectElement(*items\Items(), \item\iItem)
If \item\mask & #LVIF_TEXT
\item\pszText = @*items\Items()\Column(\item\iSubItem)
EndIf
If \item\mask & #LVIF_STATE
\item\stateMask = #LVIS_STATEIMAGEMASK
\item\state = *items\Items()\State
EndIf
If \item\mask & #LVIF_IMAGE
If *items\Items()\ItemImage >= 0
\item\iImage = *items\Items()\ItemImage
EndIf
EndIf
ProcedureReturn #True
EndWith
EndProcedure
; ----
Procedure LvnCustomDrawCB(*DrawData.NMLVCUSTOMDRAW)
Protected r1, gadget, gadgetcolor, *items.udtListIconData
With *DrawData
gadget = \nmcd\hdr\idFrom
If Not FindMapElement(ListIconData(), Str(gadget))
ProcedureReturn #PB_Default
EndIf
*items = @ListIconData()
If \nmcd\dwItemSpec >= *items\CountItems
ProcedureReturn #PB_ProcessPureBasicEvents
EndIf
If \nmcd\dwItemSpec < 0
ProcedureReturn #PB_ProcessPureBasicEvents
EndIf
Select \nmcd\dwDrawStage
Case #CDDS_PREPAINT
r1 = #PB_ProcessPureBasicEvents
Case #CDDS_ITEMPREPAINT
r1 = #CDRF_NOTIFYSUBITEMDRAW
Case #CDDS_SUBITEMPREPAINT
SelectElement(*items\Items(), \nmcd\dwItemSpec)
; Text Color
If *items\Items()\ColumnColor(\iSubItem) <> #PB_Default
\clrText = *items\Items()\ColumnColor(\iSubItem)
ElseIf *items\Items()\ItemColor <> #PB_Default
\clrText = *items\Items()\ItemColor
Else
gadgetcolor = GetGadgetColor(\nmcd\hdr\idFrom, #PB_Gadget_FrontColor)
If gadgetcolor = #PB_Default
\clrText = #CLR_DEFAULT
Else
\clrText = gadgetcolor
EndIf
EndIf
; Back Color
If *items\Items()\ColumnColorBk(\iSubItem) <> #PB_Default
\clrTextBk = *items\Items()\ColumnColorBk(\iSubItem)
ElseIf *items\Items()\ItemColorBk <> #PB_Default
\clrTextBk = *items\Items()\ItemColorBk
Else
gadgetcolor = GetGadgetColor(\nmcd\hdr\idFrom, #PB_Gadget_BackColor)
If gadgetcolor = #PB_Default
\clrTextBk = #CLR_DEFAULT
Else
\clrTextBk = gadgetcolor
EndIf
EndIf
r1 = #CDRF_DODEFAULT
Default
r1 = #PB_ProcessPureBasicEvents
EndSelect
ProcedureReturn r1
EndWith
EndProcedure
; ----
Procedure LvnClickCB(*ItemData.NMITEMACTIVATE)
Protected gadget, *items.udtListIconData, lvItem.LVITEM, rect.RECT
With *ItemData
gadget = \hdr\idFrom
If Not FindMapElement(ListIconData(), Str(gadget))
ProcedureReturn #False
EndIf
If Not (ListIconData()\ExStyle & #LVS_EX_CHECKBOXES)
ProcedureReturn #False
EndIf
If \iItem < 0
ProcedureReturn #False
EndIf
If \ptAction\x > CheckBoxSize
ProcedureReturn #False
EndIf
If \iItem >= ListIconData()\CountItems
ProcedureReturn #False
EndIf
SelectElement(ListIconData()\Items(), \iItem)
If ListIconData()\Items()\State & #LVIS_CHECKED
ListIconData()\Items()\State | #LVIS_UNCHECKED & ~#LVIS_CHECKED
Else
ListIconData()\Items()\State | #LVIS_CHECKED & ~#LVIS_UNCHECKED
EndIf
; Redraw selected item
SendMessage_(\hdr\hwndFrom, #LVM_GETITEMRECT, \iItem, @rect)
InvalidateRect_(\hdr\hwndFrom, rect, #True)
; Send PB message
PostEvent(#PB_Event_Gadget, GetActiveWindow(), \hdr\idFrom, #PB_EventType_StatusChange, \iItem)
ProcedureReturn #True
EndWith
EndProcedure
; ----
Procedure LvnKeyDownCB(*KeyData.LVKEYDOWN)
Protected gadget, iItem, *items.udtListIconData, lvItem.LVITEM, rect.RECT
With *KeyData
gadget = \hdr\idFrom
If Not FindMapElement(ListIconData(), Str(gadget))
ProcedureReturn #False
EndIf
If Not (ListIconData()\ExStyle & #LVS_EX_CHECKBOXES)
ProcedureReturn #False
EndIf
If \wVKey <> #VK_SPACE
ProcedureReturn #False
EndIf
iItem = SendMessage_(\hdr\hwndFrom, #LVM_GETSELECTIONMARK, 0, 0)
If iItem < 0 Or iItem >= ListIconData()\CountItems
ProcedureReturn #False
EndIf
SelectElement(ListIconData()\Items(), iItem)
If ListIconData()\Items()\State & #LVIS_CHECKED
ListIconData()\Items()\State | #LVIS_UNCHECKED & ~#LVIS_CHECKED
Else
ListIconData()\Items()\State | #LVIS_CHECKED & ~#LVIS_UNCHECKED
EndIf
; Redraw selected item
SendMessage_(\hdr\hwndFrom, #LVM_GETITEMRECT, iItem, @rect)
InvalidateRect_(\hdr\hwndFrom, rect, #True)
; Send PB message
PostEvent(#PB_Event_Gadget, GetActiveWindow(), \hdr\idFrom, #PB_EventType_StatusChange, iItem)
ProcedureReturn #True
EndWith
EndProcedure
; ----
Procedure _DrawHeader(*ListIconData.udtListIconData, *lpCD.NMCUSTOMDRAW)
Protected hdi.HDITEM, format, Color.l, ColorBk.i
With *ListIconData
Select *lpCD\dwDrawStage
Case #CDDS_PREPAINT
ProcedureReturn #CDRF_NOTIFYITEMDRAW
Case #CDDS_ITEMPREPAINT
If *lpCD\uItemState & #CDIS_SELECTED
; Selected Text and Background Color
Color = \HeaderColorSelect
ColorBk = \HeaderColorSelectBk
Else
; Text Color
If \HeaderColumnColor(*lpCD\dwItemSpec) <> #PB_Default
Color = \HeaderColumnColor(*lpCD\dwItemSpec)
ElseIf \HeaderColor <> #PB_Default
Color = \HeaderColor
Else
color = #Black
EndIf
; Background Color
If \HeaderColumnColorBk(*lpCD\dwItemSpec) <> #PB_Default
ColorBk = \HeaderColumnColorBk(*lpCD\dwItemSpec)
ElseIf \HeaderColorBk <> #PB_Default
ColorBk = \HeaderColorBk
EndIf
EndIf
; Get Header Item
hdi\mask = #HDI_TEXT | #HDI_FORMAT
hdi\pszText = *ListIconData + OffsetOf(udtListIconData\Text)
hdi\cchTextMax = 256
SendMessage_(*lpCD\hdr\hwndFrom, #HDM_GETITEM, *lpCD\dwItemSpec, @hdi)
; Draw Background
If ColorBk <> #PB_Default
FrameRect_(*lpCD\hdc, *lpCD\rc, HeaderLineColor)
*lpCD\rc\left + 0
*lpCD\rc\right - 1
FillRect_(*lpCD\hdc, *lpCD\rc, ColorBk)
EndIf
; Draw Text
SetBkMode_(*lpCD\hdc,#TRANSPARENT)
SetTextColor_(*lpCD\hdc, Color)
format = #DT_VCENTER | #DT_SINGLELINE | #DT_END_ELLIPSIS
If hdi\fmt & #HDF_CENTER
format | #DT_CENTER
EndIf
If hdi\fmt & #HDF_RIGHT
format | #DT_RIGHT
EndIf
*lpCD\rc\left + 6
*lpCD\rc\right - 5
DrawText_(*lpCD\hdc, @\Text, Len(\Text), *lpCD\rc, format)
ProcedureReturn #CDRF_SKIPDEFAULT
Default
ProcedureReturn #CDRF_DODEFAULT
EndSelect
EndWith
EndProcedure
; ----
Procedure LvnGadgetCB(hWnd, uMsg, wParam, lParam, uIdSubclass, dwRefData)
Protected *nmh.NMHDR
Select uMsg
Case #WM_NOTIFY
*nmh = lParam
Select *nmh\code
Case #NM_CUSTOMDRAW
ProcedureReturn _DrawHeader(dwRefData, lParam)
EndSelect
EndSelect
ProcedureReturn DefSubclassProc_(hWnd, uMsg, wParam, lParam)
EndProcedure
; ----
Procedure _AddListIconImage(Gadget, *ListIconData.udtListIconData, *Item.udtListIconItem, ImageID)
Protected IsImage, Index
With *ListIconData
If Not \hImageList
\hImageList = ImageList_Create_(16, 16, #ILC_COLOR32, 2, 0)
If \hImageList
SendMessage_(GadgetID(Gadget), #LVM_SETIMAGELIST, #LVSIL_SMALL, ListIconData()\hImageList)
Else
ProcedureReturn #False
EndIf
EndIf
If Not FindMapElement(\ImageList(), Str(ImageID))
AddMapElement(\ImageList(), Str(ImageID))
Index = ImageList_Add_(\hImageList, ImageID, 0)
If index < 0
DeleteMapElement(\ImageList())
ProcedureReturn #False
EndIf
\ImageList() = Index
EndIf
*Item\ItemImage = \ImageList()
ProcedureReturn #True
EndWith
EndProcedure
; ----
;- Public
Procedure ListIconGadgetEx(Gadget, x, y, Width, height, FirstColumnTitle$, FirstColumnWith, Flags=0)
Protected id, ExStyle , hHeader
id = ListIconGadget(Gadget, x, y, Width, height, FirstColumnTitle$, FirstColumnWith, Flags | #LVS_OWNERDATA)
If id
If Gadget = #PB_Any
Gadget = id
EndIf
If FindMapElement(ListIconData(), Str(Gadget))
ClearList(ListIconData()\Items())
Else
AddMapElement(ListIconData(), Str(Gadget))
EndIf
; Fix Gridlines
ExStyle = SendMessage_(GadgetID(Gadget), #LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0)
If Flags & #PB_ListIcon_GridLines
ExStyle | #LVS_EX_GRIDLINES
SendMessage_(GadgetID(Gadget), #LVM_SETEXTENDEDLISTVIEWSTYLE, 0, ExStyle)
EndIf
ListIconData()\ExStyle = ExStyle
; Items
ListIconData()\CountItems = 0
ListIconData()\CountColumns = 1
; Header
ListIconData()\HeaderColor = #PB_Default
ListIconData()\HeaderColorBk = #PB_Default
ListIconData()\HeaderColorSelect = #PB_Default
ListIconData()\HeaderColorSelectBk = #PB_Default
FillMemory(ListIconData()\HeaderColumnColor(), #LISTICON_COLUMN_SIZE * SizeOf(LONG), #PB_Default, #PB_Long)
FillMemory(ListIconData()\HeaderColumnColorBk(), #LISTICON_COLUMN_SIZE * SizeOf(INTEGER), #PB_Default, #PB_Integer)
EndIf
ProcedureReturn id
EndProcedure
; ----
Procedure FreeListIconGadget(Gadget)
Protected count, index
If GadgetType(Gadget) = #PB_GadgetType_ListIcon
If FindMapElement(ListIconData(), Str(Gadget))
If ListIconData()\IsHeaderColor
RemoveWindowSubclass_(GadgetID(Gadget), @LvnGadgetCB(), @ListIconData())
EndIf
SendMessage_(GadgetID(Gadget), #LVM_SETITEMCOUNT, 0, 1)
; Release Header Colors
If ListIconData()\HeaderColorBk <> #PB_Default
DeleteObject_(ListIconData()\HeaderColorBk)
ListIconData()\HeaderColorBk = #PB_Default
EndIf
If ListIconData()\HeaderColorSelectBk <> #PB_Default
DeleteObject_(ListIconData()\HeaderColorSelectBk)
ListIconData()\HeaderColorSelectBk = #PB_Default
EndIf
count = ListIconData()\CountColumns - 1
For index = 0 To count
If ListIconData()\HeaderColumnColorBk(index) <> #PB_Default
DeleteObject_(ListIconData()\HeaderColumnColorBk(index))
EndIf
Next
; Release Images
If ListIconData()\hImageList
ImageList_Destroy_(ListIconData()\hImageList)
EndIf
InvalidateRect_(GadgetID(Gadget), 0, #True)
DeleteMapElement(ListIconData())
EndIf
FreeGadget(Gadget)
EndIf
EndProcedure
; ----
Procedure UpdateListIconGadget(Gadget)
If FindMapElement(ListIconData(), Str(gadget))
SendMessage_(GadgetID(Gadget), #LVM_SETITEMCOUNT, ListIconData()\CountItems, 1)
InvalidateRect_(GadgetID(Gadget), 0, #True)
EndIf
EndProcedure
; ----
Procedure AddGadgetColumnEx(Gadget, Column, Title$, Width)
Protected index, count, array_size
If GadgetType(Gadget) <> #PB_GadgetType_ListIcon
ProcedureReturn AddGadgetColumn(Gadget, Column, Title$, Width)
EndIf
If Not FindMapElement(ListIconData(), Str(Gadget))
ProcedureReturn #False
EndIf
count = ListIconData()\CountColumns
If Column > count
ProcedureReturn #False
EndIf
If Column = -1
Column = count
EndIf
ListIconData()\CountColumns + 1
SendMessage_(GadgetID(Gadget), #LVM_SETITEMCOUNT, 0, 1)
AddGadgetColumn(Gadget, Column, Title$, Width)
SendMessage_(GadgetID(Gadget), #LVM_SETITEMCOUNT, ListIconData()\CountItems, 1)
; Update Header Column
array_size = ListIconData()\CountColumns
If ArraySize(ListIconData()\HeaderColumnColor()) < array_size
ReDim ListIconData()\HeaderColumnColor(array_size)
ReDim ListIconData()\HeaderColumnColorBk(array_size)
EndIf
For index = count To Column + 1 Step -1
ListIconData()\HeaderColumnColor(index) = ListIconData()\HeaderColumnColor(index-1)
ListIconData()\HeaderColumnColorBk(index) = ListIconData()\HeaderColumnColorBk(index-1)
Next
ListIconData()\HeaderColumnColor(Column) = #PB_Default
ListIconData()\HeaderColumnColorBk(Column) = #PB_Default
; Update Items Columns
array_size = 0
If ListIconData()\CountItems
FirstElement(ListIconData()\Items())
If ArraySize(ListIconData()\Items()\Column()) < ListIconData()\CountColumns
array_size = ListIconData()\CountColumns
EndIf
ForEach ListIconData()\Items()
If array_size
ReDim ListIconData()\Items()\Column(array_size)
ReDim ListIconData()\Items()\ColumnColor(array_size)
ReDim ListIconData()\Items()\ColumnColorBk(array_size)
EndIf
For index = count To Column + 1 Step -1
ListIconData()\Items()\Column(index) = ListIconData()\Items()\Column(index-1)
ListIconData()\Items()\ColumnColor(index) = ListIconData()\Items()\ColumnColor(index-1)
ListIconData()\Items()\ColumnColorBk(index) = ListIconData()\Items()\ColumnColorBk(index-1)
Next
ListIconData()\Items()\Column(Column) = #Empty$
ListIconData()\Items()\ColumnColor(Column) = #PB_Default
ListIconData()\Items()\ColumnColorBk(Column) = #PB_Default
Next
EndIf
InvalidateRect_(GadgetID(Gadget), 0, #True)
ProcedureReturn #True
EndProcedure
; ----
Procedure RemoveGadgetColumnEx(Gadget, Column)
Protected index, count
If GadgetType(Gadget) <> #PB_GadgetType_ListIcon
ProcedureReturn RemoveGadgetColumn(Gadget, Column)
EndIf
If Not FindMapElement(ListIconData(), Str(Gadget))
ProcedureReturn #False
EndIf
If Column = #PB_All
count = ListIconData()\CountColumns - 1
SendMessage_(GadgetID(Gadget), #LVM_SETITEMCOUNT, 0, 1)
ClearList(ListIconData()\Items())
ListIconData()\CountItems = 0
ListIconData()\CountColumns = 0
; Release Header Column Colors
For index = 0 To count
If ListIconData()\HeaderColumnColorBk(index) <> #PB_Default
DeleteObject_(ListIconData()\HeaderColumnColorBk(index))
EndIf
Next
Dim ListIconData()\HeaderColumnColor(#LISTICON_COLUMN_SIZE)
Dim ListIconData()\HeaderColumnColorBk(#LISTICON_COLUMN_SIZE)
FillMemory(ListIconData()\HeaderColumnColor(), #LISTICON_COLUMN_SIZE * SizeOf(LONG), #PB_Default, #PB_Long)
FillMemory(ListIconData()\HeaderColumnColorBk(), #LISTICON_COLUMN_SIZE * SizeOf(INTEGER), #PB_Default, #PB_Integer)
RemoveGadgetColumn(Gadget, Column)
Else
count = ListIconData()\CountColumns
If Column >= count
ProcedureReturn #False
EndIf
If Column < 0
ProcedureReturn #False
EndIf
SendMessage_(GadgetID(Gadget), #LVM_SETITEMCOUNT, 0, 1)
RemoveGadgetColumn(Gadget, Column)
SendMessage_(GadgetID(Gadget), #LVM_SETITEMCOUNT, ListIconData()\CountItems, 1)
ListIconData()\CountColumns - 1
count - 1
; Update Header Columns
If ListIconData()\HeaderColumnColorBk(Column) <> #PB_Default
DeleteObject_(ListIconData()\HeaderColumnColorBk(Column))
EndIf
For index = Column To count
ListIconData()\HeaderColumnColor(index) = ListIconData()\HeaderColumnColor(index + 1)
ListIconData()\HeaderColumnColorBk(index) = ListIconData()\HeaderColumnColorBk(index + 1)
Next
ListIconData()\HeaderColumnColor(index) = #PB_Default
If ListIconData()\HeaderColumnColorBk(index) <> #PB_Default
DeleteObject_(ListIconData()\HeaderColumnColorBk(index))
ListIconData()\HeaderColumnColorBk(index) = #PB_Default
EndIf
; Update Items Columns
ForEach ListIconData()\Items()
For index = Column To count
ListIconData()\Items()\Column(index) = ListIconData()\Items()\Column(index + 1)
ListIconData()\Items()\ColumnColor(index) = ListIconData()\Items()\ColumnColor(index + 1)
ListIconData()\Items()\ColumnColorBk(index) = ListIconData()\Items()\ColumnColorBk(index + 1)
Next
ListIconData()\Items()\Column(index) = #Empty$
ListIconData()\Items()\ColumnColor(index) = #PB_Default
ListIconData()\Items()\ColumnColorBk(index) = #PB_Default
Next
EndIf
If ListIconData()\CountColumns = 0
If ListIconData()\IsHeaderColor
ListIconData()\IsHeaderColor = #False
RemoveWindowSubclass_(GadgetID(Gadget), @LvnGadgetCB(), @ListIconData())
EndIf
; Release Header Colors
ListIconData()\HeaderColor = #PB_Default
If ListIconData()\HeaderColorBk <> #PB_Default
DeleteObject_(ListIconData()\HeaderColorBk)
ListIconData()\HeaderColorBk = #PB_Default
EndIf
; Release Header Selection Colors
ListIconData()\HeaderColorSelect = #PB_Default
If ListIconData()\HeaderColorSelectBk <> #PB_Default
DeleteObject_(ListIconData()\HeaderColorSelectBk)
ListIconData()\HeaderColorSelectBk = #PB_Default
EndIf
EndIf
InvalidateRect_(GadgetID(Gadget), 0, #True)
ProcedureReturn #True
EndProcedure
; ----
Procedure AddGadgetItemEx(Gadget, Item, Text$, ImageID=0, Flags=0)
Protected *item.udtListIconItem, count, columns, index, size
If GadgetType(Gadget) <> #PB_GadgetType_ListIcon
ProcedureReturn AddGadgetItem(Gadget, Item, Text$, ImageID, Flags)
EndIf
If Not FindMapElement(ListIconData(), Str(Gadget))
ProcedureReturn #False
EndIf
count = ListSize(ListIconData()\Items())
If Item = -1
LastElement(ListIconData()\Items())
AddElement(ListIconData()\Items())
ElseIf Item = count
LastElement(ListIconData()\Items())
AddElement(ListIconData()\Items())
ElseIf Item < count
SelectElement(ListIconData()\Items(), Item)
InsertElement(ListIconData()\Items())
Else
ProcedureReturn #False
EndIf
ListIconData()\CountItems = ListSize(ListIconData()\Items())
columns = ListIconData()\CountColumns
If ArraySize(ListIconData()\Items()\Column()) < columns
ReDim ListIconData()\Items()\Column(columns)
ReDim ListIconData()\Items()\ColumnColor(columns)
ReDim ListIconData()\Items()\ColumnColorBk(ListIconData()\CountColumns)
EndIf
*item = @ListIconData()\Items()
*item\State = #LVIS_UNCHECKED
*item\ItemColor = #PB_Default
*item\ItemColorBk = #PB_Default
*item\ItemImage = -1
*item\UserData = 0
columns = CountString(Text$, #LF$)
If columns >= ListIconData()\CountColumns
columns = ListIconData()\CountColumns - 1
EndIf
For index = 0 To columns
*item\Column(index) = StringField(Text$, index + 1, #LF$)
Next
columns + 1
For index = columns To ListIconData()\CountColumns - 1
*item\Column(index) = #Empty$
Next
size = ArraySize(ListIconData()\Items()\Column()) * SizeOf(LONG)
FillMemory(@*item\ColumnColor(), size, #PB_Default, #PB_Long)
FillMemory(@*item\ColumnColorBk(), size, #PB_Default, #PB_Long)
If ImageID
_AddListIconImage(Gadget, @ListIconData(), *Item, ImageID)
EndIf
EndProcedure
; ----
Procedure RemoveGadgetItemEx(Gadget, Item)
If GadgetType(Gadget) <> #PB_GadgetType_ListIcon
ProcedureReturn RemoveGadgetItem(Gadget, Item)
EndIf
If Not FindMapElement(ListIconData(), Str(Gadget))
ProcedureReturn #False
EndIf
If Item >= ListIconData()\CountItems
ProcedureReturn #False
EndIf
If Item < 0
ProcedureReturn #False
EndIf
SelectElement(ListIconData()\Items(), Item)
DeleteElement(ListIconData()\Items())
ListIconData()\CountItems = ListSize(ListIconData()\Items())
SendMessage_(GadgetID(Gadget), #LVM_SETITEMCOUNT, ListIconData()\CountItems, 1)
InvalidateRect_(GadgetID(Gadget), 0, #True)
ProcedureReturn #True
EndProcedure
; ----
Procedure ClearGadgetItemsEx(Gadget)
If GadgetType(Gadget) <> #PB_GadgetType_ListIcon
ProcedureReturn ClearGadgetItems(Gadget)
EndIf
If Not FindMapElement(ListIconData(), Str(Gadget))
ProcedureReturn #False
EndIf
ClearList(ListIconData()\Items())
ListIconData()\CountItems = 0
SendMessage_(GadgetID(Gadget), #LVM_SETITEMCOUNT, 0, 1)
InvalidateRect_(GadgetID(Gadget), 0, #True)
ProcedureReturn #True
EndProcedure
; ----
Procedure SetGadgetItemStateEx(Gadget, Item, State)
If GadgetType(Gadget) <> #PB_GadgetType_ListIcon
ProcedureReturn SetGadgetItemState(Gadget, Item, State)
EndIf
If Not FindMapElement(ListIconData(), Str(Gadget))
ProcedureReturn #False
EndIf
If Item >= ListIconData()\CountItems
ProcedureReturn #False
EndIf
If Item < 0
ProcedureReturn #False
EndIf
SelectElement(ListIconData()\Items(), Item)
If State & #PB_ListIcon_Checked
ListIconData()\Items()\State | #LVIS_CHECKED & ~#LVIS_UNCHECKED
Else
ListIconData()\Items()\State | #LVIS_UNCHECKED & ~#LVIS_CHECKED
EndIf
EndProcedure
; ----
Procedure GetGadgetItemStateEx(Gadget, Item)
Protected r1
If GadgetType(Gadget) <> #PB_GadgetType_ListIcon
ProcedureReturn GetGadgetItemState(Gadget, Item)
EndIf
If Not FindMapElement(ListIconData(), Str(Gadget))
ProcedureReturn 0
EndIf
If Item >= ListIconData()\CountItems
ProcedureReturn 0
EndIf
If Item < 0
ProcedureReturn 0
EndIf
SelectElement(ListIconData()\Items(), Item)
If ListIconData()\Items()\State & #LVIS_CHECKED
r1 = #PB_ListIcon_Checked
EndIf
If SendMessage_(GadgetID(Gadget), #LVM_GETITEMSTATE, Item, #LVIS_SELECTED) & #LVIS_SELECTED
r1 | #PB_ListIcon_Selected
EndIf
ProcedureReturn r1
EndProcedure
; ----
Procedure SetGadgetItemDataEx(Gadget, Item, Value)
If GadgetType(Gadget) <> #PB_GadgetType_ListIcon
ProcedureReturn SetGadgetItemData(Gadget, Item, Value)
EndIf
If Not FindMapElement(ListIconData(), Str(Gadget))
ProcedureReturn #False
EndIf
If Item >= ListIconData()\CountItems
ProcedureReturn #False
EndIf
If Item < 0
ProcedureReturn #False
EndIf
SelectElement(ListIconData()\Items(), Item)
ListIconData()\Items()\UserData = Value
ProcedureReturn #True
EndProcedure
; ----
Procedure GetGadgetItemDataEx(Gadget, Item)
If GadgetType(Gadget) <> #PB_GadgetType_ListIcon
ProcedureReturn GetGadgetItemData(Gadget, Item)
EndIf
If Not FindMapElement(ListIconData(), Str(Gadget))
ProcedureReturn 0
EndIf
If Item >= ListIconData()\CountItems
ProcedureReturn 0
EndIf
If Item < 0
ProcedureReturn 0
EndIf
SelectElement(ListIconData()\Items(), Item)
ProcedureReturn ListIconData()\Items()\UserData
EndProcedure
; ----
Procedure SetGadgetItemTextEx(Gadget, Item, Text$, Column=-1)
If GadgetType(Gadget) <> #PB_GadgetType_ListIcon Or Item < 0
If Column = -1
ProcedureReturn SetGadgetItemText(Gadget, Item, Text$)
Else
ProcedureReturn SetGadgetItemText(Gadget, Item, Text$, Column)
EndIf
EndIf
If Not FindMapElement(ListIconData(), Str(Gadget))
ProcedureReturn 0
EndIf
If Item >= ListIconData()\CountItems
ProcedureReturn 0
EndIf
If Column >= ListIconData()\CountColumns
ProcedureReturn #False
EndIf
If Column < 0
Column = 0
EndIf
SelectElement(ListIconData()\Items(), Item)
ListIconData()\Items()\Column(Column) = Text$
InvalidateRect_(GadgetID(Gadget), 0, #True)
ProcedureReturn #True
EndProcedure
; ----
Procedure.s GetGadgetItemTextEx(Gadget, Item, Column=-1)
If GadgetType(Gadget) <> #PB_GadgetType_ListIcon Or Item < 0
If Column = -1
ProcedureReturn GetGadgetItemText(Gadget, Item)
Else
ProcedureReturn GetGadgetItemText(Gadget, Item, Column)
EndIf
EndIf
If Not FindMapElement(ListIconData(), Str(Gadget))
ProcedureReturn ""
EndIf
If Item >= ListIconData()\CountItems
ProcedureReturn ""
EndIf
If Column >= ListIconData()\CountColumns
ProcedureReturn ""
EndIf
If Column < 0
Column = 0
EndIf
SelectElement(ListIconData()\Items(), Item)
ProcedureReturn ListIconData()\Items()\Column(Column)
EndProcedure
; ----
Procedure SetGadgetItemColorEx(Gadget, Item, ColorType, Color, Column=-1)
Protected color_red, color_green, color_blue
If GadgetType(Gadget) <> #PB_GadgetType_ListIcon
If Column = -1
ProcedureReturn SetGadgetItemColor(Gadget, Item, ColorType, Color)
Else
ProcedureReturn SetGadgetItemColor(Gadget, Item, ColorType, Color, Column)
EndIf
EndIf
If Not FindMapElement(ListIconData(), Str(Gadget))
ProcedureReturn 0
EndIf
If Item >= ListIconData()\CountItems
ProcedureReturn 0
EndIf
If Item < 0
; Set Header Colors
If Not ListIconData()\IsHeaderColor
; Initalize Header Colors
ListIconData()\IsHeaderColor = #True
SetWindowSubclass_(GadgetID(0), @LvnGadgetCB(), @ListIconData(), @ListIconData())
ListIconData()\HeaderColorSelect = #Black ; GetSysColor_(#COLOR_HIGHLIGHTTEXT)
ListIconData()\HeaderColorSelectBk = CreateSolidBrush_($FFE1CA) ; CreateSolidBrush_(GetSysColor_(#COLOR_HIGHLIGHT))
EndIf
If Column < 0
; Set Header Color
Select ColorType
Case #PB_Gadget_FrontColor
ListIconData()\HeaderColor = Color
Case #PB_Gadget_BackColor
If ListIconData()\HeaderColorBk <> #PB_Default
DeleteObject_(ListIconData()\HeaderColorBk)
DeleteObject_(ListIconData()\HeaderColorSelectBk)
EndIf
ListIconData()\HeaderColorBk = CreateSolidBrush_(Color)
color_red = Red(color) * 92 / 100
color_green = Green(color) * 92 / 100
color_blue = Blue(color) * 92 / 100
color = RGB(color_red, color_green, color_blue)
ListIconData()\HeaderColorSelect = ListIconData()\HeaderColor
ListIconData()\HeaderColorSelectBk = CreateSolidBrush_(Color)
EndSelect
ProcedureReturn #True
ElseIf Column < ListIconData()\CountColumns
; Set Header Column Color
Select ColorType
Case #PB_Gadget_FrontColor
ListIconData()\HeaderColumnColor(Column) = Color
Case #PB_Gadget_BackColor
If ListIconData()\HeaderColumnColorBk(Column) <> #PB_Default
DeleteObject_(ListIconData()\HeaderColumnColorBk(Column))
EndIf
ListIconData()\HeaderColumnColorBk(Column) = CreateSolidBrush_(Color)
EndSelect
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
Else
; Set Items Colors
SelectElement(ListIconData()\Items(), Item)
If Column < 0
; Set Item Color
Select ColorType
Case #PB_Gadget_FrontColor
ListIconData()\Items()\ItemColor = Color
Case #PB_Gadget_BackColor
ListIconData()\Items()\ItemColorBk = Color
EndSelect
ProcedureReturn #True
ElseIf Column < ListIconData()\CountColumns
; Set Column Color
Select ColorType
Case #PB_Gadget_FrontColor
ListIconData()\Items()\ColumnColor(Column) = Color
Case #PB_Gadget_BackColor
ListIconData()\Items()\ColumnColorBk(Column) = Color
EndSelect
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndIf
EndProcedure
; ----
Procedure GetGadgetItemColorEx(Gadget, Item, ColorType, Column=-1)
If GadgetType(Gadget) <> #PB_GadgetType_ListIcon
If Column = -1
ProcedureReturn GetGadgetItemColor(Gadget, Item, ColorType)
Else
ProcedureReturn GetGadgetItemColor(Gadget, Item, ColorType, Column)
EndIf
EndIf
If Not FindMapElement(ListIconData(), Str(Gadget))
ProcedureReturn 0
EndIf
If Item >= ListIconData()\CountItems
ProcedureReturn 0
EndIf
If Item < 0
ProcedureReturn #PB_Default
EndIf
If Column >= ListIconData()\CountColumns
ProcedureReturn #PB_Default
EndIf
SelectElement(ListIconData()\Items(), Item)
If Column < 0
Select ColorType
Case #PB_Gadget_FrontColor
ProcedureReturn ListIconData()\Items()\ItemColor
Case #PB_Gadget_BackColor
ProcedureReturn ListIconData()\Items()\ItemColor
EndSelect
Else
Select ColorType
Case #PB_Gadget_FrontColor
ProcedureReturn ListIconData()\Items()\ColumnColor(Column)
Case #PB_Gadget_BackColor
ProcedureReturn ListIconData()\Items()\ColumnColorBk(Column)
EndSelect
EndIf
ProcedureReturn #PB_Default
EndProcedure
; ----
Procedure SetGadgetItemImageEx(Gadget, Item, ImageID)
If GadgetType(Gadget) <> #PB_GadgetType_ListIcon
ProcedureReturn SetGadgetItemImage(Gadget, Item, ImageID)
EndIf
If Not FindMapElement(ListIconData(), Str(Gadget))
ProcedureReturn #False
EndIf
If Item >= ListIconData()\CountItems
ProcedureReturn #False
EndIf
If Item < 0
ProcedureReturn #False
EndIf
SelectElement(ListIconData()\Items(), Item)
If ImageID
_AddListIconImage(Gadget, @ListIconData(), @ListIconData()\Items(), ImageID)
Else
ListIconData()\Items()\ItemImage = -1
EndIf
ProcedureReturn #True
EndProcedure
; ----
;- Private Special Function
Procedure _CustomSortInteger(*a.udtListIconItem, *b.udtListIconItem)
Protected *strA.string, *strB.string, a.i, b.i
*strA = @*a\Reference
*strB = @*b\Reference
a = Val(*strA\s)
b = Val(*strB\s)
If a < b
ProcedureReturn #PB_Sort_Lesser
ElseIf a > b
ProcedureReturn #PB_Sort_Greater
Else
ProcedureReturn #PB_Sort_Equal
EndIf
EndProcedure
Procedure _CustomSortDouble(*a.udtListIconItem, *b.udtListIconItem)
Protected *strA.string, *strB.string, a.d, b.d
*strA = @*a\Reference
*strB = @*b\Reference
a = ValD(*strA\s)
b = ValD(*strB\s)
If a < b
ProcedureReturn #PB_Sort_Lesser
ElseIf a > b
ProcedureReturn #PB_Sort_Greater
Else
ProcedureReturn #PB_Sort_Equal
EndIf
EndProcedure
;- Public Special Function
; Description
; - Option: #PB_Sort_Ascending, #PB_Sort_Descending, #PB_Sort_NoCase
; - Typ : #PB_String, #PB_Integer, #PB_Double
Procedure SortListIconGadgetEx(Gadget, Option, Column, Typ = #PB_String, StartItem = #PB_Default, EndItem = #PB_Default)
If GadgetType(Gadget) <> #PB_GadgetType_ListIcon
ProcedureReturn #False
EndIf
If FindMapElement(ListIconData(), Str(Gadget))
If Column >= ListIconData()\CountColumns
ProcedureReturn #False
EndIf
; Build Sort Reference
ForEach ListIconData()\Items()
ListIconData()\Items()\Reference = @ListIconData()\Items()\Column(Column)
Next
If StartItem <> #PB_Default
If EndItem = #PB_Default
EndItem = ListIconData()\CountItems - 1
EndIf
Select Typ
Case #PB_String
SortStructuredList(ListIconData()\Items(), Option, OffsetOf(udtListIconItem\Reference), #PB_String, StartItem, EndItem)
Case #PB_Integer
CustomSortList(ListIconData()\Items(), @_CustomSortInteger(), Option, StartItem, EndItem)
Case #PB_Double
CustomSortList(ListIconData()\Items(), @_CustomSortDouble(), Option, StartItem, EndItem)
EndSelect
Else
Select Typ
Case #PB_String
SortStructuredList(ListIconData()\Items(), Option, OffsetOf(udtListIconItem\Reference), #PB_String)
Case #PB_Integer
CustomSortList(ListIconData()\Items(), @_CustomSortInteger(), Option)
Case #PB_Double
CustomSortList(ListIconData()\Items(), @_CustomSortDouble(), Option)
EndSelect
EndIf
InvalidateRect_(GadgetID(Gadget), 0, 1)
EndIf
EndProcedure
; ----
;- Macros
CompilerIf #USE_GLOBAL_LISTICON_OWNER_DATA
Macro ListIconGadget(Gadget, x, y, Width, height, FirstColumnTitle, FirstColumnWith, Flags=0)
ListIconGadgetEx(Gadget, x, y, Width, height, FirstColumnTitle, FirstColumnWith, Flags)
EndMacro
Macro AddGadgetColumn(Gadget, Column, Title, Width)
AddGadgetColumnEx(Gadget, Column, Title, Width)
EndMacro
Macro RemoveGadgetColumn(Gadget, Column)
RemoveGadgetColumnEx(Gadget, Column)
EndMacro
Macro AddGadgetItem(Gadget, Item, Text, ImageID=0, Flags=0)
AddGadgetItemEx(Gadget, Item, Text, ImageID, Flags)
EndMacro
Macro RemoveGadgetItem(Gadget, Item)
RemoveGadgetItemEx(Gadget, Item)
EndMacro
Macro ClearGadgetItems(Gadget)
ClearGadgetItemsEx(Gadget)
EndMacro
Macro SetGadgetItemState(Gadget, Item, State)
SetGadgetItemStateEx(Gadget, Item, State)
EndMacro
Macro GetGadgetItemState(Gadget, Item)
GetGadgetItemStateEx(Gadget, Item)
EndMacro
Macro SetGadgetItemData(Gadget, Item, Value)
SetGadgetItemDataEx(Gadget, Item, Value)
EndMacro
Macro GetGadgetItemData(Gadget, Item)
GetGadgetItemDataEx(Gadget, Item)
EndMacro
Macro SetGadgetItemText(Gadget, Item, Text, Column=-1)
SetGadgetItemTextEx(Gadget, Item, Text, Column)
EndMacro
Macro GetGadgetItemText(Gadget, Item, Column=-1)
GetGadgetItemTextEx(Gadget, Item, Column)
EndMacro
Macro SetGadgetItemColor(Gadget, Item, ColorType, Color, Column=-1)
SetGadgetItemColorEx(Gadget, Item, ColorType, Color, Column)
EndMacro
Macro GetGadgetItemColor(Gadget, Item, ColorType, Column=-1)
GetGadgetItemColorEx(Gadget, Item, ColorType, Column)
EndMacro
Macro SetGadgetItemImage(Gadget, Item, ImageID)
SetGadgetItemImageEx(Gadget, Item, ImageID)
EndMacro
CompilerEndIf
; ----
Procedure WinCallback(hWnd, uMsg, wParam, lParam)
Protected r1, *nmh.NMHDR
Select uMsg
Case #WM_NOTIFY
*nmh = lParam
Select *nmh\code
Case #LVN_GETDISPINFO
If LvnGetDispInfoCB(lParam)
ProcedureReturn #True
EndIf
Case #NM_CUSTOMDRAW
r1 = LvnCustomDrawCB(lParam)
If r1 <> #PB_Default
ProcedureReturn r1
EndIf
; More Custom draw
Case #NM_CLICK
LvnClickCB(lParam)
Case #LVN_KEYDOWN
LvnKeyDownCB(lParam)
EndSelect
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
;- ********
;-Example
CompilerIf #PB_Compiler_IsMainFile
#CharSortAscend = "▲ "
#CharSortDescend = "▼ "
UsePNGImageDecoder()
Procedure ListFillData()
Protected i, time, image0, image1, image2 , dblVal.d
time = ElapsedMilliseconds()
; Create Images
CreateImage(0, 16, 16, 32, #PB_Image_Transparent)
If StartDrawing(ImageOutput(0))
DrawingMode(#PB_2DDrawing_AllChannels)
Circle(7, 7, 7, $FF000000 | #Red)
DrawingMode(#PB_2DDrawing_Outlined)
Circle(7, 7, 7, $FF000000 | #Black)
StopDrawing()
EndIf
CreateImage(1, 16, 16, 32, #PB_Image_Transparent)
If StartDrawing(ImageOutput(1))
DrawingMode(#PB_2DDrawing_AllChannels)
Circle(7, 7, 7, $FF000000 | #Yellow)
DrawingMode(#PB_2DDrawing_Outlined)
Circle(7, 7, 7, $FF000000 | #Black)
StopDrawing()
EndIf
CreateImage(2, 16, 16, 32, #PB_Image_Transparent)
If StartDrawing(ImageOutput(2))
DrawingMode(#PB_2DDrawing_AllChannels)
Circle(7, 7, 7, $FF000000 | #Green)
DrawingMode(#PB_2DDrawing_Outlined)
Circle(7, 7, 7, $FF000000 | #Black)
StopDrawing()
EndIf
LoadImage(3, #PB_Compiler_Home + "Examples\Sources\Data\world.png")
LoadImage(4, #PB_Compiler_Home + "Examples\Sources\Data\Drive.bmp")
For i = 0 To 100000
dblVal = 0.001 * Random(100000)
AddGadgetItem(0, -1, "Item " + i + #LF$ + Str(i + 100) + #LF$ + Str(i + 1000) + #LF$ + Str(Random(10000)) + #LF$ + Str(Random(10000)) + #LF$ + StrD(dblVal, 3), ImageID(Random(4)))
Next
SetGadgetItemState(0, 2, #PB_ListIcon_Checked)
; Header Colors
SetGadgetItemColor(0, -1, #PB_Gadget_FrontColor, $701919)
SetGadgetItemColor(0, -1, #PB_Gadget_BackColor, $FFBF00)
; Header Column Color
SetGadgetItemColor(0, -1, #PB_Gadget_FrontColor, #White, 2)
SetGadgetItemColor(0, -1, #PB_Gadget_BackColor, #Blue, 2)
; Item Colors
SetGadgetItemColor(0, 1, #PB_Gadget_BackColor, #Red)
SetGadgetItemColor(0, 1, #PB_Gadget_FrontColor, #Yellow)
SetGadgetItemColor(0, 1, #PB_Gadget_BackColor, #Green, 0)
SetGadgetItemColor(0, 1, #PB_Gadget_FrontColor, #Black, 0)
SetGadgetItemColor(0, 2, #PB_Gadget_BackColor, #Green, 1)
SetGadgetItemColor(0, 2, #PB_Gadget_FrontColor, #Black, 1)
SetGadgetItemColor(0, 3, #PB_Gadget_BackColor, #Red)
SetGadgetItemColor(0, 3, #PB_Gadget_FrontColor, #Yellow)
SetGadgetItemColor(0, 3, #PB_Gadget_BackColor, #Blue, 2)
SetGadgetItemColor(0, 3, #PB_Gadget_FrontColor, #White, 2)
SetGadgetItemColor(0, 5, #PB_Gadget_BackColor, $D0D0D0)
i - 1
SetGadgetItemColor(0, i, #PB_Gadget_BackColor, #Green)
SetGadgetItemColor(0, i, #PB_Gadget_FrontColor, #Blue)
AddGadgetItem(0, 10, "Insert Item 10" + #LF$ + Str(1) + #LF$ +Str(2))
SetGadgetItemImage(0, 1, 0)
SetGadgetItemImage(0, 3, 0)
SetGadgetItemImage(0, 5, ImageID(0))
UpdateListIconGadget(0)
Debug "Fill Time " + Str(ElapsedMilliseconds() - time)
EndProcedure
Procedure ListCheckBoxData()
Protected i, cnt
cnt = CountGadgetItems(0) - 1
For i = 0 To cnt
If Random(1)
SetGadgetItemState(0, i, #PB_ListIcon_Checked)
SetGadgetItemColor(0, i, #PB_Gadget_FrontColor, #Black)
SetGadgetItemColor(0, i, #PB_Gadget_BackColor, $FFE2B0)
Else
SetGadgetItemState(0, i, 0)
SetGadgetItemColor(0, i, #PB_Gadget_FrontColor, #PB_Default)
SetGadgetItemColor(0, i, #PB_Gadget_BackColor, #PB_Default)
EndIf
Next
UpdateListIconGadget(0)
EndProcedure
; ----
Procedure UpdateWindow()
Protected dx, dy
dx = WindowWidth(0)
dy = WindowHeight(0) - StatusBarHeight(0) - MenuHeight()
; Resize Gadgets
ResizeGadget(0, 0, 0, dx, dy)
EndProcedure
LoadFont(0, "Arial", 11, #PB_Font_Bold)
Procedure Main()
Protected dx, dy, item, state, i, column, count, temp.s, time
#WinStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
If OpenWindow(0, #PB_Ignore, #PB_Ignore, 640, 420, "Window ListIconGadget Owner Data", #WinStyle)
; MenuBar
CreateMenu(0, WindowID(0))
MenuTitle("&File")
MenuItem(99, "E&xit")
MenuTitle("Test")
MenuItem(1, "Fill CheckBoxed")
MenuItem(2, "Insert Column 1")
MenuItem(3, "Remove Column 1")
MenuItem(4, "Remove All Column")
MenuItem(5, "Remove Item 1")
MenuItem(6, "Remove All Items")
MenuItem(7, "Get Selected Items")
; StatusBar
CreateStatusBar(0, WindowID(0))
AddStatusBarField(#PB_Ignore)
; Gadgets
dx = WindowWidth(0)
dy = WindowHeight(0) - StatusBarHeight(0) - MenuHeight()
#ListStyle = #PB_ListIcon_GridLines | #PB_ListIcon_CheckBoxes | #PB_ListIcon_FullRowSelect | #PB_ListIcon_MultiSelect
ListIconGadget(0, 0, 0, dx, dy, "Column 0", 200, #ListStyle)
For i = 1 To 6
AddGadgetColumn(0, i, "Column " + i, 200)
Next
SetGadgetItemAttribute(0, 0, #PB_ListIcon_ColumnAlignment, #PB_ListIcon_Center, 1)
SetGadgetItemAttribute(0, 0, #PB_ListIcon_ColumnAlignment, #PB_ListIcon_Right, 2)
SetGadgetColor(0, #PB_Gadget_FrontColor, $4F4F2F)
SetGadgetColor(0, #PB_Gadget_BackColor, $FFFFE0)
SetGadgetFont(0, FontID(0))
; Bind Events
BindEvent(#PB_Event_SizeWindow, @UpdateWindow(), 0)
; Set Window Callback
SetWindowCallback(@WinCallback())
ListFillData()
; Main Loop
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Select EventWindow()
Case 0
FreeListIconGadget(0)
Break
EndSelect
Case #PB_Event_Menu
Select EventMenu()
Case 1
ListCheckBoxData()
Case 2
AddGadgetColumn(0, 1, "Insert", 100)
Case 3
RemoveGadgetColumn(0, 1)
Case 4
RemoveGadgetColumn(0, #PB_All)
Case 5
RemoveGadgetItem(0, 1)
Case 6
ClearGadgetItems(0)
Case 7
count = CountGadgetItems(0) - 1
For i = 0 To count
If GetGadgetItemState(0, i) & #PB_ListIcon_Selected
Debug "Selected Item " + i
EndIf
Next
Case 99
PostEvent(#PB_Event_CloseWindow, 0, 0)
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case 0
Select EventType()
Case #PB_EventType_Change
item = GetGadgetState(0)
state = GetGadgetItemState(0, item)
Debug "PB Event Change Item " + item + " / State " + state
Case #PB_EventType_StatusChange
item = EventData()
state = GetGadgetItemState(0, item)
Debug "PB Event StatusChange Item " + item + " / CheckBox " + Bool(state & #PB_ListIcon_Checked)
Case #PB_EventType_LeftDoubleClick
item = GetGadgetState(0)
state = GetGadgetItemState(0, item)
Debug "PB Event LeftDoubleClick Item " + item + " / CheckBox " + Bool(state & #PB_ListIcon_Checked)
Case #PB_EventType_ColumnClick
time = ElapsedMilliseconds()
column = GetGadgetAttribute(0, #PB_ListIcon_ClickedColumn)
If column < 2
Debug "ColumnClick - " + GetGadgetItemText(0, -1, column) + " - Sort String"
temp = #CharSortAscend + "Column " + column
SortListIconGadgetEx(0, #PB_Sort_Ascending, column)
Debug "Sort Time " + Str(ElapsedMilliseconds() - time) + "ms"
ElseIf column <= 3
Debug "ColumnClick - " + GetGadgetItemText(0, -1, column) + " - Sort Integer"
temp = #CharSortAscend + "Column " + column
SortListIconGadgetEx(0, #PB_Sort_Ascending, column, #PB_Integer)
Debug "Sort Time " + Str(ElapsedMilliseconds() - time) + "ms"
ElseIf column <= 4
Debug "ColumnClick - " + GetGadgetItemText(0, -1, column) + " - Sort Integer Desc"
temp = #CharSortDescend + "Column " + column
SortListIconGadgetEx(0, #PB_Sort_Descending, column, #PB_Integer)
Debug "Sort Time " + Str(ElapsedMilliseconds() - time) + "ms"
ElseIf column <= 5
Debug "ColumnClick - " + GetGadgetItemText(0, -1, column) + " - Sort Double"
temp = #CharSortAscend + "Column " + column
SortListIconGadgetEx(0, #PB_Sort_Ascending, column, #PB_Double)
Debug "Sort Time " + Str(ElapsedMilliseconds() - time) + "ms"
Else
Debug "ColumnClick - " + GetGadgetItemText(0, -1, column)
temp = "Column " + column
EndIf
EndSelect
count = GetGadgetAttribute(0, #PB_ListIcon_ColumnCount) - 1
For i = 0 To count
If i = column
SetGadgetItemText(0, -1, temp, i)
Else
SetGadgetItemText(0, -1, "Column " + i, i)
EndIf
Next
EndSelect
EndSelect
ForEver
EndIf
EndProcedure : Main()
CompilerEndIf