Jump to content

TreeView Sort


Andreik
 Share

Recommended Posts

I have a treeview filled for example with items like:

KM# 100

Y# 25

KM# 6.2

Y# 4b

Y# 68

KM# 11

and so on. A normal sorting will arrange the items but not in the order that I want.

I would like to put them arranged firstly by letters before # char, then arranged by number after # char and finally, if are 2 or more items with same letters before # and same number after #, arranged by last part (this might be .2 b)

Sorted as I want the order should be:

KM# 6.2

KM# 11

KM# 100

Y# 4b

Y# 25

Y# 68

This is what I tried. Seems to work using native treeview & treeview items but not using UDF's functions. If anyone see why isn't working using UDF's function please let me know.

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

Global Const $TVSORTCB = "ptr Parent;ptr Compare;lparam SortParam;"
Global Enum $OPT_1, $OPT_2

$hMain = GUICreate("Example")
$hTree = GUICtrlCreateTreeView(5,5,390,390)
$hParent = GUICtrlCreateTreeViewItem("Parent",$hTree)
GUICtrlCreateTreeViewItem("Belgium - 100 Francs",$hParent)
GUICtrlCreateTreeViewItem("Belgium - 50 Francs",$hParent)
$hCallback = DllCallbackRegister("TreeView_ItemsCompare","int","lparam;lparam;lparam")
_GUICtrlTreeView_BeginUpdate($hTree)
_TreeView_Sort($hTree,$hCallback,$OPT_1)
_GUICtrlTreeView_EndUpdate($hTree)
DllCallbackFree($hCallback)
GUISetState(@SW_SHOW,$hMain)

While True
    Switch GUIGetMsg()
        Case -3
            Exit
    EndSwitch
    Sleep(10)
WEnd

Func TreeView_ItemsCompare($lParam1,$lParam2,$lParam3)
    Local $sItem1 = _GUICtrlTreeView_GetText($hTree,$lParam1)
    Local $sItem2 = _GUICtrlTreeView_GetText($hTree,$lParam2)
    If $lParam3 Then
        Local $sFCatalog = StringStripWS(StringLeft($sItem1,StringInStr($sItem1,"#")),7)
        Local $sSCatalog = StringStripWS(StringLeft($sItem2,StringInStr($sItem2,"#")),7)
        Local $nCompare = StringCompare($sFCatalog,$sSCatalog)
        Select
            Case $nCompare = 0
                Local $sNumber1 = StringStripWS(StringTrimLeft($sItem1,StringInStr($sItem1,"#")),7)
                Local $sNumber2 = StringStripWS(StringTrimLeft($sItem2,StringInStr($sItem2,"#")),7)
                Local $aRegExp1 = StringRegExp($sNumber1,"D",3)
                Local $aRegExp2 = StringRegExp($sNumber1,"D",3)
                If IsArray($aRegExp1) And IsArray($aRegExp2) Then
                    Local $nCompare = StringCompare($aRegExp1[0],$aRegExp2[0])
                    Select
                        Case $nCompare = 0
                            Return 0
                        Case $nCompare < 0
                            Return -1
                        Case $nCompare > 0
                            Return 1
                    EndSelect
                ElseIf IsArray($aRegExp1) And (Not IsArray($aRegExp2)) Then
                    Return 1
                ElseIf (Not IsArray($aRegExp1)) And IsArray($aRegExp2) Then
                    Return -1
                Else
                    If Number($sNumber1) < Number($sNumber2) Then
                        Return -1
                    ElseIf Number($sNumber1) > Number($sNumber2) Then
                        Return 1
                    Else
                        Return 0
                    EndIf
                EndIf
            Case $nCompare < 0
                Return -1
            Case $nCompare > 0
                Return 1
        EndSelect
        Return 0
    Else
        Local $sFCountry = StringStripWS(StringLeft($sItem1,StringInStr($sItem1,"-")-1),7)
        Local $sSCountry = StringStripWS(StringLeft($sItem2,StringInStr($sItem2,"-")-1),7)
        Local $nCompare = StringCompare($sFCountry,$sSCountry)
        Select
            Case $nCompare = 0
                Local $sDen1 = StringStripWS(StringTrimLeft($sItem1,StringInStr($sItem1,"-")),7)
                Local $sDen2 = StringStripWS(StringTrimLeft($sItem2,StringInStr($sItem2,"-")),7)
                Local $nVal1 = Number(StringStripWS(StringLeft($sDen1,StringInStr($sDen1," ")-1),7))
                Local $nVal2 = Number(StringStripWS(StringLeft($sDen2,StringInStr($sDen2," ")-1),7))
                Local $sType1 = StringStripWS(StringTrimLeft($sDen1,StringInStr($sDen1," ")),7)
                Local $sType2 = StringStripWS(StringTrimLeft($sDen2,StringInStr($sDen2," ")),7)
                Local $nTypeCompare = StringCompare($sType1,$sType2)
                Select
                    Case $nTypeCompare = 0
                        If $nVal1 < $nVal2 Then
                            Return -1
                        ElseIf $nVal1 > $nVal2 Then
                            Return 1
                        Else
                            Return 0
                        EndIf
                    Case $nTypeCompare < 0
                        Return -1
                    Case $nTypeCompare > 0
                        Return 1
                EndSelect
            Case $nCompare < 0
                Return -1
            Case $nCompare > 0
                Return 1
        EndSelect
        Return 0
    EndIf
EndFunc

Func _TreeView_Sort($hWnd,$hCallback,$fCoins=True)
    Local $pFunc = DllCallbackGetPtr($hCallback)
    If $pFunc = 0 Then Return SetError(1, 0, False)
    Local $tSort, $pSort
    $tSort = DllStructCreate($TVSORTCB)
    $pSort = DllStructGetPtr($tSort)
    DllStructSetData($tSort,"Compare",$pFunc)
    DllStructSetData($tSort,"SortParam",$fCoins)
    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
Edited by Andreik

When the words fail... music speaks.

Link to comment
Share on other sites

Hi,

This is what I tried. Seems to work using native treeview & treeview items but not using UDF's functions. If anyone see why isn't working using UDF's function please let me know.

You mean why it does not with the function _GUICtrlTreeView_Sort ?

Br, FireFox.

Link to comment
Share on other sites

Nope. Check first lines of my example where I used native functions to create treeview control and items

$hTree = GUICtrlCreateTreeView(5,5,390,390)
$hParent = GUICtrlCreateTreeViewItem("Parent",$hTree)
GUICtrlCreateTreeViewItem("Belgium - 100 Francs",$hParent)
GUICtrlCreateTreeViewItem("Belgium - 50 Francs",$hParent)

If I rewrite the example using UDFs functions, my example won't work anymore.

Edited by Andreik

When the words fail... music speaks.

Link to comment
Share on other sites

I see, but I don't understand your script :sweating:

The items handle given for the function TreeView_ItemsCompare are the same : "Parent" and not its child like in the working example.

But you have maybe already noticed it. You havn't said precisely what isn't working and you know better than me how it works.

Br, FireFox.

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...