GUICtrlTreeView: alle Child-Item eines Parent-Item rekursiv Aus-/ Einklappen

    • Offizieller Beitrag

    Hi,
    standardmäßig kann ich entweder alle Item eines Treeview inkl. aller Sub-Item oder nur eine Ebene tiefer zum aktuellen Item Aus-/Einklappen.

    Die folgende Funktion ermöglicht es, rekursiv alle Child-Item eines Parents Aus- bzw. Einzuklappen.
    Im Bsp. kann per Kontextmenü der markierte Zweig des Treeview Aus- und Eingeklappt werden.
    Die Warnung beim Skriptstart ignorieren, betrifft eine Variable, die innerhalb der Funktion erstellt wird.

    _GUICtrlTreeView_ExpandItemRekursiv()
    [autoit]

    #include<GUIConstantsEx.au3>
    #include<GuiImageList.au3>
    #include<GuiTreeView.au3>
    #include<TreeViewConstants.au3>
    #include<WindowsConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    _Main()

    [/autoit] [autoit][/autoit] [autoit]

    Func _Main()
    Local $hItem, $hImage, $iImage, $hTreeView
    Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES)

    $gui = GUICreate("TreeView Expand One Sub-Level", 400, 300)
    $hTreeView = GUICtrlCreateTreeView(2, 2, 396, 268, $iStyle, $WS_EX_CLIENTEDGE)
    $ContextMenu = GUICtrlCreateContextMenu($hTreeView)
    $mnuExpand = GUICtrlCreateMenuItem('Zweig kpl. Ausklappen', $ContextMenu)
    $mnuCollapse = GUICtrlCreateMenuItem('Zweig kpl. Einklappen', $ContextMenu)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    $hImage = _GUIImageList_Create(16, 16, 5, 3)
    _GUIImageList_AddIcon($hImage, "shell32.dll", 110)
    _GUIImageList_AddIcon($hImage, "shell32.dll", 131)
    _GUIImageList_AddIcon($hImage, "shell32.dll", 165)
    _GUIImageList_AddIcon($hImage, "shell32.dll", 168)
    _GUIImageList_AddIcon($hImage, "shell32.dll", 137)
    _GUIImageList_AddIcon($hImage, "shell32.dll", 146)
    _GUICtrlTreeView_SetNormalImageList($hTreeView, $hImage)

    [/autoit] [autoit][/autoit] [autoit]

    _GUICtrlTreeView_BeginUpdate($hTreeView)
    For $x = 1 To Random(3, 4, 1)
    $iImage = Random(0, 5, 1)
    $hItem = _GUICtrlTreeView_Add($hTreeView, 0, StringFormat("[%02d] New Item", $x), $iImage, $iImage)
    For $y = 1 To Random(3, 4, 1)
    $iImage = Random(0, 5, 1)
    $hChild = _GUICtrlTreeView_AddChild($hTreeView, $hItem, StringFormat("[%02d] New Child", $y), $iImage, $iImage)
    For $z = 1 To Random(3, 4, 1)
    $iImage = Random(0, 5, 1)
    _GUICtrlTreeView_AddChild($hTreeView, $hChild, StringFormat("[%02d] New Child", $y), $iImage, $iImage)
    Next
    Next
    Next
    _GUICtrlTreeView_EndUpdate($hTreeView)
    Do
    $msg = GUIGetMsg()
    Switch $msg
    Case $mnuExpand
    _GUICtrlTreeView_ExpandItemRekursiv($hTreeView)
    Case $mnuCollapse
    _GUICtrlTreeView_ExpandItemRekursiv($hTreeView, -1, False)
    EndSwitch
    Until $msg = $GUI_EVENT_CLOSE
    GUIDelete()
    EndFunc ;==>_Main

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;==================================================================================================
    ; Function Name: _GUICtrlTreeView_ExpandItemRekursiv($hTreeView [, $hParentItem=-1 [, $bExpand=True]])
    ; Description:: Aus- oder Einklappen aller Child-Items eines Item und deren Child-Items
    ; Parameter(s): $hTreeView Handle des TreeView
    ; $hParentItem Handle des Aus/Einzuklappenden Parent-Items
    ; Standard -1 ==> Handle des markierten Item
    ; $bExpand Ausklappen (Standard) = True, Einklappen = False
    ; Return: Erfolg nichts
    ; Fehler @error 1 - ItemHandle nicht übergeben und kein Item markiert
    ; Requirement(s): GetAllParents()
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;==================================================================================================
    Func _GUICtrlTreeView_ExpandItemRekursiv($hTreeView, $hParentItem=-1, $bExpand=True)
    If $hParentItem < 1 Then
    Local $hCurrentItem = _GUICtrlTreeView_GetSelection($hTreeView)
    Else
    Local $hCurrentItem = $hParentItem
    EndIf
    If $hCurrentItem = 0 Then Return SetError(1)
    Global $aParentItem[1] = [0]
    GetAllParents($hTreeView, $hCurrentItem)
    For $i = 0 To UBound($aParentItem) -1
    If $bExpand Then
    _GUICtrlTreeView_Expand($hTreeView, $aParentItem[$i])
    Else
    _GUICtrlTreeView_Expand($hTreeView, $aParentItem[$i], False)
    EndIf
    Next
    ReDim $aParentItem[1]
    $aParentItem[0] = 0
    EndFunc ;==>_GUICtrlTreeView_ExpandItemRekursiv

    [/autoit] [autoit][/autoit] [autoit]

    Func GetAllParents($hTreeView, $hItem)
    Local $hChild
    Local $countChild = _GUICtrlTreeView_GetChildCount($hTreeView, $hItem)
    If $countChild = 0 Then Return
    If $aParentItem[UBound($aParentItem)-1] <> 0 Then ReDim $aParentItem[UBound($aParentItem)+1]
    $aParentItem[UBound($aParentItem)-1] = $hItem
    For $i = 1 To $countChild
    If $i = 1 Then
    $hChild = _GUICtrlTreeView_GetFirstChild($hTreeView, $hItem)
    Else
    $hChild = _GUICtrlTreeView_GetNextSibling($hTreeView, $hChild)
    EndIf
    If _GUICtrlTreeView_GetChildren($hTreeView, $hChild) Then GetAllParents($hTreeView, $hChild)
    Next
    EndFunc ;==>GetAllParents

    [/autoit]

    Edit 09.06.08: Die Funktion klappt einwandfrei ... aber völlig überflüssig :S , s. Post 3

  • danke funktioniert gut, konnte beim rumspielen keine Probleme feststellen - kann man gut für Einstellungen oder Installationen verwenden

    • Offizieller Beitrag

    Ich befürchte, ich werde wirklich alt ;( .
    Da hatte ich doch mein eigenes Testskript falsch bestückt und kam dadurch zu der Annahme, dass rekursiv standarmäßig nicht geht, stattdessen aber ein Level tief.
    Tatsächlich ist es genau umgekehrt :S
    Mit Angabe des ItemHandle werden alle Subs Aus-/Eingeklappt ( _GUICtrlTreeView_Expand($hTreeView, $hItem) ). Also genau das, was ich mit obiger Funktion mühevoll nachgebaut habe :D.

    Nun gut, da ein Level Ausklappen (per Maus: Klick auf '+') per Funktion nicht geht (oder soll ich vorsichtshalber sagen, dass meine altersschwachen Augen es bis jetzt vielleicht übersehen haben ? ;) ), reiche ich somit diese Funktion nach.
    Hierbei geht es nur um das Ausklappen, da mit der Standard Expand-Funktion eingeklappt werden kann:

    _GUICtrlTreeView_ExpandOneLevel()
    [autoit]

    ;==================================================================================================
    ; Function Name: _GUICtrlTreeView_ExpandOneLevel($hTreeView [, $hParentItem=0])
    ; Description:: Ausklappen nur EINER Ebene eines Items, analog zum Mausklick auf '+'
    ; Parameter(s): $hTreeView Handle des TreeView
    ; $hParentItem Handle des Auszuklappenden Parent-Items
    ; Standard 0 ==> Handle des ersten Item im TreeView
    ; Return: Erfolg nichts
    ; Fehler @error 1 - TreeView enthält kein Item
    ; @error 2 - Item hat keine Child-Item
    ; Note: Die Funktion sollte zwischen _GUICtrlTreeView_BeginUpdate() und _GUICtrlTreeView_EndUpdate()
    ; ausgeführt werden um ein Flackern zu verhindern
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;==================================================================================================
    Func _GUICtrlTreeView_ExpandOneLevel($hTreeView, $hParentItem=0)
    If $hParentItem < 1 Then
    Local $hCurrentItem = _GUICtrlTreeView_GetFirstItem($hTreeView)
    Else
    Local $hCurrentItem = $hParentItem
    EndIf
    If $hCurrentItem = 0 Then Return SetError(1)
    Local $hChild
    Local $countChild = _GUICtrlTreeView_GetChildCount($hTreeView, $hCurrentItem)
    If $countChild = 0 Then Return SetError(2)
    _GUICtrlTreeView_Expand($hTreeView, $hCurrentItem)
    For $i = 1 To $countChild
    If $i = 1 Then
    $hChild = _GUICtrlTreeView_GetFirstChild($hTreeView, $hCurrentItem)
    Else
    $hChild = _GUICtrlTreeView_GetNextSibling($hTreeView, $hChild)
    EndIf
    If _GUICtrlTreeView_GetChildren($hTreeView, $hChild) Then _GUICtrlTreeView_Expand($hTreeView, $hChild, False)
    Next
    EndFunc ;==>_GUICtrlTreeView_ExpandOneLevel

    [/autoit]