- SetListIconSorting ( sort listicon items )
- supports x64 platform
- SetListIconHeader with header options :
- Fixed : fixed width
- AutoResize : mouseclick to fit column contents / fill width if last column
- NoDrag : disable drag 'n' drop
- SetGadgetItemAttribute(#List1, -1, #PB_ListIcon_ColumnWidth, #PB_Ignore, Column) ; AutoResize specific column
- SetGadgetItemAttribute(#List1, -1, #PB_ListIcon_ColumnWidth, #PB_Ignore, #PB_Ignore) ; AutoFill last column
- AddGadgetColumn(#List1, 3, "ColumnTitle", #PB_Ignore) ; AutoFill new column
Code: Select all
;{/// UTILS
CompilerIf Defined(GADGET_VT, #PB_Structure)=#False
Structure GADGET_VT ; PB_GadgetVT
GadgetType.i ; gadget type (used by GadgetType command)
SizeOf.i ; Size of structure
*GadgetCallback
*FreeGadget
*GetGadgetState
*SetGadgetState
*GetGadgetText
*SetGadgetText
*AddGadgetItem2
*AddGadgetItem3
*RemoveGadgetItem
*ClearGadgetItemList
*ResizeGadget
*CountGadgetItems
*GetGadgetItemState
*SetGadgetItemState
*GetGadgetItemText
*SetGadgetItemText
*OpenGadgetList2
*GadgetX
*GadgetY
*GadgetWidth
*GadgetHeight
*HideGadget
*AddGadgetColumn
*RemoveGadgetColumn
*GetGadgetAttribute
*SetGadgetAttribute
*GetGadgetItemAttribute2
*SetGadgetItemAttribute2
*SetGadgetColor
*GetGadgetColor
*SetGadgetItemColor2
*GetGadgetItemColor2
*SetGadgetItemData
*GetGadgetItemData
EndStructure
CompilerEndIf
CompilerIf Defined(GADGET, #PB_Structure)=#False
Structure GADGET ; PB_Gadget
hwnd.i ; gadget window handle
*VT.GADGET_VT ; gadget commands
*GadgetData ; gadget data (used by SetGadgetData command)
*OldCallback ; window CALLBACK (used by purebasic CALLBACK)
Dates.i[4] ; .....
EndStructure
CompilerEndIf
CompilerIf Defined(HDN_BEGINDRAG, #PB_Constant)=#False
Enumeration
#HDN_ENDDRAG=#HDN_FIRST-11
#HDN_BEGINDRAG
#HDN_GETDISPINFO
#HDF_SORTUP=$400
#HDF_SORTDOWN=$200
EndEnumeration
CompilerEndIf
CompilerIf Defined(PB_ListIcon_Item, #PB_Structure)=#False
Structure PB_ListIcon_Item ; undocumented PB stuff
*UserData
EndStructure
CompilerEndIf
;}
Enumeration ;ListIconPlus Flags
;header flags
#ListIconHeader_Normal=0
#ListIconHeader_AutoSize=1
#ListIconHeader_FixedSize=2
#ListIconHeader_NoDrag=4
#ListIconHeader_Sort=8
;header sort commands
#ListIconHeader_Sort_Up=#ListIconHeader_Sort | 16 ;sorting enabled & arrow up
#ListIconHeader_Sort_Down=#ListIconHeader_Sort | 32 ;sorting enabled & arrow down
#ListIconHeader_Sort_None=#ListIconHeader_Sort | 64 ;sorting enabled & hidden arrow
#ListIconHeader_Sort_Disabled=128 ;sorting disabled
;group flags
#ListIconGroup_Position=-1<<(SizeOf(Integer)*8-1)
#ListIconGroup_TextLengthMax=100
;editor commands
#ListIconEditor_GetChanges=-100
#ListIconEditor_BeforeEdit
#ListIconEditor_BeginEdit
#ListIconEditor_CancelEdit
#ListIconEditor_CancelChanges
#ListIconEditor_ApplyChanges
EndEnumeration
Structure LGP_PARAMS
ID.i ;stored original gadget ID
CB.i ;stored original gadget callback
*VT.GADGET_VT ;stored original gadget commands
header.i ;listicon header
*headerFlags.integer ;listicon header flags
columns.i ;columns count
columnsRedraw.b ;columns redrawing (e.g: add new column, resize column )
columnToFill.i ;column to fill (last AutoSize column)
*SortFunction ;sort function
SortSingleColumn.b ;sort single column (multi-column sorting if #FALSE)
*EditFunction ;edit function
*EditorCB ;text editor callback
Editor.i ;text editor
EditorCol.i ;text editor column
EditorPos.i ;text editor position
EndStructure
Structure LGP_SORTING
ID.i
SortAsc.b ;sort mode (ascending order / descending order)
Column.i ;sort column
*SortFunction ;sort function
EndStructure
Structure LGP_ITEM
index.i ;item index (for sorting)
*olddata ;stored UserData (will be restored at the end of sorting)
EndStructure
Prototype.s LGP_GetGadgetItemText(*gadget.GADGET, Position, Column, *unknown)
ProcedureDLL.s LGP_GetGadgetItemText(*gadget.GADGET, Position, Column, *unknown)
Protected *params.LGP_PARAMS=GetProp_(*gadget\hwnd, "GadgetInfo")
If *params
With *params
Protected GroupID
If Position<-1
GroupID=Position
Protected LVGROUP.LVGROUP
LVGROUP\cbSize=SizeOf(LVGROUP)
LVGROUP\mask=#LVGF_GROUPID | #LVGF_HEADER
LVGROUP\iGroupId=GroupID
SendMessage_(*gadget\hwnd, #LVM_GETGROUPINFO, GroupID, @LVGROUP)
Protected text$=PeekS(LVGROUP\pszHeader, 1000, #PB_Unicode)
ProcedureReturn text$
Else
Protected GetItemText.LGP_GetGadgetItemText=\VT\GetGadgetItemText
ProcedureReturn GetItemText(*gadget.GADGET, Position, Column, *unknown)
EndIf
EndWith
EndIf
EndProcedure
Procedure LGP_AddGadgetColumn(*gadget.GADGET, Position, Title$, Width)
Protected *params.LGP_PARAMS=GetProp_(*gadget\hwnd, "GadgetInfo")
If *params
With *params
Protected WidthAUTO=0
If Width=#PB_Ignore
Width=100
WidthAUTO=1
EndIf
\columnsRedraw=1
CallFunctionFast(\VT\AddGadgetColumn, *gadget, Position, Title$, Width)
\columnsRedraw=0
If WidthAUTO
SetGadgetItemAttribute(\ID, 0, #PB_ListIcon_ColumnWidth, #PB_Ignore, #PB_Ignore)
EndIf
EndWith
EndIf
EndProcedure
Procedure LGP_AddGadgetItem(*gadget.GADGET, Position, Text$, ImageID=0, Flags=0)
Protected *params.LGP_PARAMS=GetProp_(*gadget\hwnd, "GadgetInfo")
If *params
With *params
Protected GroupID
If Position<-1
GroupID=Position
Text$=LSet(Text$, #ListIconGroup_TextLengthMax)
Protected *Text=AllocateMemory(StringByteLength(Text$, #PB_Unicode)+2)
PokeS(*Text, Text$, MemorySize(*Text), #PB_Unicode)
Protected LVGROUP.LVGROUP
LVGROUP\cbSize=SizeOf(LVGROUP)
LVGROUP\mask=#LVGF_GROUPID | #LVGF_ALIGN | #LVGF_HEADER | #LVGF_STATE
LVGROUP\uAlign=#LVGA_HEADER_LEFT
LVGROUP\iGroupId=GroupID
LVGROUP\pszHeader=*Text
LVGROUP\cchHeader=MemorySize(*Text)
;LVGROUP\state=2;8
;LVGROUP\statemask=LVGROUP\state
SendMessage_(*gadget\hwnd, #LVM_INSERTGROUP, -1, @LVGROUP)
FreeMemory(*Text)
Else
GroupID=Flags
CallFunctionFast(\VT\AddGadgetItem2, *gadget, Position, Text$, ImageID)
If Position=-1
Position=CountGadgetItems(\ID)-1
EndIf
Protected LVITEM.LVITEM
LVITEM\mask=#LVIF_GROUPID | #LVIF_STATE
LVITEM\iItem=Position
LVITEM\iSubItem=0
If SendMessage_(*gadget\hwnd, #LVM_GETITEM, 0, @LVITEM)
LVITEM\iGroupID=GroupID
SendMessage_(*gadget\hwnd, #LVM_SETITEM, 0, @LVITEM)
EndIf
EndIf
EndWith
EndIf
EndProcedure
Procedure LGP_RemoveGadgetItem(*gadget.GADGET, Position)
Protected *params.LGP_PARAMS=GetProp_(*gadget\hwnd, "GadgetInfo")
If *params
With *params
Protected GroupID
If Position<-1
GroupID=Position
SendMessage_(*gadget\hwnd, #LVM_REMOVEGROUP, GroupID, 0)
Else
CallFunctionFast(\VT\RemoveGadgetItem, *gadget, Position)
EndIf
EndWith
EndIf
EndProcedure
Procedure LGP_SetGadgetItemText(*gadget.GADGET, Position, Text$, Column)
Protected *params.LGP_PARAMS=GetProp_(*gadget\hwnd, "GadgetInfo")
If *params
With *params
Protected GroupID
If Position<-1
GroupID=Position
Protected LVGROUP.LVGROUP
LVGROUP\cbSize=SizeOf(LVGROUP)
LVGROUP\mask=#LVGF_HEADER | #LVGF_GROUPID
LVGROUP\iGroupId=GroupID
SendMessage_(*gadget\hwnd, #LVM_GETGROUPINFO, GroupID, @LVGROUP)
Text$=LSet(Text$, #ListIconGroup_TextLengthMax)
Protected *Text=LVGROUP\pszHeader
Protected lg=StringByteLength(Text$, #PB_Unicode)+2
PokeS(*Text, Text$, lg, #PB_Unicode)
Else
CallFunctionFast(\VT\SetGadgetItemText, *gadget, Position, Text$, Column)
EndIf
EndWith
EndIf
EndProcedure
Procedure LGP_SetGadgetItemAttribute(*gadget.GADGET, Item, Attribute, Value, Column=0)
Protected *params.LGP_PARAMS=GetProp_(*gadget\hwnd, "GadgetInfo")
If *params
With *params
If Attribute=#PB_ListIcon_ColumnWidth And Value=#PB_Ignore And Column=#PB_Ignore
;{/// RESIZE COLUMN : AUTOFILL
;column to fill (last column if none)
Column=\columnToFill
If Column=-1 : Column=\columns-1 : EndIf
;column width calculation
Protected col
Value=GadgetWidth(\ID)-5
For col=0 To \columns-1
If col=Column : Continue : EndIf
Value-GetGadgetItemAttribute(\ID, -1, #PB_ListIcon_ColumnWidth, col)
Next
If GetWindowLongPtr_(GadgetID(\ID), #GWL_STYLE) & #WS_VSCROLL
Value-GetSystemMetrics_(#SM_CXVSCROLL)
EndIf
;column width updating
\columnsRedraw=1
SetGadgetItemAttribute(\ID, -1, #PB_ListIcon_ColumnWidth, Value, Column)
\columnsRedraw=0
;fix scrollbar display
SendMessage_(*gadget\hwnd, #LVM_SCROLL, 0, 0)
;}
ElseIf Attribute=#PB_ListIcon_ColumnWidth And Value=#PB_Ignore And (Column>=0 And Column<\columns)
;{/// RESIZE COLUMN : AUTOSIZE
SetGadgetItemAttribute(\ID, -1, #PB_ListIcon_ColumnWidth, #LVSCW_AUTOSIZE, column)
;}
Else
;{/// RESIZE COLUMN : WIDTH
CallFunctionFast(\VT\SetGadgetItemAttribute2, *gadget, Item, Attribute, Value, Column)
;}
EndIf
EndWith
EndIf
EndProcedure
Procedure LGP_SortDefault(ID, Column, SortAsc, itemIndex1, itemIndex2, *GadgetItemData1, *GadgetItemData2)
Protected result
Protected A$=GetGadgetItemText(ID, itemIndex1, Column)
Protected B$=GetGadgetItemText(ID, itemIndex2, Column)
;not used - *GadgetItemData1
;not used - *GadgetItemData2
If A$=B$
result=0
ElseIf A$>B$
result=1
Else
result=-1
EndIf
If Not SortAsc
result=-result
EndIf
ProcedureReturn result
EndProcedure
Procedure LGP_SortList(*item1.PB_ListIcon_Item, *item2.PB_ListIcon_Item, *LGP_SORTING.LGP_SORTING)
Protected *LGP_ITEM1.LGP_ITEM=*item1\UserData
Protected *LGP_ITEM2.LGP_ITEM=*item2\UserData
With *LGP_SORTING
ProcedureReturn CallFunctionFast(\SortFunction, \ID, \Column, \SortAsc, *LGP_ITEM1\index, *LGP_ITEM2\index, *LGP_ITEM1\olddata, *LGP_ITEM2\olddata)
EndWith
EndProcedure
Procedure LGP_EditorCB(EditorWindow, Message, wParam, lParam)
Protected Window=GetParent_(EditorWindow)
Protected *params.LGP_PARAMS=GetProp_(Window, "GadgetInfo")
If *params
With *params
Protected EditorPos
Protected EditorCol
Protected EditorState
Select Message
Case #WM_KEYDOWN
;{/// EDITOR : CANCEL (by keypress)
If wParam=#VK_RETURN Or wParam=#VK_ESCAPE
EditorState=CallFunctionFast(\EditFunction, \ID, \EditorPos, \EditorCol, \Editor, #ListIconEditor_CancelEdit)
SendMessage_(Window, #LVM_EDITLABEL, EditorState, 0)
ProcedureReturn #True
EndIf
;}
Case #WM_KILLFOCUS
;{/// EDITOR : CANCEL (by focus)
If \EditFunction And IsGadget(\Editor)
EditorState=CallFunctionFast(\EditFunction, \ID, \EditorPos, \EditorCol, \Editor, #ListIconEditor_CancelEdit)
SendMessage_(Window, #LVM_EDITLABEL, EditorState, 0)
ProcedureReturn #False
EndIf
;}
EndSelect
ProcedureReturn CallWindowProc_(\EditorCB, EditorWindow, Message, wParam, lParam)
EndWith
EndIf
EndProcedure
Procedure LGP_CB(Window, Message, wParam, lParam)
Protected *params.LGP_PARAMS=GetProp_(Window, "GadgetInfo")
If *params
With *params
Select Message
;Case #WM_ERASEBKGND
;Case #WM_PAINT
;Case #LVM_SETCOLUMN, #LVM_SETCOLUMNA, #LVM_SETCOLUMNW
;Case #LVM_SETCOLUMNWIDTH, #LVM_SETCOLUMNWIDTHA, #LVM_SETCOLUMNWIDTHW
Case #WM_NCDESTROY
;{/// FREE GADGET
If \headerFlags=0
FreeMemory(\headerFlags)
EndIf
;}
Case #LVM_GETHEADER
;{/// COLUMN : PARAMETERS (\columnToFill)
Protected headerOrder
Protected Dim headerOrder(\columns)
SendMessage_(\header, #HDM_GETORDERARRAY, \Columns, @headerOrder())
\columnToFill=-1
For headerOrder=\Columns-1 To 0 Step -1
Protected *thisHeaderFlags.Integer=\headerFlags+headerOrder(headerOrder)*SizeOf(Integer)
If (*thisHeaderFlags\i & #ListIconHeader_AutoSize)
\columnToFill=headerOrder(headerOrder)
Break
EndIf
Next
;}
Case #LVM_INSERTCOLUMN, #LVM_INSERTCOLUMNA, #LVM_INSERTCOLUMNW, #LVM_DELETECOLUMN
;{/// COLUMN : ADD,REMOVE (\HeaderFlags, \Columns)
Protected *mem_s.Integer
Protected *mem_d.Integer
Protected mem_lg
Select Message
Case #LVM_DELETECOLUMN
Protected ColumnRemoved=wParam
If ColumnRemoved>=0 And ColumnRemoved<\Columns
;delete HeaderFlags entry
If ColumnRemoved<\Columns-1
*mem_s=\headerFlags+(ColumnRemoved+1)*SizeOf(Integer)
*mem_d=\headerFlags+(ColumnRemoved+0)*SizeOf(Integer)
mem_lg=(\Columns-ColumnRemoved-1)*SizeOf(Integer)
MoveMemory(*mem_s, *mem_d, mem_lg)
EndIf
;resize Columns and HeaderFlags
\columns-1
If \columns=0
FreeMemory(\headerFlags)
\headerFlags=0
Else
ReAllocateMemory(\headerFlags, \columns*SizeOf(Integer))
EndIf
EndIf
Default
Protected ColumnAdded=wParam
If ColumnAdded>=0
;resize Columns and HeaderFlags
\columns+1
If \columns=1
\headerFlags=AllocateMemory(\columns*SizeOf(Integer))
Else
ReAllocateMemory(\headerFlags, \columns*SizeOf(Integer))
EndIf
;insert HeaderFlags entry
If ColumnAdded<\Columns-1
*mem_s=\headerFlags+(ColumnAdded+0)*SizeOf(Integer)
*mem_d=\headerFlags+(ColumnAdded+1)*SizeOf(Integer)
mem_lg=(\Columns-ColumnAdded-1)*SizeOf(Integer)
MoveMemory(*mem_s, *mem_d, mem_lg)
*mem_s\i=0
EndIf
EndIf
EndSelect
;}
Case #LVM_SORTITEMS
;{/// COLUMN : SORTING
If lparam=#Null
;change item datas
Protected itemCount=CountGadgetItems(\ID)-1
Protected index
For index=0 To itemCount
Protected *LGP_ITEM.LGP_ITEM=AllocateMemory(SizeOf(LGP_ITEM))
*LGP_ITEM\olddata=GetGadgetItemData(\ID, index)
*LGP_ITEM\index=index
SetGadgetItemData(\ID, index, *LGP_ITEM)
Next
;sort column
SendMessage_(Window, #LVM_SORTITEMS, wParam, @LGP_SortList())
;restore item datas
For index=0 To itemCount
*LGP_ITEM.LGP_ITEM=GetGadgetItemData(\ID, index)
SetGadgetItemData(\ID, index, *LGP_ITEM\olddata)
FreeMemory(*LGP_ITEM)
Next
;refresh group if necessary
If SendMessage_(Window, #LVM_ISGROUPVIEWENABLED, 0, 0)
SendMessage_(Window, #WM_SETREDRAW, 0, 0)
SendMessage_(Window, #LVM_ENABLEGROUPVIEW, 0, 0)
SendMessage_(Window, #LVM_ENABLEGROUPVIEW, 1, 0)
SendMessage_(Window, #WM_SETREDRAW, 1, 0)
EndIf
ProcedureReturn #True
EndIf
;}
Case #WM_SIZE
;{/// COLUMN : AUTOFILLING (only if gadget is resizing)
If \columnToFill>-1 And Not \columnsRedraw
SetGadgetItemAttribute(\ID, -1, #PB_ListIcon_ColumnWidth, #PB_Ignore, #PB_Ignore)
EndIf
;}
Case #WM_LBUTTONDBLCLK
;{/// EDITOR : CHECKING
If \EditFunction
Protected EditorPos
Protected EditorCol
Protected EditorState
Protected lp=EventlParam()
Protected LVHITTESTINFO.LVHITTESTINFO
LVHITTESTINFO\pt\x=PeekW(@lp)
LVHITTESTINFO\pt\y=PeekW(@lp+SizeOf(word))
SendMessage_(Window, #LVM_SUBITEMHITTEST, 0, @LVHITTESTINFO)
EditorPos=LVHITTESTINFO\iItem
EditorCol=LVHITTESTINFO\iSubItem
EditorState=CallFunctionFast(\EditFunction, \ID, EditorPos, EditorCol, 0, #ListIconEditor_BeforeEdit)
If EditorState=#ListIconEditor_BeginEdit
SendMessage_(Window, #LVM_EDITLABEL, EditorPos, EditorCol)
EndIf
EndIf
;}
Case #LVM_EDITLABEL
;{/// EDITOR : OPEN
EditorPos=wParam
EditorCol=lParam
If IsGadget(\Editor)
Select EditorPos
Case #ListIconEditor_GetChanges
Case #ListIconEditor_ApplyChanges
SetGadgetItemText(\ID, \EditorPos, GetGadgetText(\Editor), \EditorCol)
FreeGadget(\Editor)
Case #ListIconEditor_CancelChanges
FreeGadget(\Editor)
EndSelect
EndIf
If EditorPos=#PB_Ignore
EditorPos=GetGadgetState(\ID)
EndIf
If EditorCol=#PB_Ignore
lp=EventlParam()
LVHITTESTINFO.LVHITTESTINFO
LVHITTESTINFO\pt\x=PeekW(@lp)
LVHITTESTINFO\pt\y=PeekW(@lp+SizeOf(word))
SendMessage_(Window, #LVM_SUBITEMHITTEST, 0, @LVHITTESTINFO)
EditorCol=LVHITTESTINFO\iSubItem
EndIf
If EditorPos>=0 And EditorPos<CountGadgetItems(\ID)
If EditorCol>=0 And EditorCol<\columns
Protected rc.RECT
rc\top=EditorCol
rc\left=#LVIR_BOUNDS
SendMessage_(Window, #LVM_GETSUBITEMRECT, EditorPos, @rc)
If EditorCol=0
rc\right=rc\left+SendMessage_(Window, #LVM_GETCOLUMNWIDTH, 0, 0)
EndIf
UseGadgetList(Window)
Protected Text$=GetGadgetItemText(\ID, EditorPos, EditorCol)
Protected x=rc\left
Protected y=rc\top
Protected w=rc\right-rc\left
Protected h=rc\bottom-rc\top
\Editor=StringGadget(#PB_Any, x, y, w, h, Text$, #ES_MULTILINE | #ES_AUTOVSCROLL)
\EditorCol=EditorCol
\EditorPos=EditorPos
\EditorCB=SetWindowLongPtr_(GadgetID(\Editor), #GWLP_WNDPROC, @LGP_EditorCB())
SetActiveGadget(\Editor)
EndIf
EndIf
ProcedureReturn 0
;}
Case #WM_NOTIFY
Protected *HD_NOTIFY.HD_NOTIFY=lParam
Protected Code=*HD_NOTIFY\hdr\code
Protected Column=*HD_NOTIFY\Iitem
Protected MouseButton=*HD_NOTIFY\iButton
Protected AutoResize=GetProp_(\header, "LGP_SetGadgetItemAttribute")
;Find header flags
If Column>=0 Or Column<\columns
Protected *headerFlags.Integer=\headerFlags+Column*SizeOf(Integer)
EndIf
Select code
;Case #HDN_ITEMCHANGED, #HDN_ITEMCHANGEDA, #HDN_ITEMCHANGEDW
;Case #HDN_ITEMCHANGING, #HDN_ITEMCHANGINGW, #HDN_ITEMCHANGINGA
;Case #HDN_TRACK
;Case #HDN_ENDDRAG
Case #HDN_BEGINDRAG
;{/// COLUMN HEADER : NODRAG
If (*headerFlags\i & #ListIconHeader_NoDrag)
SetCapture_(0)
ProcedureReturn #True
EndIf
;}
Case #HDN_ITEMCLICK, #HDN_ITEMCLICKW, #HDN_ITEMCLICKA
;{/// COLUMN HEADER : AUTOSIZE
If (*headerFlags\i & #ListIconHeader_AutoSize)
If \columnToFill=Column
SetGadgetItemAttribute(\ID, -1, #PB_ListIcon_ColumnWidth, #PB_Ignore, #PB_Ignore)
Else
SetGadgetItemAttribute(\ID, -1, #PB_ListIcon_ColumnWidth, #PB_Ignore, Column)
SetGadgetItemAttribute(\ID, -1, #PB_ListIcon_ColumnWidth, #PB_Ignore, #PB_Ignore)
EndIf
EndIf
;}
;{/// COLUMN HEADER : SORT (UP,DOWN,NONE)
If (*headerFlags\i & #ListIconHeader_Sort)
Protected HD_ITEM.HD_ITEM
Protected SortAsc
HD_ITEM\mask=#HDI_FORMAT
SendMessage_(\header, #HDM_GETITEM, Column, @HD_ITEM)
If (HD_ITEM\fmt & #HDF_SORTDOWN)
SortAsc=0
Else
SortAsc=1
EndIf
;sort single column
If (\SortSingleColumn)
Protected col
For col=0 To \columns-1
Protected *hf.Integer=\headerFlags+col*SizeOf(Integer)
If (*hf\i & #ListIconHeader_Sort)
*hf\i & ~#ListIconHeader_Sort_Up
*hf\i & ~#ListIconHeader_Sort_Down
*hf\i | #ListIconHeader_Sort_None
EndIf
Protected hi.HD_ITEM
hi\mask=#HDI_FORMAT
SendMessage_(\header, #HDM_GETITEM, col, @hi)
hi\fmt & ~#HDF_SORTUP & ~#HDF_SORTDOWN
SendMessage_(\header, #HDM_SETITEM, col, @hi)
Next
EndIf
;set arrow and flag
If SortAsc=1
HD_ITEM\fmt & ~#HDF_SORTUP | #HDF_SORTDOWN
SendMessage_(\header, #HDM_SETITEM, Column, @HD_ITEM)
*headerFlags\i & ~#ListIconHeader_Sort_None
*headerFlags\i & ~#ListIconHeader_Sort_Up
*headerFlags\i | #ListIconHeader_Sort_Down
Else
HD_ITEM\fmt & ~#HDF_SORTDOWN | #HDF_SORTUP
SendMessage_(\header, #HDM_SETITEM, Column, @HD_ITEM)
*headerFlags\i & ~#ListIconHeader_Sort_None
*headerFlags\i & ~#ListIconHeader_Sort_Down
*headerFlags\i | #ListIconHeader_Sort_Up
EndIf
;sort column
Protected LGP_SORTING.LGP_SORTING
LGP_SORTING\ID=\ID
LGP_SORTING\SortAsc=SortAsc
LGP_SORTING\Column=Column
LGP_SORTING\SortFunction=\SortFunction
SendMessage_(GadgetID(\ID), #LVM_SORTITEMS, @LGP_SORTING, #Null)
EndIf
;}
Case #HDN_BEGINTRACK, #HDN_BEGINTRACKA, #HDN_BEGINTRACKW, #HDN_DIVIDERDBLCLICK, #HDN_DIVIDERDBLCLICKA, #HDN_DIVIDERDBLCLICKW
;{/// COLUMN HEADER : FIXED
If (*headerFlags\i & #ListIconHeader_FixedSize) And Not \columnsRedraw
ProcedureReturn #True
EndIf
;}
;{/// COLUMN HEADER : DIVIDER MOVE
Select code
Case #HDN_BEGINTRACK, #HDN_BEGINTRACKA, #HDN_BEGINTRACKW
\columnsRedraw=1
EndSelect
;}
;{/// EDITOR : CANCEL (by divider)
If \EditFunction And IsGadget(\Editor)
EditorState=CallFunctionFast(\EditFunction, \ID, \EditorPos, \EditorCol, \Editor, #ListIconEditor_CancelEdit)
SendMessage_(Window, #LVM_EDITLABEL, EditorState, 0)
EndIf
;}
Case #HDN_ENDTRACK, #HDN_ENDTRACKA, #HDN_ENDTRACKW
;{/// COLUMN HEADER : DIVIDER STOP
\columnsRedraw=0
;}
EndSelect
EndSelect
ProcedureReturn CallWindowProc_(\CB, Window, Message, wParam, lParam)
EndWith
EndIf
EndProcedure
ProcedureDLL GetListIconColumns(ID) ;count listicon columns
Protected *gadget.GADGET=IsGadget(ID)
Protected *params.LGP_PARAMS=GetProp_(*gadget\hwnd, "GadgetInfo")
If *params
With *params
\columns=SendMessage_(\header, #HDM_GETITEMCOUNT, #Null, #Null)
ProcedureReturn \columns
EndWith
EndIf
EndProcedure
ProcedureDLL.b GetListIconColumnOrder(ID, Array ColumnsOrder(1)) ;get column order (ColumnOrder: an array of position)
Protected *gadget.GADGET=IsGadget(ID)
Protected *params.LGP_PARAMS=GetProp_(*gadget\hwnd, "GadgetInfo")
If *params
With *params
If \columns
ReDim ColumnsOrder(\columns-1)
If SendMessage_(\header, #HDM_GETORDERARRAY, \Columns, @ColumnsOrder())
ProcedureReturn #True
EndIf
EndIf
EndWith
EndIf
EndProcedure
ProcedureDLL SetListIconColumnOrder(ID, Array ColumnsOrder(1)) ;set column order (ColumnOrder: an array of position)
Protected *gadget.GADGET=IsGadget(ID)
Protected *params.LGP_PARAMS=GetProp_(*gadget\hwnd, "GadgetInfo")
If *params
With *params
If ArraySize(ColumnsOrder())=\Columns-1
SendMessage_(\header, #HDM_SETORDERARRAY, \Columns, @ColumnsOrder())
EndIf
EndWith
EndIf
EndProcedure
ProcedureDLL.b GetListIconGroupItems(ID, GroupID, Array GroupItems(1))
Protected *gadget.GADGET=IsGadget(ID)
Protected *params.LGP_PARAMS=GetProp_(*gadget\hwnd, "GadgetInfo")
If *params
With *params
Protected Position
Protected Index
For Position=0 To CountGadgetItems(ID)-1
Protected LVITEM.LVITEM
LVITEM\mask=#LVIF_GROUPID
LVITEM\iItem=Position
LVITEM\iSubItem=0
If SendMessage_(*gadget\hwnd, #LVM_GETITEM, 0, @LVITEM) And LVITEM\iGroupID=GroupID
Index=ArraySize(GroupItems())
GroupItems(Index)=Position
Index+1
ReDim GroupItems(Index)
EndIf
Next
If Index>0
ReDim GroupItems(Index-1)
ProcedureReturn #True
EndIf
EndWith
EndIf
EndProcedure
ProcedureDLL SetListIconGroupItems(ID, GroupID, Array GroupItems(1))
Protected *gadget.GADGET=IsGadget(ID)
Protected *params.LGP_PARAMS=GetProp_(*gadget\hwnd, "GadgetInfo")
If *params
With *params
Protected i
For i=0 To ArraySize(GroupItems())
Protected LVITEM.LVITEM
Protected Position=GroupItems(i)
LVITEM\mask=#LVIF_GROUPID | #LVIF_STATE
LVITEM\iItem=Position
LVITEM\iSubItem=0
If SendMessage_(*gadget\hwnd, #LVM_GETITEM, 0, @LVITEM)
LVITEM\iGroupID=GroupID
SendMessage_(*gadget\hwnd, #LVM_SETITEM, 0, @LVITEM)
EndIf
Next
EndWith
EndIf
EndProcedure
ProcedureDLL GetListIconGroupView(ID) ;get groupview state (#True if enabled)
ProcedureReturn SendMessage_(GadgetID(ID), #LVM_ISGROUPVIEWENABLED, 0, 0)
EndProcedure
ProcedureDLL SetListIconGroupView(ID, EnableListIconGroups.b) ;set groupview state (#True if enabled)
Protected Window=GadgetID(ID)
SendMessage_(Window, #WM_SETREDRAW, 0, 0)
SendMessage_(Window, #LVM_ENABLEGROUPVIEW, EnableListIconGroups, 0)
SendMessage_(Window, #WM_SETREDRAW, 1, 0)
EndProcedure
ProcedureDLL GetListIconHeader(ID, Column) ;get header flags
Protected *gadget.GADGET=IsGadget(ID)
Protected *params.LGP_PARAMS=GetProp_(*gadget\hwnd, "GadgetInfo")
If *params
With *params
;find column header
Protected *headerFlags.Integer=\headerFlags+Column*SizeOf(Integer)
ProcedureReturn *headerFlags\i
EndWith
EndIf
EndProcedure
ProcedureDLL SetListIconHeader(ID, Column, ListIconHeaderFlags=#PB_Ignore, ImageID=#PB_Ignore) ;set header options
Protected *gadget.GADGET=IsGadget(ID)
Protected *params.LGP_PARAMS=GetProp_(*gadget\hwnd, "GadgetInfo")
If *params
With *params
;Find header flags
If Column>=0 Or Column<\columns
Protected *headerFlags.Integer=\headerFlags+Column*SizeOf(Integer)
EndIf
;{/// HEADER FLAGS
Select ListIconHeaderFlags
Case #PB_Ignore
;do nothing
Case #ListIconHeader_Sort_Up, #ListIconHeader_Sort_Down, #ListIconHeader_Sort_None, #ListIconHeader_Sort_Disabled
;change only the sorting flags
*headerFlags\i & ~#ListIconHeader_Sort_Up
*headerFlags\i & ~#ListIconHeader_Sort_Down
*headerFlags\i & ~#ListIconHeader_Sort_None
If ListIconHeaderFlags<>#ListIconHeader_Sort_Disabled
*headerFlags\i | ListIconHeaderFlags
EndIf
Default
;change flags
*headerFlags\i=ListIconHeaderFlags
EndSelect
;}
;{/// HEADER DISPLAY
Protected HD_ITEM.HD_ITEM
HD_ITEM\mask=#HDI_FORMAT
If SendMessage_(\header, #HDM_GETITEM, Column, @HD_ITEM)
;show arrow
HD_ITEM\fmt & ~#HDF_SORTDOWN
HD_ITEM\fmt & ~#HDF_SORTUP
If (*headerFlags\i & #ListIconHeader_Sort_Down)=#ListIconHeader_Sort_Down
HD_ITEM\fmt | #HDF_SORTDOWN
ElseIf (*headerFlags\i & #ListIconHeader_Sort_Up)=#ListIconHeader_Sort_Up
HD_ITEM\fmt | #HDF_SORTUP
EndIf
;show image
If ImageID<>#PB_Ignore
If ImageID=0
HD_ITEM\fmt & ~#HDF_BITMAP
HD_ITEM\iImage=-1
Else
#HDF_BITMAP_ON_RIGHT=$1000
HD_ITEM\fmt | #HDF_RIGHT | #HDF_BITMAP_ON_RIGHT
HD_ITEM\iImage=-1
HD_ITEM\hbm=ImageID
EndIf
EndIf
SendMessage_(\header, #HDM_SETITEM, Column, @HD_ITEM)
EndIf
;}
SendMessage_(*gadget\hwnd, #LVM_GETHEADER, 0, 0)
EndWith
EndIf
EndProcedure
ProcedureDLL SetListIconEditFunction(ID, *EditFunction)
Protected *gadget.GADGET=IsGadget(ID)
Protected *params.LGP_PARAMS=GetProp_(*gadget\hwnd, "GadgetInfo")
If *params
With *params
;define sort function
Select *EditFunction
Case 0
\EditFunction=#Null
Default
\EditFunction=*EditFunction
EndSelect
EndWith
EndIf
EndProcedure
ProcedureDLL SetListIconSortFunction(ID, SingleSortArrow.b, *SortFunction=#PB_Ignore) ;set sorting mode and define function to use
Protected *gadget.GADGET=IsGadget(ID)
Protected *params.LGP_PARAMS=GetProp_(*gadget\hwnd, "GadgetInfo")
If *params
With *params
;define sort function
Select *SortFunction
Case #PB_Ignore
Case 0
\SortFunction=@LGP_SortDefault()
Default
\SortFunction=*SortFunction
EndSelect
;define sort mode
\SortSingleColumn=SingleSortArrow
EndWith
EndIf
EndProcedure
ProcedureDLL SortListIcon(ID, Column, SortAsc.b) ;sort listicon items (in Ascending order if SortAsc=1)
Protected *gadget.GADGET=IsGadget(ID)
Protected *params.LGP_PARAMS=GetProp_(*gadget\hwnd, "GadgetInfo")
If *params
With *params
;sort column
Protected LGP_SORTING.LGP_SORTING
LGP_SORTING\ID=\ID
LGP_SORTING\SortAsc=SortAsc
LGP_SORTING\Column=Column
LGP_SORTING\SortFunction=\SortFunction
SendMessage_(GadgetID(\ID), #LVM_SORTITEMS, @LGP_SORTING, #Null)
EndWith
EndIf
EndProcedure
ProcedureDLL.s EditListIcon(ID, Position=#PB_Ignore, Column=#PB_Ignore)
Protected *gadget.GADGET=IsGadget(ID)
Protected *params.LGP_PARAMS=GetProp_(*gadget\hwnd, "GadgetInfo")
If *params
With *params
If IsGadget(\Editor)
Protected EditorPos=Position
Protected EditorCol=Column
Select EditorPos
Case #ListIconEditor_GetChanges
ProcedureReturn GetGadgetText(\Editor)
Case #ListIconEditor_ApplyChanges
SetGadgetItemText(\ID, \EditorPos, GetGadgetText(\Editor), \EditorCol)
FreeGadget(\Editor)
ProcedureReturn GetGadgetItemText(\ID, \EditorPos, \EditorCol)
Case #ListIconEditor_CancelChanges
FreeGadget(\Editor)
ProcedureReturn
EndSelect
EndIf
SendMessage_(*gadget\hwnd, #LVM_EDITLABEL, Position, Column)
EndWith
EndIf
EndProcedure
ProcedureDLL ListIconGadgetPlus(ID, x, y, Width, Height, Title$, TitleWidth, Flags=0) ; create listicon gadget
;gadget
If IsGadget(ID) : FreeGadget(ID) : EndIf
Protected result=ListIconGadget(ID, x, y, Width, Height, Title$, TitleWidth, Flags)
If result=0 : ProcedureReturn 0 : EndIf
If ID=#PB_Any : ID=result : EndIf
;set commands
Protected *gadget.GADGET=IsGadget(ID)
With *gadget
Static LGP_GADGETVT_NEW.GADGET_VT
Static LGP_GADGETVT_OLD.GADGET_VT
If LGP_GADGETVT_OLD\AddGadgetColumn=0
LGP_GADGETVT_OLD\AddGadgetColumn=\VT\AddGadgetColumn
LGP_GADGETVT_OLD\SetGadgetItemAttribute2=\VT\SetGadgetItemAttribute2
LGP_GADGETVT_OLD\AddGadgetItem2=\VT\AddGadgetItem2
LGP_GADGETVT_OLD\AddGadgetItem3=\VT\AddGadgetItem3
LGP_GADGETVT_OLD\RemoveGadgetItem=\VT\RemoveGadgetItem
LGP_GADGETVT_OLD\SetGadgetItemText=\VT\SetGadgetItemText
LGP_GADGETVT_OLD\GetGadgetItemText=\VT\GetGadgetItemText
LGP_GADGETVT_OLD\SetGadgetItemState=\VT\SetGadgetItemState
LGP_GADGETVT_OLD\GetGadgetItemState=\VT\GetGadgetItemState
CopyMemory(\VT, @LGP_GADGETVT_NEW, SizeOf(GADGET_VT))
LGP_GADGETVT_NEW\AddGadgetColumn=@LGP_AddGadgetColumn()
LGP_GADGETVT_NEW\SetGadgetItemAttribute2=@LGP_SetGadgetItemAttribute()
LGP_GADGETVT_NEW\AddGadgetItem2=@LGP_AddGadgetItem()
LGP_GADGETVT_NEW\AddGadgetItem3=@LGP_AddGadgetItem()
LGP_GADGETVT_NEW\RemoveGadgetItem=@LGP_RemoveGadgetItem()
LGP_GADGETVT_NEW\SetGadgetItemText=@LGP_SetGadgetItemText()
LGP_GADGETVT_NEW\GetGadgetItemText=@LGP_GetGadgetItemText()
;LGP_GADGETVT_NEW\SetGadgetItemState=@LGP_SetGadgetItemState()
;LGP_GADGETVT_NEW\GetGadgetItemState=@LGP_GetGadgetItemState()
EndIf
\VT=@LGP_GADGETVT_NEW
EndWith
;set parameters
Protected *LGP_PARAMS.LGP_PARAMS=AllocateMemory(SizeOf(LGP_PARAMS))
With *LGP_PARAMS
\ID=ID
\CB=GetWindowLongPtr_(GadgetID(ID), #GWL_WNDPROC)
\VT=@LGP_GADGETVT_OLD
\header=SendMessage_(GadgetID(ID), #LVM_GETHEADER, 0, 0)
\headerFlags=AllocateMemory(1*SizeOf(Integer))
\columns=1
\columnToFill=-1
\SortFunction=@LGP_SortDefault()
\SortSingleColumn=#True
SetProp_(GadgetID(ID), "GadgetInfo", *LGP_PARAMS)
EndWith
;set callback
SetWindowLongPtr_(GadgetID(ID), #GWL_WNDPROC, @LGP_CB())
;if AUTOFILL first column
If TitleWidth=#PB_Ignore
SetGadgetItemAttribute(ID, 0, #PB_ListIcon_ColumnWidth, #PB_Ignore, #PB_Ignore)
EndIf
ProcedureReturn result
EndProcedure