Sign in to follow this  
Followers 0
rexx

Sort a subtree in treeview

4 posts in this topic

Hi,

I want to know how to sort a subtree in treeview.

I use _GUICtrlTreeView_Sort($hWnd) but it only sort the root tree.

Also found this but it sorts all, what i what is sort only a specified (the selected) subtree.

I tried to use the subtree item handle as $hWnd but nothing changed.

Thanks in advance.

Share this post


Link to post
Share on other sites



Try this:

#include <GUIConstantsEx.au3>
#Include <GuiTreeView.au3>
#include <Array.au3>
Local $gui, $tv, $bt, $r_desc, $hSel, $desc, $aItem[4]

$gui = GUICreate('test')
$tv = GUICtrlCreateTreeView(10, 10, 200, 300)
$aItem[0] = GUICtrlCreateTreeViewItem('Item_1', $tv)
$aItem[1] = GUICtrlCreateTreeViewItem('Item_2', $tv)
$aItem[2] = GUICtrlCreateTreeViewItem('Item_3', $tv)
$aItem[3] = GUICtrlCreateTreeViewItem('Item_4', $tv)
For $i = 0 To 3
    For $n = 1 To 10
        GUICtrlCreateTreeViewItem(_GetRandomStr(8), $aItem[$i])
    Next
Next
$bt = GUICtrlCreateButton('sort selected Item', 220, 10, 150, 20)
GUICtrlCreateGroup('', 220, 40, 170, 40)
GUICtrlCreateRadio('ascending', 230, 55, 70)
GUICtrlSetState(-1, $GUI_CHECKED)
$r_desc = GUICtrlCreateRadio('descending', 305, 55, 80)
GUISetState()

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case -3
            Exit
        Case $bt
            $hSel = _GUICtrlTreeView_GetSelection($tv)
            $desc = 0
            If BitAND(GUICtrlRead($r_desc), $GUI_CHECKED) Then $desc = 1
            If $hSel Then _sortOneParent($tv, $hSel, $desc)
    EndSwitch
WEnd

Func _sortOneParent($hWnd, $hSel, $desc=0) ; sorts ascending, with $desc=1 sorts descending
    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)
    Local $hChild = _GUICtrlTreeView_GetFirstChild($hWnd, $hSel)
    If Not $hChild Then Return
    Local $arhwndChild[1] = [$hChild], $artextChild[1] = [_GUICtrlTreeView_GetText($hWnd, $hChild)]
    While 1
        $hChild = _GUICtrlTreeView_GetNextSibling($hWnd, $hChild)
        If Not $hChild Then ExitLoop
        ReDim $arhwndChild[UBound($arhwndChild)+1]
        ReDim $artextChild[UBound($artextChild)+1]
        $arhwndChild[UBound($arhwndChild)-1] = $hChild
        $artextChild[UBound($artextChild)-1] = _GUICtrlTreeView_GetText($hWnd, $hChild)
    WEnd
    _ArraySort($artextChild, $desc)
    _GUICtrlTreeView_BeginUpdate($hWnd)
    For $i = 0 To UBound($arhwndChild) -1
        _GUICtrlTreeView_SetText($hWnd, $arhwndChild[$i], $artextChild[$i])
    Next
    _GUICtrlTreeView_EndUpdate($hWnd)
EndFunc

Func _GetRandomStr($len)
    Local $aChar = StringSplit('01234AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz56789','')
    Local $str = ''
    For $i = 1 To $len
        $str &= $aChar[Random(1,$aChar[0],1)]
    Next
    Return $str
EndFunc

Best Regards BugFix  

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Thanks!

But if there're multi level submenu it goes wrong.

it only changed the text, but it didn't move an item's children.

for example

#include <GUIConstantsEx.au3>
#Include <GuiTreeView.au3>
#include <Array.au3>
Local $gui, $tv, $bt, $r_desc, $hSel, $desc, $aItem[4]

$gui = GUICreate('test')
$tv = GUICtrlCreateTreeView(10, 10, 200, 300)
$aItem[0] = GUICtrlCreateTreeViewItem('Item_1', $tv)
$aItem[1] = GUICtrlCreateTreeViewItem('Item_2', $tv)
$aItem[2] = GUICtrlCreateTreeViewItem('Item_3', $aItem[1])
$aItem[3] = GUICtrlCreateTreeViewItem('Item_4', $aItem[2])
For $i = 0 To 3
    For $n = 1 To 10
        GUICtrlCreateTreeViewItem(_GetRandomStr(8), $aItem[$i])
    Next
Next
$bt = GUICtrlCreateButton('sort selected Item', 220, 10, 150, 20)
GUICtrlCreateGroup('', 220, 40, 170, 40)
GUICtrlCreateRadio('ascending', 230, 55, 70)
GUICtrlSetState(-1, $GUI_CHECKED)
$r_desc = GUICtrlCreateRadio('descending', 305, 55, 80)
GUISetState()

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case -3
            Exit
        Case $bt
            $hSel = _GUICtrlTreeView_GetSelection($tv)
            $desc = 0
            If BitAND(GUICtrlRead($r_desc), $GUI_CHECKED) Then $desc = 1
            If $hSel Then _sortOneParent($tv, $hSel, $desc)
    EndSwitch
WEnd

Func _sortOneParent($hWnd, $hSel, $desc=0) ; sorts ascending, with $desc=1 sorts descending
    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)
    Local $hChild = _GUICtrlTreeView_GetFirstChild($hWnd, $hSel)
    If Not $hChild Then Return
    Local $arhwndChild[1] = [$hChild], $artextChild[1] = [_GUICtrlTreeView_GetText($hWnd, $hChild)]
    While 1
        $hChild = _GUICtrlTreeView_GetNextSibling($hWnd, $hChild)
        If Not $hChild Then ExitLoop
        ReDim $arhwndChild[UBound($arhwndChild)+1]
        ReDim $artextChild[UBound($artextChild)+1]
        $arhwndChild[UBound($arhwndChild)-1] = $hChild
        $artextChild[UBound($artextChild)-1] = _GUICtrlTreeView_GetText($hWnd, $hChild)
    WEnd
    _ArraySort($artextChild, $desc)
    _GUICtrlTreeView_BeginUpdate($hWnd)
    For $i = 0 To UBound($arhwndChild) -1
        _GUICtrlTreeView_SetText($hWnd, $arhwndChild[$i], $artextChild[$i])
    Next
    _GUICtrlTreeView_EndUpdate($hWnd)
EndFunc

Func _GetRandomStr($len)
    Local $aChar = StringSplit('01234AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz56789','')
    Local $str = ''
    For $i = 1 To $len
        $str &= $aChar[Random(1,$aChar[0],1)]
    Next
    Return $str
EndFunc
Edited by rexx

Share this post


Link to post
Share on other sites

I found it's easier than i think.

just call

DllCall('user32.dll','int','SendMessage','hwnd',$hWnd,'uint',$TVM_SORTCHILDREN,'wparam',true,'lparam',$hItem)

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