Jump to content

trigger listview sort callback function (GUICtrlRegisterListViewSort())


Go to solution Solved by argumentum,

Recommended Posts

Hi!

i'm using GUICtrlRegisterListViewSort() with a custum sort callback function to compare/sort dates (in column 3).

I know about _GUICtrlListView_SortItems() with _GUICtrlListView_RegisterSortCallBack(), but that 'simple sort function' and will not work correctly with dates, right?

is it possible to re-sort a listview after adding items to it?

example:

#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <GuiListView.au3>

Global $g_iCurCol = -1
Global $g_iSortDir = 1
Global $g_bSet = False
Global $g_iCol = -1

Example()

Func Example()
    GUICreate("Test", 300, 200)

    Local $idLv = GUICtrlCreateListView("Column1|Col2|Col3", 10, 10, 280, 150)
    GUICtrlRegisterListViewSort(-1, "LVSort") ; Register the function "SortLV" for the sorting callback

    GUICtrlCreateListViewItem("ABC|666|10.05.2004", $idLv)
    GUICtrlSetImage(-1, "shell32.dll", 7)
    GUICtrlCreateListViewItem("DEF|444|11.05.2005", $idLv)
    GUICtrlSetImage(-1, "shell32.dll", 12)
    GUICtrlCreateListViewItem("CDE|444|12.05.2004", $idLv)
    GUICtrlSetImage(-1, "shell32.dll", 3)

    $idBtn = GUICtrlCreateButton('add item', 10, 166, 280, 28)

    GUISetState(@SW_SHOW)

    Local $idMsg
    ; Loop until the user exits.
    While 1
        $idMsg = GUIGetMsg()
        Switch $idMsg
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $idLv
                $g_bSet = False
                $g_iCurCol = $g_iCol
                GUICtrlSendMsg($idLv, $LVM_SETSELECTEDCOLUMN, GUICtrlGetState($idLv), 0)
;~                 DllCall("user32.dll", "int", "InvalidateRect", "hwnd", GUICtrlGetHandle($idLv), "int", 0, "int", 1)
            Case $idBtn
                GUICtrlCreateListViewItem("BCD|333|13.05.2001", $idLv)
                GUICtrlSetImage(-1, "shell32.dll", 5)

                ; ################################
                ; RE-SORT ITEMS NOW! BUT HOW?
                ; ################################
        EndSwitch
    WEnd

    GUIDelete()
EndFunc   ;==>Example

; Our sorting callback funtion
Func LVSort($hWnd, $nItem1, $nItem2, $iColumn)
    Local $sVal1, $sVal2, $iResult

    ; Switch the sorting direction
    If $iColumn = $g_iCurCol Then
        If Not $g_bSet Then
            $g_iSortDir = $g_iSortDir * -1
            $g_bSet = True
        EndIf
    Else
        $g_iSortDir = 1
    EndIf
    $g_iCol = $iColumn

    $sVal1 = GetSubItemText($hWnd, $nItem1, $iColumn)
    $sVal2 = GetSubItemText($hWnd, $nItem2, $iColumn)

    ; If it is the 3rd colum (column starts with 0) then compare the dates
    If $iColumn = 2 Then
        $sVal1 = StringRight($sVal1, 4) & StringMid($sVal1, 4, 2) & StringLeft($sVal1, 2)
        $sVal2 = StringRight($sVal2, 4) & StringMid($sVal2, 4, 2) & StringLeft($sVal2, 2)
    EndIf

    $iResult = 0 ; No change of item1 and item2 positions

    If $sVal1 < $sVal2 Then
        $iResult = -1 ; Put item2 before item1
    ElseIf $sVal1 > $sVal2 Then
        $iResult = 1 ; Put item2 behind item1
    EndIf

    $iResult = $iResult * $g_iSortDir

    Return $iResult
EndFunc   ;==>LVSort

; Retrieve the text of a listview item in a specified column
Func GetSubItemText($idCtrl, $idItem, $iColumn)
    Local $tLvfi = DllStructCreate("uint;ptr;int;int[2];int")

    DllStructSetData($tLvfi, 1, $LVFI_PARAM)
    DllStructSetData($tLvfi, 3, $idItem)

    Local $tBuffer = DllStructCreate("char[260]")

    Local $nIndex = GUICtrlSendMsg($idCtrl, $LVM_FINDITEM, -1, DllStructGetPtr($tLvfi));

    Local $tLvi = DllStructCreate("uint;int;int;uint;uint;ptr;int;int;int;int")

    DllStructSetData($tLvi, 1, $LVIF_TEXT)
    DllStructSetData($tLvi, 2, $nIndex)
    DllStructSetData($tLvi, 3, $iColumn)
    DllStructSetData($tLvi, 6, DllStructGetPtr($tBuffer))
    DllStructSetData($tLvi, 7, 260)

    GUICtrlSendMsg($idCtrl, $LVM_GETITEMA, 0, DllStructGetPtr($tLvi));

    Local $sItemText = DllStructGetData($tBuffer, 1)

    Return $sItemText
EndFunc   ;==>GetSubItemText

I really appreciate any help you guys can provide!

Link to comment
Share on other sites

you could add an additional column, hide the additional column, put the dates as Integer ( 20151231 ) and tell it to sort from there. ( my .02 cents )  

 

heh, that's pretty clever!

another way to solve this is.. create copies of GUICtrlListView_SortItems(), _GUICtrlListView_RegisterSortCallBack() and __GUICtrlListView_Sort() and implement whatever you need!

dirty, but its working :)

thank you for your reply!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...