Sorting Multicolumn Listview

BlitzMax Forums/MaxGUI Module/Sorting Multicolumn Listview

andre72(Posted 2007) [#1]
I tried to modify the code by Zitch (some changes done by Cardonic) to make a Listview sortable.
An easy way to do (but like it seems also to difficult for me :) ) I found in a VB example: http://www.microsoft.com/germany/msdn/library/visualtools/vb6/ListViewZeilenInVisualBasicKorrektSortieren.mspx?mfr=true

The code itself works and if you rem out the SortListView after the event occurs anything is fine.
Only the sort routines itself are a little bit buggy ...
The program crashes here:
Return CallWindowProc(oldListProc, hWnd, MSG, wParam, Int(Byte Ptr(lParam))) : Unhandled Memory Exception Error

but like I said, only when SortListView is called.

I know that the code is ugly (I mean my additional one no offence to the code I just copied) but this will be changed when there's a working example.

 
Strict 

Extern "win32" 
   Function SendMessage:Int(hWnd:Int,MSG:Int,wParam:Int,lParam:Int) = "SendMessageA@16" 
   Function SetWindowLong:Int(hWnd:Int,nIndex:Int,lNewLong:Int) = "SetWindowLongA@12" 
   Function GetWindowLong:Int(hWnd:Int, nIndex:Int) = "GetWindowLongA@8" 
   Function CallWindowProc:Int(lpPrevWndFunc, hWnd, uMsg, wParam, lParam) = "CallWindowProcA@20" 
End Extern 

Const LBS_NOTIFY:Int            = $1 
Const LBS_SORT:Int              = $2 
Const LBS_NOREDRAW:Int          = $4 
Const LBS_MULTIPLESEL:Int       = $8 
Const LBS_OWNERDRAWFIXED:Int    = $10 
Const LBS_OWNERDRAWVARIABLE:Int = $20 
Const LBS_HASSTRINGS:Int        = $40 
Const LBS_USETABSTOPS:Int       = $70 
Const LBS_NOINTEGRALHEIGHT:Int  = $100 
Const LBS_MULTICOLUMN:Int       = $200 
Const LBS_WANTKEYBOARDINPUT:Int = $400 
Const LBS_EXTENDEDSEL:Int       = $800 
Const LBS_DISABLENOSCROLL:Int   = $100 
Const LBS_NODATA:Int            = $2000 
Const LBS_NOSEL:Int             = $4000 
Const LBS_STANDARD:Int          = $a00003 

Const LVM_FIRST:Int = $1000 
Const LVM_GETITEMA:Int          = (LVM_FIRST+5) 
Const LVM_SETITEMA:Int          = (LVM_FIRST+6) 
Const LVM_INSERTITEMA:Int       = (LVM_FIRST+7) 
Const LVM_DELETEITEM:Int        = (LVM_FIRST+8) 
Const LVM_DELETEALLITEMS:Int    = (LVM_FIRST+9) 
Const LVM_GETCALLBACKMASK:Int   = (LVM_FIRST+10) 
Const LVM_SETCALLBACKMASK:Int   = (LVM_FIRST+11) 
Const LVM_GETCOLUMNA:Int        = (LVM_FIRST+25) 
Const LVM_SETCOLUMNA:Int        = (LVM_FIRST+26) 
Const LVM_INSERTCOLUMNA:Int     = (LVM_FIRST+27) 
Const LVM_DELETECOLUMN:Int      = (LVM_FIRST+28) 
Const LVM_GETCOLUMNWIDTH:Int    = (LVM_FIRST+29) 
Const LVM_SETCOLUMNWIDTH:Int    = (LVM_FIRST+30) 
Const LVM_GETTEXTCOLOR:Int      = (LVM_FIRST+35) 
Const LVM_SETTEXTCOLOR:Int      = (LVM_FIRST+36) 
Const LVM_GETTEXTBKCOLOR:Int    = (LVM_FIRST+37) 
Const LVM_SETTEXTBKCOLOR:Int    = (LVM_FIRST+38) 
Const LVM_SORTITEMS:Int         = (LVM_FIRST+48) 
Const LVM_SETLISTBOXEXSTYLE:Int = (LVM_FIRST+54) 
Const LVM_GETITEMW:Int          = (LVM_FIRST+75) 
Const LVM_SETITEMW:Int          = (LVM_FIRST+76) 
Const LVM_INSERTITEMW:Int       = (LVM_FIRST+77) 
Const LVM_GETCOLUMNW:Int        = (LVM_FIRST+95) 
Const LVM_SETCOLUMNW:Int        = (LVM_FIRST+96) 
Const LVM_INSERTCOLUMNW:Int     = (LVM_FIRST+97) 

Const LVS_EX_GRIDLINES:Int        = $1 
Const LVS_EX_SUBITEMIMAGES:Int    = $2 
Const LVS_EX_CHECKBOXES:Int       = $4 
Const LVS_EX_TRACKSELECT:Int      = $8 
Const LVS_EX_HEADERDRAGDROP:Int   = $10 
Const LVS_EX_FULLROWSELECT:Int    = $20 
Const LVS_EX_ONECLICKACTIVATE:Int = $40 
Const LVS_EX_TWOCLICKACTIVATE:Int = $80 
Const LVS_EX_FLATSB:Int           = $100 
Const LVS_EX_REGIONAL:Int         = $200 
Const LVS_EX_INFOTIP:Int          = $400 
Const LVS_EX_UNDERLINEHOT:Int     = $800 
Const LVS_EX_UNDERLINECOLD:Int    = $1000 
Const LVS_EX_MULTIWORKAREAS:Int   = $2000 
Const LVS_EX_LABELTIP:Int         = $4000 
Const LVS_EX_BORDERSELECT:Int     = $8000 
Const LVS_EX_DOUBLEBUFFER:Int     = $10000 
Const LVS_EX_HIDELABELS:Int       = $20000 
Const LVS_EX_SINGLEROW:Int        = $40000 
Const LVS_EX_SNAPTOGRID:Int       = $80000 
Const LVS_EX_SIMPLESELECT:Int     = $100000 

Const LVCF_FMT:Int     = $1 
Const LVCF_WIDTH:Int   = $2 
Const LVCF_TEXT:Int    = $4 
Const LVCF_SUBITEM:Int = $8 
Const LVCF_IMAGE:Int   = $10 
Const LVCF_ORDER:Int   = $20 

Const LVIF_TEXT:Int        = $1 
Const LVIF_IMAGE:Int       = $2 
Const LVIF_PARAM:Int       = $4 
Const LVIF_STATE:Int       = $8 
Const LVIF_INDENT:Int      = $10 
Const LVIF_GROUPID:Int     = $100 
Const LVIF_COLUMNS:Int     = $200 
Const LVIF_NORECOMPUTE:Int = $800  
Const LVIF_DI_SETITEM:Int  = $1000 

Const LVS_ALIGNTOP:Int        = $0 
Const LVS_ICON:Int            = $0 
Const LVS_REPORT:Int          = $1 
Const LVS_SMALLICON:Int       = $2 
Const LVS_LIST:Int            = $3 
Const LVS_TYPEMASK:Int        = $3 
Const LVS_SINGLESEL:Int       = $4 
Const LVS_SHOWSELALWAYS:Int   = $8 
Const LVS_SORTASCENDING:Int   = $10 
Const LVS_SORTDESCENDING:Int  = $20 
Const LVS_SHAREIMAGELISTS:Int = $40 
Const LVS_NOLABELWRAP:Int     = $80 
Const LVS_AUTOARRANGE:Int     = $100 
Const LVS_EDITLABELS:Int      = $200 
Const LVS_OWNERDRAWFIXED:Int  = $400 
Const LVS_ALIGNLEFT:Int       = $800 
Const LVS_ALIGNMASK:Int       = $C00 
Const LVS_NOSCROLL:Int        = $2000 
Const LVS_NOCOLUMNHEADER:Int  = $4000 
Const LVS_NOSORTHEADER:Int    = $8000 
Const LVS_TYPESTYLEMASK:Int   = $FC00 

Const GWL_STYLE:Int = -$10 
Const HDN_ITEMCLICK:Int = -302 
Const GWL_WNDPROC:Int = -4 
Const WM_NOTIFY = 78 
Const HDN_ITEMCLICKW = -322 

Type  LVCOLUMN  
   Field mask:Int 
   Field fmt:Int 
   Field cx:Int 
   Field pszText:Byte Ptr 
   Field cchTextMax:Int 
   Field iSubItem:Int 
EndType 

Type LVITEM 
   Field mask:Int 
   Field iItem:Int 
   Field iSubItem:Int 
   Field iState:Int 
   Field stateMask:Int 
   Field pszText:Byte Ptr 
   Field cchTextMax:Int 
   Field iImage:Int 
   Field lParam:Byte Ptr 
   Field iIndent:Int 
   Field iGroupId:Int 
   Field cColumns:Int 
   Field puColumns:Int 
EndType 

Type HD_NOTIFY 
'Field hdr:Byte Ptr ' NMHDR 
   Field hwndFrom 
   Field idFrom 
   Field code 
   Field iItem 
   Field iButton 
   Field pitem 
EndType 

Type LVWSORT 
  Field hWndListView:Int  ' Fensterhandle des ListView-Controls 
  Field SortKey:Int       ' Spalte, die sortiert werden soll 
  Field SortType:Int ' Typ der zu sortierenden Daten 
  Field SortOrder:Int ' Sortierrichtung 
End Type 

Const lvwAscending:Int = 0     ' Aufsteigende Sortierung 
Const lvwDescending:Int = 1  ' Absteigende Sortierung 

Const stString:Int = 1     ' Stringsortierung 
Const stDate:Int = 2       ' Datensortierung 
Const stNumeric:Int = 3     ' Zahlensortierung 

Const LVM_FINDITEM:Int = (LVM_FIRST + 13) 
Const LVFI_PARAM:Int = $1 

Type POINTAPI ' ben�tigt f�r LV_FINDINFO 
  Field x:Int 
  Field y:Int 
End Type 

Type LV_FINDINFO 
  Field flags:Int 
  Field psz:String 
  Field lParam:Int 
  Field pt:POINTAPI 
  Field vkDirection:Long 
End Type 

Const LVM_GETITEMTEXT:Int = (LVM_FIRST + 45) 

Function AddListBoxColumn(ListBox:TGadget, ColumnNr:Int, Width:Int) 
   Local ListBoxHwnd:Int = QueryGadget(ListBox,QUERY_HWND) 
   Local Column:LVColumn = New LVColumn 
   Column.mask = LVCF_WIDTH 
   Column.cx = Width 
   SendMessageA(ListBoxHwnd,LVM_INSERTCOLUMNA,ColumnNr,Int(Byte Ptr Column)) 
End Function 

Function SetListBoxHeading(ListBox:TGadget,ColumnNr:Int,HeadingText:String,Style:Int=0) 
   Local ListBoxHwnd:Int = QueryGadget(ListBox,QUERY_HWND) 
   Local Column:LVColumn = New LVColumn 
   Column.mask = LVCF_TEXT | LVCF_FMT 
   Column.fmt = Style 
   Column.pszText = HeadingText.ToCString() 
   Local ListBoxStyle:Int = GetWindowLongA(ListBoxHwnd,GWL_STYLE) 
   If (ListBoxStyle & LVS_NOCOLUMNHEADER ) Then 
      ListBoxStyle = ListBoxStyle ~ LVS_NOCOLUMNHEADER 
      SetWindowLongA(ListBoxHwnd,GWL_STYLE,ListBoxStyle) 
   EndIf 
   SendMessageA(ListBoxHwnd,LVM_SETCOLUMNA,ColumnNr,Int(Byte Ptr Column)) 
End Function 

Function SetListBoxColumnWidth(ListBox:TGadget,ColumnNr:Int,Width:Int) 
   Local ListBoxHwnd:Int = QueryGadget(ListBox,QUERY_HWND) 
   Local Column:LVColumn = New LVColumn 
   Column.mask = LVCF_WIDTH 
   Column.cx = Width 
   SendMessageA(ListBoxHwnd,LVM_SETCOLUMNA,ColumnNr,Int(Byte Ptr Column)) 
End Function 

Function ModifyListBoxItem(ListBox:TGadget,RowNr:Int,ColumnNr:Int,Text:String) 
   Local ListBoxHwnd:Int = QueryGadget(ListBox,QUERY_HWND) 
   Local Item:LVItem = New LVItem 
   Item.mask = LVIF_TEXT 
   Item.iSubItem = ColumnNr 
   Item.iItem = RowNr 
   Item.pszText = Text.ToCString() 
   Item.cchTextMax = Text.Length+1 
   SendMessageA(ListBoxHwnd,LVM_SETITEMA,0,Int(Byte Ptr Item)) 
End Function 

Function GetListBoxItemText:String(ListBox:TGadget,RowNr:Int,ColumnNr:Int) 
   Local ListBoxHwnd:Int = QueryGadget(ListBox,QUERY_HWND) 
   Local ReturnText:String 
   Local TextBank:TBank = CreateBank(1024) 
   Local Item:LVItem = New LVItem 
   Item.mask = LVIF_Text 
   Item.iSubItem = ColumnNr 
   Item.iItem = RowNr 
   Item.pszText = BankBuf(TextBank) 
   Item.cchTextMax = 255 
   SendMessageA(ListBoxHwnd,LVM_GETITEMA,0,Int(Byte Ptr Item)) 
   If Item.pszText <> Null Then 
      ReturnText = ReturnText.FromCString(Item.pszText) 
   EndIf 
   Return ReturnText 
End Function 

Function SetListBoxExtendedStyle(ListBox:TGadget,Style:Int) 
   Local ListBoxHwnd:Int = QueryGadget(ListBox,QUERY_HWND) 
   SendMessageA(ListBoxHwnd,LVM_SETLISTBOXEXSTYLE,Style,Style) 
End Function 

Function SetListBoxMultiSelect(ListBox:TGadget, Enable:Byte = True) 
   Local ListBoxHwnd:Int = QueryGadget(ListBox,QUERY_HWND) 
   Local ListBoxStyle:Int = GetWindowLongA(ListboxHwnd,GWL_STYLE) 
   If Sgn(ListBoxStyle & LVS_SINGLESEL) = Enable Then 
      ListBoxStyle = ListBoxStyle ~ LVS_SINGLESEL 
   EndIf 
   SetWindowLongA(ListBoxHwnd,GWL_STYLE,ListBoxStyle) 
End Function 

Function NewListProc:Int(hWnd:Int, Msg:Int, wParam:Int, lParam:Int) "win32" 

   If MSG = WM_NOTIFY Then 
      Local NotifyMess:HD_NOTIFY = New HD_NOTIFY 

      MemCopy(Byte Ptr(NotifyMess), Byte Ptr(lParam), SizeOf(HD_NOTIFY)) 
      'DebugLog "hwndFrom  " + NotifyMess.hwndFrom 
      'DebugLog "idFrom  " + NotifyMess.idFrom 
      'DebugLog "code " + NotifyMess.code 
      'DebugLog "iItem " + NotifyMess.iitem 
      'DebugLog "iButton  " + NotifyMess.iButton 
      'DebugLog "pitem  " + NotifyMess.pitem 

      If NotifyMess.code = HDN_ITEMCLICKW Then 
         Local event:TEvent = New TEvent 
         event.id = HDN_ITEMCLICKW 
         event.source = ActiveGadget() 
         event.data = NotifyMess.iitem 
            PostEvent(event) 
         'DebugLog(NotifyMess.iitem) 
         EndIf 
   EndIf 

   If oldListProc <> 0 Then 
         DebugLog "MSG: " + MSG 
         DebugLog "hWnd: " + hwnd 
         DebugLog "wParam: " + wParam 
         DebugLog "lParam: " + lParam 
      Return CallWindowProc(oldListProc, hWnd, MSG, wParam, Int(Byte Ptr(lParam))) 
   EndIf 
EndFunction 

Function SortListView:Int(ListBox:TGadget, SortKey:Int, SortType:Int = stString, SortOrder:Int = lvwAscending) 
' ----------------------------------------------------- 
' &#65533;ffentlich aufzurufende Prozedur SortListView, die 
' f&#65533;r die individuelle Sortierung einer ListView-Spalte 
' sorgt. 
' ----------------------------------------------------- 
' hWndListView: Fensterhandle des ListView-Steuerelements 
' SortKey:      Spalte (nullbasiert), die sortiert werden 
'               soll (= Spaltennummer - 1). 
' SortType:     stString, um Strings zu sortieren (Standardwert) 
'               stDate, um Datumsangaben zu sortieren 
'               stNumeric, um Zahlen zu sortieren 
' SortOrder:    lvwAscending f&#65533;r aufsteigende Sortierung (Std.) 
'               lvwDescending f&#65533;r absteigende Sortierung 
' ----------------------------------------------------- 
  ' &#65533;bergebene Informationen in einer LVWSORT- 
  ' Struktur zusammenfassen: 
     Local udtLVWSORT:LVWSORT = New LVWSORT 
    udtLVWSORT.hWndListView = QueryGadget(ListBox, QUERY_HWND) 
    udtLVWSORT.SortKey = SortKey 
    udtLVWSORT.SortOrder = SortOrder 
    udtLVWSORT.SortType = SortType 

  ' Eigene Sortierfunktionalit&#65533;t in der Funktion 
  ' CompareFunc verwenden: Die Informationen der 
  ' LVWSORT-Struktur wird mithilfe eines Zeigers 
  ' auf die Variable udtLVWSORT beigegeben: 
  SendMessage QueryGadget(ListBox, QUERY_HWND), LVM_SORTITEMS, Int(Byte Ptr(udtLVWSORT)), Int(Byte ptr(CompareFunc)) 
End Function 

Function CompareFunc:Int(lParam1:Int, lParam2:Int, lParamSort:Int) 
' ----------------------------------------------------- 
' Vergleichsfunktion CompareFunc 
' ----------------------------------------------------- 
' Verglichen werden jeweils zwei Elemente der zu 
' sortierenden Spalte des ListView-Steuerelements, 
' die &#65533;ber lParam1 und lParam2 angegeben werden. 
' Hierbei wird &#65533;ber den R&#65533;ckgabewert der Funktion 
' bestimmt, welches der beiden Elemente als gr&#65533;&#65533;er 
' gelten soll (hier f&#65533;r Aufw&#65533;rtssortierung): 
' * Element 1 < Element 2: R&#65533;ckgabewert < 0 
' * Element 1 = Element 2: R&#65533;ckgabewert = 0 
' * Element 1 > Element 2: R&#65533;ckgabewert > 0 
' ----------------------------------------------------- 

Local ListViewSort:LVWSORT = New LVWSORT 
Local sEntry1:String 
Local sEntry2:String 
Local vCompare1:VARIANT 
Local vCompare2:VARIANT 
  ' In lParamSort von SortListView als Long-Pointer 
  ' &#65533;bergebene LVWSORT-Struktur abholen, um auf deren 
  ' Werte zugreifen zu k&#65533;nnen: 
  MemCopy(Byte Ptr(ListViewSort), Byte Ptr(lParamSort), SizeOf(ListViewSort)) 

  ' Die Werte der zu vergleichenden Elemente werden 
  ' mithilfe der privaten Funktion LvwGetText aus 
  ' den Angaben lParam1 und lParam2 ermittelt: 

  sEntry1 = LvwGetText(ListViewSort, lParam1) 
  sEntry2 = LvwGetText(ListViewSort, lParam2) 
  DebugLog sEntry1 + " " + sEntry2 

  ' Sind die Elemente gleich, kann die Funktion 
  ' sofort mit dem aktuellen R&#65533;ckgabewert 0 
  ' verlassen werden: 
  If sEntry1 = sEntry2 Then 
      Return 
  End If 
  ' F&#65533;r die Sortierung wird unterschieden zwischen 
  ' Daten, Zahlen und allgemeinen Strings. Hierf&#65533;r 
  ' steht jeweils eine separate, private Vergleichs- 
  ' funktion zur Verf&#65533;gung. 


    Select ListViewSort.SortType 
    Case stDate    ' Spalteninhalte sind Datumswerte 
      'CompareFunc = CompareDates(sEntry1, sEntry2, ListViewSort.SortOrder) 
    Case stNumeric ' Spalteninhalte sind Zahlen 
      'CompareFunc = CompareNumbers(sEntry1, sEntry2, ListViewSort.SortOrder) 
    Case stString  ' Spalteninhalte sind Strings 
      Local CompareFunc:Int = CompareStrings(sEntry1, sEntry2, ListViewSort.SortOrder) 
  End Select 

End Function 

Function LvwGetText:String(ListViewSort:LVWSORT, lParam:Int) 
' ----------------------------------------------------- 
' Ermittelt aus dem Fensterhandle des ListView- 
' Steuerelements, der in ListViewSort.SortKey 
' angegebenen (nullbasierten) Spalte im ListView 
' und der an CompareFunc &#65533;bergebenen Werte lParam1/2 
' die davon repr&#65533;sentierten Zelleninhalte. 
' ----------------------------------------------------- 

Local udtFindInfo:LV_FINDINFO = New LV_FINDINFO 
Local udtLVItem:LVITEM = New LVITEM 
Local lngIndex:Int 
'Local baBuffer:Byte[512] 
Local TextBank:TBank = CreateBank(1024) 
Local lngLength:Int 
Local ReturnText:String 

  ' Den Index der Zelle aus lParam ermitteln: 
  udtFindInfo.flags = LVFI_PARAM 
  udtFindInfo.lParam = lParam 
  
  lngIndex = SendMessage(ListViewSort.hWndListView, LVM_FINDITEM, - 1, Int(Byte Ptr(udtFindInfo))) 
  ' Auf Basis des gefundenen Index den Text der Zelle 
  ' in ein Byte-Array &#65533;bertragen: 

    udtLVItem.mask = LVIF_TEXT 
    udtLVItem.iSubItem = ListViewSort.SortKey 
    udtLVItem.pszText = BankBuf(TextBank) 
   'Int(VarPtr(baBuffer[0] )) 
    udtLVItem.cchTextMax = 255 

  'lngLength = SendMessage(ListViewSort.hWndListView, LVM_GETITEMTEXT, lngIndex, Int(Byte Ptr(udtLVItem))) 
  ' Byte-Array in passender L&#65533;nge als String- 
  ' R&#65533;ckgabewert kopieren: 
  If lngLength > 0 Then 
   ReturnText = ReturnText.FromCString(udtLVItem.pszText) 
   DebugLog lngLength + " " + ReturnText 
   Return ReturnText 
    'LvwGetText = Left:String(StrConv(baBuffer, vbUnicode), lngLength) 
  End If 

End Function 


Function CompareStrings:Int(sEntry1:String, sEntry2:String, SortOrder:Int) 
' ----------------------------------------------------- 
' Gibt zurück, ob das erste der beiden unterschiedlichen 
' Elemente nach Maßgabe des Parameters SortOrder größer 
' (1 bei aufsteigender Sortierung) oder kleiner (-1 bei 
' aufsteigender Sortierung) als das zweite Element ist. 
' Gleiche Elemente wurden bereits in CompareFunc ausge- 
' schlossen; für sie wäre sonst 0 zurückzugeben. 
' ----------------------------------------------------- 
  ' Rückgabewert je nach erwünschter Sortierung: 
  If SortOrder = lvwAscending Then 
    ' Aufsteigende Sortierung zweier unterschiedlicher Strings 
    If sEntry1 < sEntry2 Then 
      Return - 1 
    Else 
      Return 1 
    End If 
  Else ' Absteigende Sortierung 
    If sEntry1 > sEntry2 Then 
      Return - 1 
    Else 
      Return 1 
    End If 
  End If 
End Function 

Local Window:TGadget = CreateWindow("Erweiterte ListBox f&#65533;r BMax", 100, 100, 500, 300, Null, 1) 
Local ListBox:TGadget = CreateListBox(2,2,ClientWidth(Window)-4,ClientHeight(Window)-4,Window) 

Local ListBoxExtendedStyle:Int = LVS_EX_GRIDLINES | LVS_EX_CHECKBOXES '| LVS_EX_FLATSB 
'SetListBoxExtendedStyle(ListBox,ListBoxExtendedStyle) 

AddListBoxColumn(ListBox,1,100) 
AddListBoxColumn(ListBox,2,100) 
AddListBoxColumn(ListBox,3,100) 
AddListBoxColumn(ListBox,4,100) 

SetListBoxHeading(ListBox,1,"T") 
SetListBoxHeading(ListBox,2,"E") 
SetListBoxHeading(ListBox,3,"S") 
SetListBoxHeading(ListBox,4,"T") 

Global oldListProc 
oldListProc = SetWindowLongA(QueryGadget(ListBox, QUERY_HWND), GWL_WNDPROC, Int(Byte Ptr(NewListProc))) 

For Local Row:Int = 0 To 29 
   AddGadgetItem(ListBox,Row) 
   For Local Column:Int = 1 To 4 
      ModifyListBoxItem(ListBox, Row, Column, "Item " + Row + "/" + Column) 
   Next 
Next 

ModifyListBoxItem(ListBox,10,0,"blubb") 
RemoveGadgetItem(ListBox,5) 

Local SelectedItem:Int 
Repeat 

   Select WaitEvent() 
     Case HDN_ITEMCLICKW 
      SortListView ListBox, EventData() 
       
      'DebugLog "Row " + EventData() + " had been clicked" 
    
      Case EVENT_GADGETACTION 
         SelectedItem = SelectedGadgetItem(ListBox) 
         Print "SelectedItem "+SelectedItem 
         Print GetListBoxItemText(ListBox,SelectedItem,0) 
         Print GetListBoxItemText(ListBox,SelectedItem,1) 
         Print GetListBoxItemText(ListBox,SelectedItem,2) 
         Print GetListBoxItemText(ListBox,SelectedItem,3) 
         Print GetListBoxItemText(ListBox,SelectedItem,4) 
      Case EVENT_WINDOWCLOSE 
         End 
   End Select 

Forever


Thanks

Andre


Ziltch(Posted 2007) [#2]
This look like you are trying to use Microsofts listview sorting.

I had this going a few versions of maxgui ago, but a maxgui change to get tooltips working used the lparam field in the listview structure. As lparam is used for sorting, MS sort routines no longer work.

this is briefly talked about here.

http://www.blitzbasic.com/Community/posts.php?topic=61318#686941


andre72(Posted 2007) [#3]
Thanks Ziltch - as you wrote you'd allready a working version of sorting?
Ok I understand that the tooltip make it broken and the last post in the topic was about a fix...
This was about one year ago - any news about?