Hi, here's some code to allow items sorting by clicking on the column label of a ListIconGadget. I know the code looks quite ugly with all that mixing of Asm/PB (and some of the Asm is not really needed, it's there only for speed and practicing), but it works.
It can be easily adapted to sort ListView gadgets internally (ListView and ListIcon are quite the same thing for Windows). If someone wants to translate this mess into something human-readable, you're welcome (Fred, is there any other way to use a custom callback function? I'm talking about the CompareFunc, not the Window callback, procedure won't work as arguments are not retrieved if not called from the PB code).
Code: Select all
#LVM_SETEXTENDEDLISTVIEWSTYLE = #LVM_FIRST + 54
#LVM_GETEXTENDEDLISTVIEWSTYLE = #LVM_FIRST + 55
#LVS_EX_GRIDLINES = 1
#LVS_EX_FULLROWSELECT = $20
Global ListIconGadget.l, Buffer1.l, Buffer2.l, lvi.LV_ITEM, lParamSort.l, updown.l, lastcol.l
Buffer1 = AllocateMemory(0, 128, 0)
Buffer2 = AllocateMemory(1, 128, 0)
returnaddress.l
item1.l
item2.l
!jmp jmpproc
CompareFunc:
! pop dword [v_returnaddress]
! pop dword [v_item1]
! pop dword [v_item2]
! pop dword [v_lParamSort]
lvi\iSubItem = lParamSort
lvi\pszText = Buffer1
lvi\cchTextMax = 128
lvi\mask = #LVIF_TEXT
SendMessage_(ListIconGadget, #LVM_GETITEMTEXT, item1, @lvi)
lvi\pszText = Buffer2
SendMessage_(ListIconGadget, #LVM_GETITEMTEXT, item2, @lvi)
! compare:
! push ecx
! mov eax, [v_Buffer1]
! mov edx, [v_Buffer2]
! .upcase1:
! mov cl, [eax]
! cmp cl, "a"
! jb .upcase2
! cmp cl, "z"
! ja .upcase2
! sub cl, 32
! .upcase2:
! mov ch, [edx]
! cmp ch, "a"
! jb .upcased
! cmp ch, "z"
! ja .upcased
! sub ch, 32
! .upcased:
! cmp cl, ch
! ja .above
! jb .below
! inc eax
! inc edx
! Or cl, ch
! jnz .upcase1
! xor eax, eax
! jmp .endcompare
! .above:
! mov eax, [v_updown]
! jmp .endcompare
! .below:
! mov eax, [v_updown]
! neg eax
! .endcompare:
! pop ecx
! jmp [v_returnaddress]
!jmpproc:
Procedure UpdatelParam()
ItemCount = SendMessage_(ListIconGadget, #LVM_GETITEMCOUNT, 0, 0)
lvi\mask = #LVIF_PARAM
lvi\iItem = 0
While ItemCount>0
lvi\lParam = lvi\iItem
For SubItem = 0 To 3
lvi\iSubItem = SubItem
SendMessage_(ListIconGadget, #LVM_SETITEM, 0, @lvi)
Next SubItem
lvi\iItem = lvi\iItem+1
ItemCount = ItemCount-1
Wend
EndProcedure
Procedure ColumnClickCallback(WindowID, Message, wParam, lParam)
If Message = #WM_NOTIFY
*msg.NMHDR = lParam
If *msg\hwndFrom = ListIconGadget And *msg\code = #LVN_COLUMNCLICK
*pnmv.NM_LISTVIEW = lParam
If lastcol*pnmv\iSubItem
updown = 1
EndIf
SendMessage_(ListIconGadget, #LVM_SORTITEMS, *pnmv\iSubItem, ?CompareFunc)
UpdatelParam()
UpdateWindow_(ListIconGadget)
lastcol = *pnmv\iSubItem
updown = -updown
EndIf
EndIf
EndProcedure
InitGadget(1)
If OpenWindow(0, #CW_USEDEFAULT, #CW_USEDEFAULT, #CW_USEDEFAULT, #CW_USEDEFAULT, #PB_Window_SystemMenu|#PB_Window_MinimizeGadget, "ListIconGadget sort example")
LVWidth = WindowWidth()-4
LVCWidth = Int(LVWidth/4-1)
If CreateGadgetList(WindowID())
ListIconGadget = ListIconGadget(0, 0, 0, LVWidth, WindowHeight()-30, "Column 0", LVCWidth)
AddGadgetColumn(0, 1, "Column 1", LVCWidth)
AddGadgetColumn(0, 2, "Column 2", LVCWidth)
AddGadgetColumn(0, 3, "Column 3", LVCWidth)
EndIf
SendMessage_(ListIconGadget, #LVM_SETEXTENDEDLISTVIEWSTYLE, #LVS_EX_GRIDLINES, -1) ; show grid lines
SendMessage_(ListIconGadget, #LVM_SETEXTENDEDLISTVIEWSTYLE, #LVS_EX_FULLROWSELECT, -1) ; the entire row is highlighted when the item is selected
AddListIconGadgetItem(0, 0, "Aaa 1"+Chr(10)+"Bcc 3"+Chr(10)+"Cdd 2"+Chr(10)+"Eee 3"+Chr(10), 0)
AddListIconGadgetItem(0, 1, "Aab 2"+Chr(10)+"Bbc 2"+Chr(10)+"Ddd 3"+Chr(10)+"Dde 1"+Chr(10), 0)
AddListIconGadgetItem(0, 2, "Abb 3"+Chr(10)+"Baa 1"+Chr(10)+"Ccd 1"+Chr(10)+"Dee 2"+Chr(10), 0)
updown = 1
lastcol = 0
UpdatelParam()
SetWindowCallback(@ColumnClickCallback())
Repeat
EventID.l = WaitWindowEvent()
Select EventID
Case #PB_EventCloseWindow
Quit = 1
EndSelect
Until Quit = 1
EndIf
End
El_Choni