Sign in to follow this  
Followers 0
tilb

Sorting Treeview

4 posts in this topic

Hi,

Is it possible to sort a treeview using descending mode (Z -> A).

The UDF _GUICtrlTreeView_Sort() can only sort ascending (A -> Z).

Thanks a lot for your help !

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

The most direct AutoIt way would be to keep your data in some other array, sort it, and rebuild the tree view.

If you want to get down and geeky on it, look at the _GUICtrlTreeView_Sort() function in the GuiTreeView.au3 UDF. It calls a Windows API to do the the sort with TVM_SORTCHILDREN. To have your own sorting function called by windows, use TVM_SORTCHILDRENCB instead and provide a callback from DllCallbackRegister(). If you search the forum, maybe you'll find examples already done.

GUICtrlRegisterListViewSort() must do something similar, but for ListView controls.

:mellow:

Edit: Typo. And Authenticity does 'da demo! :P

Edited by PsaltyDS

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

#AutoIt3Wrapper_au3check_parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#include <GuiConstantsEx.au3>
#include <GuiTreeView.au3>
#include <WindowsConstants.au3>

Opt('MustDeclareVars', 1)

$Debug_TV = False ; Check ClassName being passed to functions, set to True and use a handle to another control to see it work

Global Const $TVSORTCB = "ptr Parent;ptr Compare;lparam SortParam;"

_Main()

Func _Main()

    Local $hItem[10], $hChildItem[30], $hGrandChildItem[90], $hGrandGrantChildItem[180]
    Local $iCItem = 0, $iGCItem = 0, $IGGCItem = 0, $i1 = 10, $i2 = 30, $i3 = 90, $i4 = 180
    Local $hTreeView, $hFunc
    Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS)

    GUICreate("TreeView Sort", 400, 300)

    $hTreeView = GUICtrlCreateTreeView(2, 2, 396, 268, $iStyle, $WS_EX_CLIENTEDGE)
    _GUICtrlTreeView_SetUnicodeFormat($hTreeView, True)
    GUISetState()

    _GUICtrlTreeView_BeginUpdate($hTreeView)
    For $a = 0 To 9
        $hItem[$a] = GUICtrlCreateTreeViewItem(StringFormat("[%02d] New Item", $i1), $hTreeView)
        For $b = 1 To 3
            $hChildItem[$iCItem] = GUICtrlCreateTreeViewItem(StringFormat("[%02d] New Child", $i2), $hItem[$a])
            For $c = 1 To 3
                $hGrandChildItem[$iGCItem] = GUICtrlCreateTreeViewItem(StringFormat("[%02d] New GrandChild", $i3), $hChildItem[$iCItem])
                For $d = 1 To 2
                    $hGrandGrantChildItem[$IGGCItem] = GUICtrlCreateTreeViewItem(StringFormat("[%03d] New GrandGrandChild", $i4), $hGrandChildItem[$iGCItem])
                    $IGGCItem += 1
                    $i4 -= 1
                Next
                $iGCItem += 1
                $i3 -= 1
            Next
            $iCItem += 1
            $i2 -= 1
        Next
        $i1 -= 1
    Next
    _GUICtrlTreeView_Expand($hTreeView)
    _GUICtrlTreeView_EndUpdate($hTreeView)
    _GUICtrlTreeView_SelectItem($hTreeView, $hItem[0])

    $hFunc = DllCallbackRegister("_CompareFunc", "int", "lparam;lparam;lparam")
    MsgBox(4160, "Information", "Sorting ascending")
    _GUICtrlTreeView_BeginUpdate($hTreeView)
    __GUICtrlTreeView_Sort($hTreeView, $hFunc)
    _GUICtrlTreeView_EndUpdate($hTreeView)
    _GUICtrlTreeView_SelectItem($hTreeView, $hItem[9])
    MsgBox(4160, "Information", "Sorting descending")
    _GUICtrlTreeView_BeginUpdate($hTreeView)
    __GUICtrlTreeView_Sort($hTreeView, $hFunc, False)
    _GUICtrlTreeView_EndUpdate($hTreeView)
    _GUICtrlTreeView_SelectItem($hTreeView, $hItem[0])

    ; Loop until user exits
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    DllCallbackFree($hFunc)
    GUIDelete()
EndFunc   ;==>_Main

Func _CompareFunc($ilParam1, $ilParam2, $fAscending)
    Local $sText1, $sText2, $iCompare

    $sText1 = GUICtrlRead($ilParam1, 1)
    $sText2 = GUICtrlRead($ilParam2, 1)

    $iCompare = StringCompare($sText1, $sText2) ; case-insensitive
    If $fAscending Then ; Ascending case
        If $iCompare < 0 Then ; Text1 < Text2 so return -1 (Item1 should precede Item2)
            Return -1
        ElseIf $iCompare > 0 Then ; Text2 < Text1 so return 1 (Item2 should precede Item1)
            Return 1
        Else ; Text1 = Text2 so return 0 (don't swap)
            Return 0
        EndIf
    Else ; Descending case
        If $iCompare > 0 Then ; Text1 > Text2 so return -1 (Item1 should precede Item2)
            Return -1
        ElseIf $iCompare < 0 Then ; Text2 > Text1 so return 1 (Item2 should precede Item1)
            Return 1
        Else ; Text1 = Text2 so return 0 (don't swap)
            Return 0
        EndIf
    EndIf
EndFunc ; _CompareFunc

Func __GUICtrlTreeView_Sort($hWnd, $hFunc, $fAscending = True)
    If $Debug_TV Then __UDF_ValidateClassName($hWnd, $__TREEVIEWCONSTANT_ClassName)

    Local $pFunc = DllCallbackGetPtr($hFunc)
    If $pFunc = 0 Then Return SetError(1, 0, False)

    Local $tSort, $pSort

    $tSort = DllStructCreate($TVSORTCB)
    $pSort = DllStructGetPtr($tSort)

    ; lparam = 1 sort ascending
    ; lparam = 0 sort descending
    DllStructSetData($tSort, "SortParam", $fAscending) ; It's up to the callback function to do whatever it wants to do with SortParam
    DllStructSetData($tSort, "Compare", $pFunc)

    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)

    Local $hItem = _SendMessage($hWnd, $TVM_GETNEXTITEM, $TVGN_CHILD, $TVI_ROOT, 0, "wparam", "handle", "handle")
    If Not $hItem Then Return

    While $hItem
        If _GUICtrlTreeView_GetChildren($hWnd, $hItem) Then
            DllStructSetData($tSort, "Parent", $hItem)
            _SendMessage($hWnd, $TVM_SORTCHILDRENCB, 0, $pSort, 0, "wparam", "ptr")
        EndIf
        $hItem = _GUICtrlTreeView_GetNext($hWnd, $hItem)
    WEnd
    DllStructSetData($tSort, "Parent", $TVI_ROOT)
    _SendMessage($hWnd, $TVM_SORTCHILDRENCB, 0, $pSort, 0, "wparam", "ptr")

    Return SetError(0, 0, True)
EndFunc

Share this post


Link to post
Share on other sites

Hi,

Thanks for your answers. I use the PsaltyDS's way, and it works great.

Bye,

Share this post


Link to post
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
Sign in to follow this  
Followers 0