Treeview FileExplorer

  • Hallo Oscar,

    Mr. Gitarre hat leider recht, bei Verwendung von Cursor rechts zum erweitern eines Knotens, stimmt die Anzeige in der 2. Ebene danach nicht mehr. Warum ich damals für mich auch die Schleifen von

    [autoit]

    For $sDir In $aDirList

    [/autoit]

    auf

    [autoit]

    For $i = 0 to UBound($aDirList) -1

    [/autoit]

    umgestellt habe (und den Code entsprchend angepasst) kann ich nicht mehr nachvollziehen (habe im Skript nicht kommentiert), warscheinlich nur Vorliebe da ich selbst die For In Version nie einsetze. Ich mach dir jetzt aber kein Video dazu, da ich davon ausgehe dass mit obiger Beschreibung der Fehler reproduzierbar ist,

    mfg autoBert

  • autoBert:

    Fehler immernoch vorhanden...!!!
    Habe funktion:

    [autoit]

    Func _GUICtrlTreeView_FileExplorerRecursive($hTreeview, $hItem, $sPath, $iRec)
    Local $aDirList, $aFileList, $tmp
    If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
    $iRec -= 1
    $aDirList = _MyFileListToArray($sPath, 2)
    If IsArray($aDirList) Then
    For $i = 0 to UBound($aDirList) -1 ;hier war for in
    $tmp = _GUICtrlTreeView_AddChild($hTreeview, $hItem, $aDirList[$i], 0, 1)
    If $iRec > 0 Then _GUICtrlTreeView_FileExplorerRecursive($hTreeview, $tmp, $sPath & $aDirList[$i], $iRec)
    Next
    EndIf
    $aFileList = _MyFileListToArray($sPath, 1)
    If IsArray($aFileList) Then
    For $i = 0 to UBound($aFileList) -1 ;hier war auch for in
    $tmp = _GUICtrlTreeView_AddChild($hTreeview, $hItem, $aFileList[$i], 2, 2)
    Next
    EndIf
    EndFunc ;==>_GUICtrlTreeView_FileExplorerRecursive

    [/autoit]

    von dir ersetzt und der Fehler kommt leider immernoch!!!!

    Haste noch ne Lösung...?

  • Guten Morgen,

    versucht es doch mal damit, es scheint zu funktionieren:

    Spoiler anzeigen
    [autoit]

    Func _WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $tNMTREEVIEW, $hITEM
    $tNMTREEVIEW = DllStructCreate($tagNMTREEVIEW, $ilParam)
    If DllStructGetData($tNMTREEVIEW, 'hWndFrom') = $hWndTreeview Then
    Switch DllStructGetData($tNMTREEVIEW, 'Code')
    Case $TVN_ITEMEXPANDINGA, $TVN_ITEMEXPANDINGW
    If DllStructGetData($tNMTREEVIEW, "Action") = $TVE_EXPAND Then
    $hITEM = DllStructGetData($tNMTREEVIEW, "NewhItem")
    ToolTip('Please wait...', Default, Default, 'Read Directory', 1)
    _GUICtrlTreeView_FileExplorer($hGui, $hTreeview, $hItem)
    ToolTip('')
    EndIf
    EndSwitch
    EndIf
    Return $GUI_RUNDEFMSG
    EndFunc ;==>_WM_NOTIFY

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

    Func _GUICtrlTreeView_FileExplorer($hGui, $hTreeview, $hItem)
    Local $aTVPos, $aPos, $hChild, $sTree ; , $hItem
    ;~ $aTVPos = ControlGetPos($hGui, '', $hTreeview)
    ;~ $aPos = GUIGetCursorInfo($hGui)
    ;~ $hItem = _GUICtrlTreeView_HitTestItem($hTreeview, $aPos[0], $aPos[1] - $aTVPos[1])
    If _GUICtrlTreeView_GetExpanded($hTreeview, $hItem) Then Return
    $hChild = _GUICtrlTreeView_GetFirstChild($hTreeview, $hItem)
    If $hChild <> 0 Then
    _GUICtrlTreeView_BeginUpdate($hTreeview)
    $sTree = StringReplace(_GUICtrlTreeView_GetTree($hTreeview, $hChild), '|', '\')
    _GUICtrlTreeView_DeleteChildren($hTreeview, $hChild)
    _GUICtrlTreeView_FileExplorerRecursive($hTreeview, $hChild, $sTree, 1)
    Do
    $hChild = _GUICtrlTreeView_GetNextChild($hTreeview, $hChild)
    If $hChild <> 0 Then
    $sTree = StringReplace(_GUICtrlTreeView_GetTree($hTreeview, $hChild), '|', '\')
    _GUICtrlTreeView_DeleteChildren($hTreeview, $hChild)
    _GUICtrlTreeView_FileExplorerRecursive($hTreeview, $hChild, $sTree, 1)
    EndIf
    Until $hChild = 0
    _GUICtrlTreeView_EndUpdate($hTreeview)
    EndIf
    EndFunc ;==>_GUICtrlTreeView_FileExplorer

    [/autoit]
  • @Großvater :

    Vielen Dank! Damit funktioniert es ohne Probleme!!!!!!!!!


    ----> RESPEKT <------

    Weißt du wieviel leute raufgeguckt haben, und niemanden ist der fehler aufgefallen...??

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DANKE!!!!!!!!!!!!!!!!!!!!!!!!!

    *Großvater ROCK!:)

    EDIT: Version scheint NICHT unter Windows 7 zu funktionieren!!!!

    Einmal editiert, zuletzt von Mr_gitarre (16. November 2010 um 11:03)

  • Hallo Mr_gitarre,

    ich habe keinen Fehler gefunden, ich habe nur versucht, über einen anderen Weg zum Refresh zu kommen. Falls es damit funktioniert, freut es mich. Mit XP und Vista habe ich kurz getestet, mit Win7 kann ich es nicht.

  • auch folgendes script (von GROßVATER) , bei dem ich dachte dass es funktioniert, funktioniert nich (mehr)...:(

    Bei Windows 7 konnte ich beim ersten start alles super angucken... dann beim 2en hatte man keine + im Hauptverzeichnis... (C:\, D:\, ...)
    Keine ahnung warum....

    Spoiler anzeigen
    [autoit]

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

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

    $hGui = GUICreate('FileExplorer', 400, 400)
    $hTreeview = GUICtrlCreateTreeView(10, 10, 380, 360)
    $hWndTreeview = GUICtrlGetHandle($hTreeview)
    $hOk = GUICtrlCreateButton('Ok', 240, 375, 60, 22)
    $hCancel = GUICtrlCreateButton('Cancel', 320, 375, 60, 22)

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

    $hImage = _GUIImageList_Create(16, 16, 5, 1)
    _GUIImageList_AddIcon($hImage, 'shell32.dll', 3) ; Verzeichnis-Icon
    _GUIImageList_AddIcon($hImage, 'shell32.dll', 110) ; Verzeichnis-Icon mit Haken
    _GUIImageList_AddIcon($hImage, 'shell32.dll', 1) ; Datei-Icon
    _GUIImageList_AddIcon($hImage, 'shell32.dll', 5) ; Diskette
    _GUIImageList_AddIcon($hImage, 'shell32.dll', 7) ; Wechseldatenträger
    _GUIImageList_AddIcon($hImage, 'shell32.dll', 8) ; Festplatte
    _GUIImageList_AddIcon($hImage, 'shell32.dll', 11) ; CDROM
    _GUIImageList_AddIcon($hImage, 'shell32.dll', 12) ; Netzwerklaufwerk
    _GUIImageList_AddIcon($hImage, 'shell32.dll', 53) ; Unbekannt
    _GUICtrlTreeView_SetNormalImageList($hTreeview, $hImage)

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

    GUISetState()
    GUICtrlSetStyle($hTreeview, Default, $WS_EX_COMPOSITED + $WS_EX_CLIENTEDGE)

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

    $aDrives = DriveGetDrive('ALL')
    ToolTip('Please wait...', Default, Default, 'Read Directory', 1)
    For $i = 1 To $aDrives[0]
    $iLWindex = 0
    Switch DriveGetType($aDrives[$i])
    Case 'Fixed'
    $iLWindex = 5
    Case 'CDROM'
    $iLWindex = 6
    Case 'RAMDisk'
    $iLWindex = 7
    Case 'Removable'
    $iLWindex = 4
    If StringLeft($aDrives[$i], 2) = 'a:' Or StringLeft($aDrives[$i], 2) = 'b:' Then $iLWindex = 3
    Case Else
    $iLWindex = 8
    EndSwitch
    $hRoot = _GUICtrlTreeView_Add($hTreeview, $hTreeview, StringUpper($aDrives[$i]), $iLWindex, $iLWindex)
    If DriveStatus($aDrives[$i]) <> 'READY' Then ContinueLoop
    _GUICtrlTreeView_BeginUpdate($hTreeview)
    _GUICtrlTreeView_FileExplorerRecursive($hTreeview, $hRoot, $aDrives[$i], 1)
    _GUICtrlTreeView_EndUpdate($hTreeview)
    Next
    ToolTip('')

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

    GUIRegisterMsg($WM_NOTIFY, '_WM_NOTIFY')
    While True
    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE, $hCancel
    Exit
    Case $hOk
    $iSelect = _GUICtrlTreeView_GetSelection($hTreeview)
    $sTree = StringReplace(_GUICtrlTreeView_GetTree($hTreeview, $iSelect), '|', '\')
    MsgBox(0, 'Selected Path/File', $sTree)
    EndSwitch
    WEnd

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

    Func _WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $tNMTREEVIEW, $hITEM
    $tNMTREEVIEW = DllStructCreate($tagNMTREEVIEW, $ilParam)
    If DllStructGetData($tNMTREEVIEW, 'hWndFrom') = $hWndTreeview Then
    Switch DllStructGetData($tNMTREEVIEW, 'Code')
    Case $TVN_ITEMEXPANDINGA, $TVN_ITEMEXPANDINGW
    If DllStructGetData($tNMTREEVIEW, "Action") = $TVE_EXPAND Then
    $hITEM = DllStructGetData($tNMTREEVIEW, "NewhItem")
    ToolTip('Please wait...', Default, Default, 'Read Directory', 1)
    _GUICtrlTreeView_FileExplorer($hGui, $hTreeview, $hItem)
    ToolTip('')
    EndIf
    EndSwitch
    EndIf
    Return $GUI_RUNDEFMSG
    EndFunc ;==>_WM_NOTIFY

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

    Func _GUICtrlTreeView_FileExplorer($hGui, $hTreeview, $hItem)
    Local $aTVPos, $aPos, $hChild, $sTree ; , $hItem
    ;~ $aTVPos = ControlGetPos($hGui, '', $hTreeview)
    ;~ $aPos = GUIGetCursorInfo($hGui)
    ;~ $hItem = _GUICtrlTreeView_HitTestItem($hTreeview, $aPos[0], $aPos[1] - $aTVPos[1])
    If _GUICtrlTreeView_GetExpanded($hTreeview, $hItem) Then Return
    $hChild = _GUICtrlTreeView_GetFirstChild($hTreeview, $hItem)
    If $hChild <> 0 Then
    _GUICtrlTreeView_BeginUpdate($hTreeview)
    $sTree = StringReplace(_GUICtrlTreeView_GetTree($hTreeview, $hChild), '|', '\')
    _GUICtrlTreeView_DeleteChildren($hTreeview, $hChild)
    _GUICtrlTreeView_FileExplorerRecursive($hTreeview, $hChild, $sTree, 1)
    Do
    $hChild = _GUICtrlTreeView_GetNextChild($hTreeview, $hChild)
    If $hChild <> 0 Then
    $sTree = StringReplace(_GUICtrlTreeView_GetTree($hTreeview, $hChild), '|', '\')
    _GUICtrlTreeView_DeleteChildren($hTreeview, $hChild)
    _GUICtrlTreeView_FileExplorerRecursive($hTreeview, $hChild, $sTree, 1)
    EndIf
    Until $hChild = 0
    _GUICtrlTreeView_EndUpdate($hTreeview)
    EndIf
    EndFunc ;==>_GUICtrlTreeView_FileExplorer

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

    Func _GUICtrlTreeView_FileExplorerRecursive($hTreeview, $hItem, $sPath, $iRec)
    Local $aDirList, $aFileList, $tmp
    If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
    $iRec -= 1
    $aDirList = _MyFileListToArray($sPath, 2)
    If IsArray($aDirList) Then
    For $i = 0 to UBound($aDirList) -1 ;hier war for in
    $tmp = _GUICtrlTreeView_AddChild($hTreeview, $hItem, $aDirList[$i], 0, 1)
    If $iRec > 0 Then _GUICtrlTreeView_FileExplorerRecursive($hTreeview, $tmp, $sPath & $aDirList[$i], $iRec)
    Next
    EndIf
    $aFileList = _MyFileListToArray($sPath, 1)
    If IsArray($aFileList) Then
    For $i = 0 to UBound($aFileList) -1 ;hier war auch for in
    $tmp = _GUICtrlTreeView_AddChild($hTreeview, $hItem, $aFileList[$i], 2, 2)
    Next
    EndIf
    EndFunc ;==>_GUICtrlTreeView_FileExplorerRecursive

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

    Func _MyFileListToArray($sPath, $iFlag)
    Local $sFileList = '', $hSearch, $sFile
    $hSearch = FileFindFirstFile($sPath & '*')
    If @error Then Return
    While True
    $sFile = FileFindNextFile($hSearch)
    If @error Then ExitLoop
    If ($iFlag + @extended = 2) Or _IsReparsePoint($sPath & $sFile) Then ContinueLoop
    $sFileList &= $sFile & '|'
    WEnd
    FileClose($hSearch)
    If $sFileList = '' Then Return
    Return StringSplit(StringTrimRight($sFileList, 1), '|', 2)
    EndFunc ;==>__FileListToArray

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

    Func _IsReparsePoint($FLS) ; progandy
    Dim Static $K32 = DllOpen('kernel32.dll')
    Dim $DA = DllCall($K32, 'dword', 'GetFileAttributesW', 'wstr', $FLS)
    If @error Then Return SetError(1, @error, False)
    Return BitAND($DA[0], 1024) = 1024
    EndFunc

    [/autoit]

    Edit Oscar: Bitte Spoiler benutzen!

    Edit:

    Guckt euch das mal an, der eine is mit der rechten maustaste gemacht, der andere im menü oben...!

    Sagt mir mal, was ihr seht!

  • Das mit $tagNMTREEVIEW habe ich schon komplett durch (alle Parameter versucht). Unter Windows7 kommt dabei nichts brauchbares raus.
    Entweder stimmt die Struktur nicht oder Windows7 sendet dabei keine notification message.
    Ich weiss nicht, wie man sonst noch an das angeklickte Item kommt?! ?(

    Hallo Oscar,
    welche Nachrichten kommen in _WM_NOTIFY) unter Win7-64 an?

  • Also klappts nur unter 64bit nicht?
    tagNMHDR scheint mir in den Structures_Constants nicht ganz richtig zu sein! (und somit auch $tagNMTREEVIEW)

    Structures_Constants.au3:

    [autoit]

    $tagNMHDR = "hwnd hWndFrom;uint_ptr IDFrom;int Code"

    [/autoit]


    und laut msdn wäre es so richtig:

    [autoit]

    $tagNMHDR = "hwnd hWndFrom;uint_ptr IDFrom;uint Code"

    [/autoit]


    http://msdn.microsoft.com/en-us/library/bb775514(VS.85).aspx

    2 Mal editiert, zuletzt von nuts (17. November 2010 um 10:03)

  • Zitat

    Also klappts nur unter 64bit nicht?

    habs gestern Probiert, da kahm ein fehler: hab die Version geuppt, einmal als x32 bit und dann als x64 bit...

    Wenn man x64 öffnet, bekommt man kein + an den Geöffneten Ordnern ... Bei ALLES...
    Denke dass es ein fehler von Autoit ist..."!

  • Hallo,

    wenn jemand Lust und Zeit und Win7-64 hat, kann er ja mal diese Version der Funktion testen und sehen, was so kommt:

    Spoiler anzeigen
    [autoit]

    Func _WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    Local Const $TVE_1 = "TVE_COLLAPSE"
    Local Static $iPrevCode = 0
    Local Const $TVE_2 = "TVE_EXPAND"
    Local $tNMTREEVIEW, $hITEM, $iCode, $iAction
    $tNMTREEVIEW = DllStructCreate($tagNMTREEVIEW, $ilParam)
    If DllStructGetData($tNMTREEVIEW, 'hWndFrom') = $hWndTreeview Then
    $iCode = DllStructGetData($tNMTREEVIEW, 'Code')
    Switch $iCode
    Case $TVN_ITEMEXPANDINGA, $TVN_ITEMEXPANDINGW
    $iAction = DllStructGetData($tNMTREEVIEW, "Action")
    Switch $iAction
    Case $TVE_EXPAND
    $hITEM = DllStructGetData($tNMTREEVIEW, "NewhItem")
    GUICtrlSetData($hSB, ' ...Please wait...Reading Directory')
    _GUICtrlTreeView_FileExplorer($hGui, $hTreeview, $hItem)
    GUICtrlSetData($hSB, '')
    EndSwitch
    If Eval("TVE_" & $iAction) Then $iAction = Eval("TVE_" & $iAction)
    ConsoleWrite(@HOUR & @MIN & @SEC & @MSEC & ": TVN_ITEMEXPANDING - " & $iAction & @CRLF)
    $iPrevCode = $iCode
    Return 0
    Case $TVN_ITEMEXPANDEDA, $TVN_ITEMEXPANDEDW
    $iAction = DllStructGetData($tNMTREEVIEW, "Action")
    If Eval("TVE_" & $iAction) Then $iAction = Eval("TVE_" & $iAction)
    ConsoleWrite(@HOUR & @MIN & @SEC & @MSEC & ": TVN_ITEMEXPANDED - " & $iAction & @CRLF)
    EndSwitch
    If $iCode <> $iPrevCode Then
    ConsoleWrite(@HOUR & @MIN & @SEC & @MSEC & ": " & $iCode & @CRLF)
    $iPrevCode = $iCode
    EndIf
    EndIf
    Return $GUI_RUNDEFMSG
    EndFunc ;==>_WM_NOTIFY

    [/autoit]
    • Offizieller Beitrag

    Da bekomme ich nur Konsolenausgaben (auf das Plus von C: geklickt):

    Spoiler anzeigen


    Den Verzeichnissen von C: fehlt aber das Pluszeichen.

    • Offizieller Beitrag

    Sorry, die Werte aus Post#75 waren mit der geänderten $tagNMHDR (wie von Dir, nuts, beschrieben).
    Hier sind die Werte mit der Original-StructureConstants.au3:

    Spoiler anzeigen

    nuts: Ja, Ich habe hier Win7, 64 Bit laufen.

  • Hm nach der Änderung von $tagNMHDR kommen nur unsinnige Werte raus. :(
    Keine Ahnung wieso (s. msdn), ist wohl was autoit spezifisches.


    Mit der Orginal $tagNMHDR kommt bei Oscar meist gar keine entsprechende Message an - gibts doch nicht ?( :wacko:
    Edit\ bzw. es liegt doch an der Struktur $tagNMTREEVIEW?
    Ohne 64bit System übersteigt das jetzt aber langsam meine Fähigkeiten :(
    @32bit klappts bei mir zumindest. ^^

    3 Mal editiert, zuletzt von nuts (17. November 2010 um 18:29)

  • Guten Morgen,

    nuts: Du hast schon recht, das Code-Tag in NMHDR ist als UINT definiert. MS verwendet für die Notificationcodes aber auch "pseudonegative" Werte. Um die Definitionen trotzdem übersichtlich zu halten, bedient man sich dort dann solcher "Tricks":

    Code
    #define TVN_FIRST               (0U-400U)       // treeview
    #define TVN_LAST                (0U-499U)


    In AU3 lässt sich das so nicht abbilden, und deshalb haben die Macher der Konstanten-UDFs wohl das Format INT und "echte" negative Werte vorgezogen. Bei einer Definition als UINT müsste man in AU3 folgenden Zwischenschritt nutzen:

    [autoit]

    $Code = 4294967279
    MsgBox(0, "UInt -> Int", BitAND($Code, 0xFFFFFFFF))

    [/autoit]


    Oscars Auswertung mit Win7-64 und der Original-UDF sieht eigentlich gar nicht so schlecht aus. Auffällig sind allerdings die bei $TVN_ITEMEXPANDING und $TVN_ITEMEXPANDED ausgelesenen Werte für das Tag Action. Im MSDN sind weder 0 noch 30 dokumentiert. Hier könnte es sich also um einen Fehler handeln, der entweder durch Win7-64 oder durch eine fehlerhafte Wertinterpretation in AU3 unter Win7-64 entsteht.

    Oscar : Ändert sich irgendetwas, wenn Du das Skript unter Win7-64 als 32-Bit-Exe kompilierst?

  • wenn ihr dann den fehler wisst, meldet ihn dann jemand noch bei AutoIt??
    Würde es ja machen aber Ich weiß den Fehler nicht und Die Fehlermeldungsseite von AutoIt weiß ich auch nicht!

    Danke!

    • Offizieller Beitrag

    @Großvater: Volltreffer! Als 32 Bit-Version funktioniert es. Es muss also an der 64 Bit-Variante liegen. Irgend ein Fehler in der Struktur!?

    Ich habe jetzt

    [autoit]

    #AutoIt3Wrapper_UseX64=n

    [/autoit]


    eingefügt, dann funktioniert es auch als Script.

    So nebenbei funktioniert damit jetzt auch die Tastatursteuerung (Pfeil nach rechts/links zum auf-/zuklappen). Neue Version in Post#1.

    Danke! :thumbup: