#include <GUIConstantsEx.au3>
#include <GuiTreeView.au3>
#include <TreeViewConstants.au3>
#include <WindowsConstants.au3>

#cs  Datei mit Tree-Struktur
Parent-Name; Item-Name

;Autos                // erster Eintrag, somit kein Parent
Autos;Ford
Autos;Opel
Autos;BMW
Ford;Fiesta
Ford;Mondeo
Opel;Manta
Opel;Insignia
BMW;3er
BMW;8er
#ce

Global $File = @ScriptDir & '\Tree.txt'
Global $hTV

$hGUI = GUICreate("Test", 350, 215)
$TV = GUICtrlCreateTreeView(5, 5, 180, 200, BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS), $WS_EX_CLIENTEDGE)
$hTV = GUICtrlGetHandle($TV)
$btNew = GUICtrlCreateButton('New Item', 245, 5, 100, 20)
$btFile = GUICtrlCreateButton('Load From File', 245, 45, 100, 20)
$btWrite = GUICtrlCreateButton('Write To File', 245, 85, 100, 20)
GUISetState()

Global $aFromFile = _ReadFile2TreeArray()

While 1
    Switch GUIGetMsg()
        Case -3
            Exit
        Case $btNew
            ; == Dialog NEU
        Case $btFile
            _Load()
        Case $btWrite
            _WriteTreeToFile()
    EndSwitch
WEnd


Func _Load()
    $aTVHandle = _FillTreeFromArray()
    _GUICtrlTreeView_Expand($hTV)
EndFunc

Func _ReadFile2TreeArray()
    Local $sRead = FileRead($File)
    If @error Then Return SetError(1,0,0)
    Local $a = StringRegExp($sRead, '(\w+)*;(\w+)', 3)
    If Not IsArray($a) Then Return SetError(2,0,0)
    Local $aTree[UBound($a)/2][2], $n = 0
    For $i = 0 To UBound($a) -2 Step 2
        $aTree[$n][0] = $a[$i]     ; == Parent-Name
        $aTree[$n][1] = $a[$i+1]   ; == Item-Name
        $n += 1
    Next
    Return $aTree
EndFunc

Func _FillTreeFromArray()
    Local $aHwnd[UBound($aFromFile)][2]
    Local $hRoot, $hParent, $hItem
    For $i = 0 To UBound($aFromFile) -1
        If $aFromFile[$i][0] = '' Then                          ; == erster Eintrag - Root
            $hRoot = _GUICtrlTreeView_Add($hTV, 0, $aFromFile[$i][1])
            $aHwnd[0][0] = $aFromFile[$i][1]                    ; == Text Root
            $aHwnd[0][1] = $hRoot                               ; == Handle Root
        ElseIf $aFromFile[$i][0] = $aFromFile[0][1] Then        ; == Root ist übergeordnet, Item wird Child des Root und selbst dann Parent für Childs
            $hItem = _GUICtrlTreeView_AddChild($hTV, $hRoot, $aFromFile[$i][1])
            $aHwnd[$i][0] = $aFromFile[$i][1]                   ; == Text Item
            $aHwnd[$i][1] = $hItem                              ; == Handle Item
        Else                                                    ; == andere Item sind dann in der nächsten Unterebene
            For $j = 0 To UBound($aHwnd) -1
                If $aFromFile[$i][0] = $aHwnd[$j][0] Then       ; == übergeordnetes Item suchen
                    $hParent = $aHwnd[$j][1]                    ; == dessen Handle übernehmen
                    ExitLoop
                EndIf
            Next
            $hItem = _GUICtrlTreeView_AddChild($hTV, $hParent, $aFromFile[$i][1])
            $aHwnd[$i][0] = $aFromFile[$i][1]                   ; == Text Item
            $aHwnd[$i][1] = $hItem                              ; == Handle Item
        EndIf
    Next
    Return $aHwnd
EndFunc

Func _WriteTreeToFile()
    Local $sWrite = '', $sSubs = ''
    Local $hRoot = _GUICtrlTreeView_GetFirstItem($hTV), $sRoot, $sItem
    If $hRoot <> 0 Then
        $sRoot = _GUICtrlTreeView_GetText($hTV, $hRoot)
        $sWrite &= ';' & $sRoot & @CRLF
        Local $n = _GUICtrlTreeView_GetChildCount($hTV, $hRoot), $hChild
        Local $m, $hSub, $hItem
        If $n > 0 Then
            $hChild = _GUICtrlTreeView_GetFirstChild($hTV, $hRoot)
            $sWrite &= $sRoot & ';' &  _GUICtrlTreeView_GetText($hTV, $hChild) & @CRLF
            $sSubs &= _GetSubs($hChild, _GUICtrlTreeView_GetText($hTV, $hChild))  ; == alle SubItem hiervon auslesen
            If $n > 1 Then
                For $i = 2 To $n
                    $hChild = _GUICtrlTreeView_GetNextSibling($hTV, $hChild)
                    $sItem = _GUICtrlTreeView_GetText($hTV, $hChild)
                    $sWrite &= $sRoot & ';' &  $sItem & @CRLF
                    $sSubs &= _GetSubs($hChild, $sItem)  ; == alle SubItem hiervon auslesen
                Next
            EndIf
        EndIf
    EndIf
    $sWrite &= $sSubs
    Local $fH = FileOpen($File, 2)
    FileWrite($fH, $sWrite)
;~ ConsoleWrite($sWrite & @LF)
EndFunc

Func _GetSubs($_hItem, $_sParent)
    Local $hSub, $sSub = ''
    $m = _GUICtrlTreeView_GetChildCount($hTV, $_hItem)
    If $m > 0 Then
        $hSub = _GUICtrlTreeView_GetFirstChild($hTV, $_hItem)
        $sSub &= $_sParent & ';' & _GUICtrlTreeView_GetText($hTV, $hSub) & @CRLF
        If $m > 1 Then
            For $j = 2 To $m
                $hSub = _GUICtrlTreeView_GetNextSibling($hTV, $hSub)
                $sSub &= $_sParent & ';' & _GUICtrlTreeView_GetText($hTV, $hSub) & @CRLF
            Next
        EndIf
    EndIf
    Return $sSub
EndFunc