Jump to content
Sign in to follow this  
rexx

Sort a subtree in treeview

Recommended Posts

rexx

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
BugFix

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
rexx

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
rexx

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  

×