Jump to content

Recommended Posts

Posted (edited)

Hello,

I just bumped into this problem with _GUICtrlTreeView_Sort.

Just used doc example and comment out the child creation

#include <GUIConstantsEx.au3>
#include <GuiTreeView.au3>
#include <MsgBoxConstants.au3>
#include <WindowsConstants.au3>

Example()

Func Example()
    Local $aidItem[10], $iX = 9, $iY = 29, $idTreeView
    Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS)

    GUICreate("TreeView Sort", 400, 300)

    $idTreeView = GUICtrlCreateTreeView(2, 2, 396, 268, $iStyle, $WS_EX_CLIENTEDGE)
    GUISetState(@SW_SHOW)

    _GUICtrlTreeView_BeginUpdate($idTreeView)
    For $x = 0 To 3
        $aidItem[$x] = GUICtrlCreateTreeViewItem(StringFormat("[%02d] New Item", $iX), $idTreeView)
        $iX -= 1
        For $y = 1 To 3
       ;     GUICtrlCreateTreeViewItem(StringFormat("[%02d] New Child", $iY), $aidItem[$x])
            $iY -= 1
        Next
    Next
    _GUICtrlTreeView_Expand($idTreeView)
    _GUICtrlTreeView_EndUpdate($idTreeView)

    MsgBox($MB_SYSTEMMODAL, "Information", "Sort")
    _GUICtrlTreeView_Sort($idTreeView)
    _GUICtrlTreeView_SelectItem($idTreeView, $aidItem[9])

    ; Boucle jusqu'à ce que l'utilisateur quitte.
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    GUIDelete()
EndFunc   ;==>Example

The tree is not sorted.

 

There is a similar problem with deeper tree

Also based on the example

#include <GUIConstantsEx.au3>
#include <GuiTreeView.au3>
#include <MsgBoxConstants.au3>
#include <WindowsConstants.au3>

Example()

Func Example()
    Local $aidItem[10], $bidItem[10], $iX = 9, $iY = 29, $idTreeView
    Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS)

    GUICreate("TreeView Sort", 400, 300)

    $idTreeView = GUICtrlCreateTreeView(2, 2, 396, 268, $iStyle, $WS_EX_CLIENTEDGE)
    GUISetState(@SW_SHOW)

    _GUICtrlTreeView_BeginUpdate($idTreeView)
    $index=0
    For $x = 0 To 3
        $aidItem[$x] = GUICtrlCreateTreeViewItem(StringFormat("[%02d] New Item", $iX), $idTreeView)
        $iX -= 1
        For $y = 1 To 2
            $BidItem[$y]= GUICtrlCreateTreeViewItem(StringFormat("[%02d] New Child", $iY), $aidItem[$x])
            $iY -= 1
            For $z= 1 To 2
            GUICtrlCreateTreeViewItem(StringFormat("[%02d] New Child", $iY), $BidItem[$y])
            $iY -= 1
        Next
        Next

    Next
    _GUICtrlTreeView_Expand($idTreeView)
    _GUICtrlTreeView_EndUpdate($idTreeView)

    MsgBox($MB_SYSTEMMODAL, "Information", "Sort")
    _GUICtrlTreeView_Sort($idTreeView)
    _GUICtrlTreeView_SelectItem($idTreeView, $aidItem[9])

    ; Boucle jusqu'à ce que l'utilisateur quitte.
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    GUIDelete()
EndFunc   ;==>Example

The tree is now 2 level deep and it is not properly sorted.

 

Any advices ?

 

Regards

Edited by gillesg
Posted

Sorry, I started to look at this then ran out of time.... Let me get you started with what I found.

Make a backup of GuiTreeView.au3 in your includes directory.

Search for Func _GUICtrlTreeView_Sort($hWnd)

;where you see this line:

_SendMessage($hWnd, $TVM_SORTCHILDREN, $iRecursive, $aTreeView[$i], 0, "wparam", "handle") ; Sort the items in root

;Add this line immediately before it:

_SendMessage($hWnd, $TVM_SORTCHILDREN, $iRecursive, 0, 0, "wparam", "handle")

For some reason the recursion does not appear to get back to 0. This seemed to work for the first part of your problem... hth sorry I can't stay to the end!

Problem solving step 1: Write a simple, self-contained, running, replicator of your problem.

Posted

Treeview_Sort doesn't sort the root items, it only sorts the children of each root item. If you want to sort the root items, then you need to use _GUITreeView_InsertItem and set the parameter $hItem_After to $TVI_SORT.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Posted

All, 

Thanks for giving me the tracks to solve it.

In the UDF the loop to walk thru the tree does not work.

Just using _GUICtrlTreeView_GetNext instead of _SendMessage($hWnd, $TVM_GETNEXTITEM, $TVGN_NEXT..

make the trick.

So here is a simple fix. But on large tree t is not optimised. it sorts all single leaves of the tree.

; #FUNCTION# ====================================================================================================================
; Author ........: Gary Frost (gafrost)
; Modified.......: mlipok, guinness, gillesg
; First fix not optimized ===============================================================================================================================
Func _GUICtrlTreeView_Sort2($hWnd)
    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)

    Local $iItemCount = _GUICtrlTreeView_GetCount($hWnd)
    If $iItemCount Then
        Local $aTreeView[$iItemCount], $hItem = 0, $i=0
        ; Walk through TreeView items
        Local $hHandle = _GUICtrlTreeView_GetFirstItem($hWnd)
        While 1
            ; Add item to array
            $aTreeView[$i] = $hHandle
            ; increase count
            $i += 1
            ; Move to next item
            $hHandle = _GUICtrlTreeView_GetNext($hWnd, $hHandle)
            ; Exit if at end
            If $hHandle = 0 Then ExitLoop
        WEnd

        Local $hChild = 0, $iRecursive = 1
        _SendMessage($hWnd, $TVM_SORTCHILDREN, $iRecursive, 0, 0, "wparam", "handle") ; Sort the items in root


        For $i = 0 To $iItemCount - 1
            _SendMessage($hWnd, $TVM_SORTCHILDREN, $iRecursive, $aTreeView[$i], 0, "wparam", "handle") ; Sort the items in root
            Do ; Sort all child items
                $hChild = _SendMessage($hWnd, $TVM_GETNEXTITEM, $TVGN_CHILD, $hItem, 0, "wparam", "handle", "handle")
                If $hChild Then
                    _SendMessage($hWnd, $TVM_SORTCHILDREN, $iRecursive, $hChild, 0, "wparam", "handle")
                EndIf
                $hItem = $hChild
            Until $hItem = 0x00000000
        Next
    EndIf
EndFunc   ;==>_GUICtrlTreeView_Sort2

 

On large tree we can reduce trasticly the number of sort orders sent.

; #FUNCTION# ====================================================================================================================
; Author ........: Gary Frost (gafrost)
; Modified.......: mlipok, guinness, gillesg
; Ths time optimized ===============================================================================================================================
Func _GUICtrlTreeView_Sort3($hWnd)
    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)

    Local $iItemCount = _GUICtrlTreeView_GetCount($hWnd)
    If $iItemCount Then
        Local $aTreeView[$iItemCount], $i=0
        ; get only A child at each level
        Local $hHandle = _GUICtrlTreeView_GetFirstItem($hWnd)
        $aTreeView[1]=$hHandle
        $aTreeView[0]=2
        __GUICtrlTreeView_SortGetFirstChild($hWnd, $hHandle, $aTreeView )
        redim $aTreeView[$aTreeView[0]]
        $aTreeView[0]=0

        ConsoleWrite(_ArrayToString($aTreeView,@CRLF)&@CRLF)
        for $i =0 to UBound($aTreeView) -1
            _SendMessage($hWnd, $TVM_SORTCHILDREN, 0, $aTreeView[$i], 0, "wparam", "handle") ; Sort the items in root
        NExt
    EndIf

EndFunc   ;==>_GUICtrlTreeView_Sort3

func __GUICtrlTreeView_SortGetFirstChild($hWnd, $hItem, byref $aTreeView)
    Local $hChild = _GUICtrlTreeView_GetFirstChild($hWnd, $hItem)
    if $hChild <> 0 then
        $aTreeView[$aTreeView[0] ]= $hChild
        $aTreeView[0]+=1
        __GUICtrlTreeView_SortGetFirstChild($hWnd,$hChild,$aTreeView)
    EndIf
    local $hNext = _GUICtrlTreeView_GetNextSibling($hWnd, $hItem)
    if $hNext <> 0 then __GUICtrlTreeView_SortGetFirstChild($hWnd,$hnext,$aTreeView)

EndFunc

on the 2 examples given

On example 1 -
     Solution 1 : 4 order messages sent
     Solution 2 : 1 order message sent

On example 2
     Solution 1 : 28 order messages sent
     Solution 2 : 13 order messages sent

 

Hope it helps to fix the UDF.

Gillesg

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
×
×
  • Create New...