#include-once #include #include #include #include #include #include #include #include #include #include #include #Include #include ; #INDEX# ======================================================================================================================= ; Title .........: TreeListExplorer ; AutoIt Version : 3.3.18.1 ; Language ......: English ; Description ...: UDF to use a Listview or Treeview as a File/Folder Explorer ; Author(s) .....: Kanashius ; Special Thanks.: WildByDesign for testing this UDF a lot and helping me to make it better ; Version .......: 2.12.1 ; =============================================================================================================================== ; #CURRENT# ===================================================================================================================== ; __TreeListExplorer_StartUp ; __TreeListExplorer_FreeIconCache ; __TreeListExplorer_Shutdown ; __TreeListExplorer_CreateSystem ; __TreeListExplorer_DeleteSystem ; __TreeListExplorer_AddView ; __TreeListExplorer_SetCallback ; __TreeListExplorer_RemoveView ; __TreeListExplorer_OpenPath ; __TreeListExplorer_Reload ; __TreeListExplorer_GetPath ; __TreeListExplorer_GetRoot ; __TreeListExplorer_GetSelected ; __TreeListExplorer_SetRoot ; =============================================================================================================================== ; #INTERNAL_USE_ONLY# =========================================================================================================== ; __TreeListExplorer__DeleteSystem ; __TreeListExplorer__OpenPath ; __TreeListExplorer__IsPathOpen ; __TreeListExplorer__GetCurrentPath ; __TreeListExplorer__GetCurrentRoot ; __TreeListExplorer__GetSelected ; __TreeListExplorer__GetSystemIDFromHandle ; __TreeListExplorer__GetHandleFromSystemID ; __TreeListExplorer__UpdateSystemViews ; __TreeListExplorer__UpdateView ; __TreeListExplorer__ListViewPathHandler ; __TreeListExplorer__GetSizeString ; __TreeListExplorer__GetTimeString ; __TreeListExplorer__FileGetIconIndex ; __TreeListExplorer__ExpandTreeitem ; __TreeListExplorer__UpdateTreeItemContent ; __TreeListExplorer__GetTreeViewItemDepth ; __TreeListExplorer__UpdateTreeItemExpandable ; __TreeListExplorer__GetDrives ; __TreeListExplorer__GetDriveIconId ; __TreeListExplorer__UpdateTreeViewSelection ; __TreeListExplorer__TreeViewGetRelPath ; __TreeListExplorer__IsViewUpdating ; __TreeListExplorer__SetViewUpdating ; __TreeListExplorer__PathIsFolder ; __TreeListExplorer__PathIsFile ; __TreeListExplorer__RelPathIsFolder ; __TreeListExplorer__RelPathIsFile ; __TreeListExplorer__KeyProc ; __TreeListExplorer__WinProc ; __TreeListExplorer__RegisteredOpenPath ; __TreeListExplorer__ListViewOpenCurrentItem ; __TreeListExplorer__HandleViewCallback ; __TreeListExplorer__HandleSystemCallback ; __TreeListExplorer__GetPathAndLast ; __TreeListExplorer__ConsoleWriteCallbackError ; =============================================================================================================================== ; #GLOBAL CONSTANTS# ============================================================================================================ ; Languages Global $__TreeListExplorer_Lang_EN = 0 Global $__TreeListExplorer_Lang_DE = 1 ; Callback types Global $__TreeListExplorer_Callback_Click = 1 Global $__TreeListExplorer_Callback_DoubleClick = 2 Global $__TreeListExplorer_Callback_Loading = 4 Global $__TreeListExplorer_Callback_Filter = 8 Global $__TreeListExplorer_Callback_ListViewItemCreated = 16 Global $__TreeListExplorer_Callback_ListViewPaths = 32 ; =============================================================================================================================== ; #INTERNAL_USE_ONLY GLOBAL CONSTANTS # ========================================================================================= Global $__TreeListExplorer__Type_TreeView = 1, $__TreeListExplorer__Type_ListView = 2, $__TreeListExplorer__Type_Input = 3 Global $__TreeListExplorer__Status_UpdateView = 1, $__TreeListExplorer__Status_ExpandTree = 2 Global $__TreeListExplorer__Status_LoadTree = 4, $__TreeListExplorer__Status_WaitOpenPath = 8 ; =============================================================================================================================== ; #INTERNAL_USE_ONLY GLOBAL VARIABLES # ========================================================================================= Global $__TreeListExplorer__Data[] ; =============================================================================================================================== ; #FUNCTION# ==================================================================================================================== ; Name ..........: __TreeListExplorer_StartUp ; Description ...: StartUp of the TLE UDF initializing required variables. Must be called before using other UDF functions. ; Syntax ........: __TreeListExplorer_StartUp([$iLang = $__TreeListExplorer_Lang_EN[, $iIconSize = 16]]) ; Parameters ....: $iLang - [optional] an integer to set the language ($__TreeListExplorer_Lang_EN, $__TreeListExplorer_Lang_DE). Default is $__TreeListExplorer_Lang_EN. ; $iIconSize - [optional] the size for icons in the Tree-/ListView. Default is 16. ; Return values .: True on success. ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; The following languages are currently awailable: $__TreeListExplorer_Lang_EN, $__TreeListExplorer_Lang_DE ; To add other languages, add them to the array at the beginning of this function ; and create the $__TreeListExplorer_Lang_?? variable. ; ; Errors: ; 1 - Parameter not valid (@extended: 1 - $iLang, 2 - $iIconSize) ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer_StartUp($iLang = $__TreeListExplorer_Lang_EN, $iIconSize = 16) Local $arLangData = [["Filename", "Size", "Date created", "This PC"], _ ["Dateiname", "Größe", "Erstelldatum", "Dieser PC"]] If Not IsInt($iLang) Or $iLang<0 Or $iLang>UBound($arLangData)-1 Then Return SetError(1, 1, False) If Not IsInt($iIconSize) Or $iIconSize<0 Then Return SetError(1, 2, False) $__TreeListExplorer__Data.iDoubleClickTime = 500 Local $arDoubleClickTime = DllCall('user32.dll', 'uint', 'GetDoubleClickTime') If Not @error And UBound($arDoubleClickTime)>0 And IsInt($arDoubleClickTime[0]) Then $__TreeListExplorer__Data.iDoubleClickTime = $arDoubleClickTime[0] $__TreeListExplorer__Data.iIconSize = $iIconSize _GDIPlus_Startup() Local $hImageList = _GUIImageList_Create($iIconSize, $iIconSize, 5, 1) _GUIImageList_AddIcon($hImageList, 'shell32.dll', 3) ; Folder-Icon _GUIImageList_AddIcon($hImageList, 'shell32.dll', 110) ; Folder-Icon checked _GUIImageList_AddIcon($hImageList, 'shell32.dll', 0) ; File-Icon _GUIImageList_AddIcon($hImageList, 'shell32.dll', 5) ; Disc-Icon _GUIImageList_AddIcon($hImageList, 'shell32.dll', 7) ; Changeableinput-Icon _GUIImageList_AddIcon($hImageList, 'shell32.dll', 8) ; Harddrive-Icon _GUIImageList_AddIcon($hImageList, 'shell32.dll', 11) ; CDROM-Icon _GUIImageList_AddIcon($hImageList, 'shell32.dll', 12) ; Networkdrive-Icon _GUIImageList_AddIcon($hImageList, 'shell32.dll', 53) ; Unknown-Icon _GUIImageList_AddIcon($hImageList, 'shell32.dll', 15) ; This PC _GUIImageList_AddIcon($hImageList, 'shell32.dll', 109) ; Dummy element (Crossed O) _GUIImageList_AddIcon($hImageList, 'shell32.dll', 305) ; Dummy element (Crossed O) $__TreeListExplorer__Data.iCustomIconsStartIndex = _GUIImageList_GetImageCount($hImageList) $__TreeListExplorer__Data.hIconList = $hImageList Local $mIcons[] $__TreeListExplorer__Data.mIcons = $mIcons Local $mSystems[] $__TreeListExplorer__Data.mSystems = $mSystems Local $mViews[] $__TreeListExplorer__Data.mViews = $mViews $__TreeListExplorer__Data.iLang = $iLang Local $mGuis[] $__TreeListExplorer__Data.mGuis = $mGuis $__TreeListExplorer__Data.hProc = DllCallbackRegister('__TreeListExplorer__WinProc', 'ptr', 'hwnd;uint;wparam;lparam') $__TreeListExplorer__Data.hKeyProc = DllCallbackRegister("__TreeListExplorer__KeyProc", "int", "int;ptr;ptr") $__TreeListExplorer__Data.hKeyPrevHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($__TreeListExplorer__Data.hKeyProc), _WinAPI_GetModuleHandle(0), 0) $__TreeListExplorer__Data.arLangData = $arLangData $__TreeListExplorer__Data.bCTRL_DOWN = False $__TreeListExplorer__Data.bSHIFT_DOWN = False Local $mOpenPathViews[] $__TreeListExplorer__Data.mOpenPathViews = $mOpenPathViews Return True EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer_FreeIconCache ; Description ...: Removes all cached icons for all extensions or files ; Syntax ........: __TreeListExplorer_FreeIconCache() ; Parameters ....: ; Return values .: None ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer_FreeIconCache() Local $hImageList = $__TreeListExplorer__Data.hIconList, $iCustomIndex = $__TreeListExplorer__Data.iCustomIconsStartIndex While _GUIImageList_GetImageCount($hImageList)>$iCustomIndex Local $hIcon = _GUIImageList_GetIcon($hImageList, $iCustomIndex) _GUIImageList_Remove($hImageList, $iCustomIndex) _GUIImageList_DestroyIcon($hIcon) WEnd Local $mEmpty[] $__TreeListExplorer__Data["mIcons"] = $mEmpty Local $arSystemKeys = MapKeys($__TreeListExplorer__Data.mSystems) For $i=0 To UBound($arSystemKeys)-1 Step 1 __TreeListExplorer_Reload(__TreeListExplorer__GetHandleFromSystemID($arSystemKeys[$i]), True) Next EndFunc ; #FUNCTION# ==================================================================================================================== ; Name ..........: __TreeListExplorer_Shutdown ; Description ...: Shutdown of the TLE UDF. Must be called before closing the program. If not called, the program may not exit. ; Syntax ........: __TreeListExplorer_Shutdown() ; Parameters ....: ; Return values .: True on success. ; Author ........: Kanashius ; Modified ......: ; Remarks .......: This includes deleting all TLE systems (__TreeListExplorer_DeleteSystem). ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer_Shutdown() Local $arSystems = MapKeys($__TreeListExplorer__Data.mSystems) For $i=0 To UBound($arSystems)-1 Step 1 __TreeListExplorer__DeleteSystem($arSystems[$i]) Next DllCallbackFree($__TreeListExplorer__Data.hProc) _WinAPI_UnhookWindowsHookEx($__TreeListExplorer__Data.hKeyPrevHook) DllCallbackFree($__TreeListExplorer__Data.hKeyProc) _GUIImageList_Destroy($__TreeListExplorer__Data.hIconList) Local $mMap[] $__TreeListExplorer__Data = $mMap _GDIPlus_Shutdown() __TreeListExplorer_FreeIconCache() Return True EndFunc ; #FUNCTION# ==================================================================================================================== ; Name ..........: __TreeListExplorer_CreateSystem ; Description ...: Create a new TLE System. This is used to manage the views by settings the root folder, the current folder,... ; Multiple views (TreeView/ListView) can be added, all managed by this system. ; Syntax ........: __TreeListExplorer_CreateSystem($hGui[, $sRootFolder = ""[, $sCallbackFolder = Default[, $sCallbackSelect = Default[, $iMaxDepth = Default ; [, $iLineNumber = @ScriptLineNumber]]]]]) ; Parameters ....: $hGui - the window handle for all views used by this system. ; $sRootFolder - [optional] the root folder as string. Default is "", making the drive overview the root ; $sCallbackFolder - [optional] callback function as string. Using Default will not call any function. ; $sCallbackSelect - [optional] callback function as string. Using Default will not call any function. ; $iMaxDepth - [optional] the max depth, to which TreeViews are limited. Default = No limit. ; $iLineNumber - [optional] linenumber of the function call. Default is @ScriptLineNumber. ; (Automatic, no need to change; only used for error messages) ; Return values .: The system handle $hSystem, used by the other functions ; Author ........: Kanashius ; Modified ......: ; Remarks .......: When $sRootFolder = Default, there is no root directory, enabling all drives to be accessed. Otherwise the User can ; only select child folders of the root folder. ; ; The $sCallbackFolder calls the provided function, which must have 4 parameters ($hSystem, $sRoot, $sFolder, $sSelected) and ; is called, when the root folder or the current folder changes. If the parameter number is wrong an error ; message will be written to the console at runtime (using $iLineNumber to find it better). ; ; $sCallbackSelect must be a function with 4 parameters ($hSystem, $sRoot, $sFolder, $sSelected) ; and is called, when an item in the Tree-/ListView is selected (Mouse/Keyboard) ; ; If $iMaxDepth is set, it is not possible to go deeper then that depth (Example: Drive selection with $sRoot="" and $iMaxDepth=0). ; ListViews are not limited by $iMaxDepth. ; ; Errors: ; 1 - Parameter is invalid (@extended 1 - $hGui, 3 - $sCallbackFolder, 4 - $sCallbackSelect, 5 - $iLineNumber) ; 2 - Setting WinProc for $hGui failed ; 3 - TLE system could not be added to map ; 4 - TLE system ID could not be converted to TLE system handle ; 5 - $sRootFolder is invalid and could not be set (try __TreeListExplorer_SetRoot for details) ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer_CreateSystem($hGui, $sRootFolder = Default, $sCallbackFolder = Default, $sCallbackSelect = Default, $iMaxDepth = Default, $iLineNumber = @ScriptLineNumber) If Not IsHWnd($hGui) Then Return SetError(1, 1, -1) If $sCallbackFolder <> Default And Not IsFunc(Execute($sCallbackFolder)) Then Return SetError(1, 3, -1) If $sCallbackSelect <> Default And Not IsFunc(Execute($sCallbackSelect)) Then Return SetError(1, 4, -1) If Not IsInt($iLineNumber) Then Return SetError(1, 5, False) Local $mSystem[], $mViews[] $mSystem.mViews = $mViews $mSystem.sRootOld = -1 $mSystem.sRoot = "" $mSystem.sFolderOld = -1 $mSystem.sFolder = "" $mSystem.sSelected = "" $mSystem.sSelectedOld = -1 $mSystem.bReloadFolder = False $mSystem.bReloadAllFolders = False $mSystem.iMaxDepth = $iMaxDepth $mSystem.hGui = $hGui $mSystem.sCallbackFolder = $sCallbackFolder $mSystem.sCallbackSelect = $sCallbackSelect $mSystem.iLineNumber = $iLineNumber If MapExists($__TreeListExplorer__Data.mGuis, $hGui) Then $__TreeListExplorer__Data["mGuis"][$hGui]["count"] += 1 Else Local $mGui[] $mGui["count"] = 1 $mGui["hPrevProc"] = _WinAPI_SetWindowLong($hGui, -4, DllCallbackGetPtr($__TreeListExplorer__Data.hProc)) If @error Then Return SetError(2, 0, -1) $__TreeListExplorer__Data["mGuis"][$hGui] = $mGui EndIf Local $iSystem = MapAppend($__TreeListExplorer__Data.mSystems, $mSystem) If @error Then ; Revert gui changes and return error $__TreeListExplorer__Data["mGuis"][$hGui]["count"] -= 1 If $__TreeListExplorer__Data.mGuis[$hGui].count = 0 Then _WinAPI_SetWindowLong($hGui, -4, $__TreeListExplorer__Data.mGuis[$hGui].hPrevProc) MapRemove($__TreeListExplorer__Data.mGuis, $hGui) Return SetError(3, 0, -1) EndIf Local $hSystem = __TreeListExplorer__GetHandleFromSystemID($iSystem) If @error Then __TreeListExplorer__DeleteSystem($iSystem) Return SetError(4, 0, -1) EndIf If $sRootFolder<>Default Then __TreeListExplorer_SetRoot($hSystem, $sRootFolder) If @error Then __TreeListExplorer_DeleteSystem($hSystem) Return SetError(5, 0, -1) EndIf EndIf Return $hSystem EndFunc ; #FUNCTION# ==================================================================================================================== ; Name ..........: __TreeListExplorer_DeleteSystem ; Description ...: Delete the TLE System connected to the $hSystem handle and cleans up the system resources ; Syntax ........: __TreeListExplorer_DeleteSystem($hSystem) ; Parameters ....: $hSystem - the system handle. ; Return values .: None ; Author ........: Kanashius ; Modified ......: ; Remarks .......: Errors: ; 1 - $hSystem is not a valid TLE system ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer_DeleteSystem($hSystem) Local $iSystem = __TreeListExplorer__GetSystemIDFromHandle($hSystem) If @error Then Return SetError(1, @error, 0) ; $iSystem not valid/startup not called Return __TreeListExplorer__DeleteSystem($iSystem) EndFunc ; #FUNCTION# ==================================================================================================================== ; Name ..........: __TreeListExplorer_AddView ; Description ...: Add a view (TreeView/ListView) to a TLE system. ; Syntax ........: __TreeListExplorer_AddView($hSystem, $hView, [$bShowFolders = Default, [$bShowFiles = Default, [$bNavigation = True, [$bListViewFolderUp = True, [$iLineNumber = @ScriptLineNumber]]]]]) ; Parameters ....: $hSystem - the system handle. ; $hView - the view to add (must be a TreeView or ListView). ; $bShowFolders - [optional] a boolean defining, if folders will be shown in the view. Default depends on the view type (see remarks). ; $bShowFiles - [optional] a boolean defining, if files will be shown in the view. Default depends on the view type (see remarks). ; $bNavigation - [optional] boolean. Default is True. If False, the view cannot be used to navigate folders. (ListViews only) ; $bListViewFolderUp - [optional] boolean. Default is True. If False, the view wil not have the ".." folder at the top to go to the parent directory. (ListViews only) ; $bLVDefaultColumns - [optional] boolean. Default is True. If True, the default columns for the listview will be created. (ListViews only) ; $bEnableSorting - [optional] boolean. Default is True. If True, simple sorting is enabled for the ListView, where clicking at the header sorts by that column. (ListViews only) ; $iLineNumber - [optional] an integer value. Default is @ScriptLineNumber. (should not be changed) ; Return values .: True on success ; Author ........: Kanashius ; Modified ......: ; Remarks .......: Default for $bShowFolders is True for TreeViews and ListViews, False for Inputs. ; ; Default for $bShowFiles is True for ListViews and False for TreeViews and Inputs. ; ; Additional functionality can be accomplished using callbacks (click detection/handle loading/filtering/custom columns/sorting/...). ; See __TreeListExplorer_SetCallback for further information. ; ; $bEnableSorting only allows for simple sorting. To sort by yourself, you can use the $__TreeListExplorer_Callback_ListViewPaths callback (see __TreeListExplorer_SetCallback). ; ; Errors: ; 1 - $hSystem is not a valid TLE system ; 2 - $hView is not a (valid) control handle (@extended 50: Not a TreeView/ListView/Input) ; 3 - $hView is already part of a TLE system ; 4 - Parameter is invalid (@extended 1 - $bShowFolders, 2 - $bShowFiles, 3 - $bNavigation, 4 - $bListViewFolderUp, 5 - $bEnableSorting, 6 - $iLineNumber) ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer_AddView($hSystem, $hView, $bShowFolders = Default, $bShowFiles = Default, $bNavigation = Default, $bListViewFolderUp = Default, $bLVDefaultColumns = Default, $bEnableSorting = Default, $iLineNumber = @ScriptLineNumber) Local $iSystem = __TreeListExplorer__GetSystemIDFromHandle($hSystem) If @error Then Return SetError(1, @error, False) ; $iSystem not valid/startup not called If Not IsHWnd($hView) Then $hView = GUICtrlGetHandle($hView) If @error Then Return SetError(2, @error, False) ; $hView is not a control EndIf If MapExists($__TreeListExplorer__Data.mViews, $hView) Then Return SetError(3, @error, False) ; $hView is already part of a system Local $sClass = _WinAPI_GetClassName($hView) Local $iType = 0 If StringInStr($sClass, "TreeView") Then $iType = $__TreeListExplorer__Type_TreeView ElseIf StringInStr($sClass, "ListView") Then $iType = $__TreeListExplorer__Type_ListView ElseIf StringInStr($sClass, "Edit") And (Not BitAND(_WinAPI_GetWindowLong($hView, $GWL_STYLE), $ES_MULTILINE)) Then ; check if control is input $iType = $__TreeListExplorer__Type_Input Else Return SetError(2, 50, False) ; $hView is not a valid control (wrong control type) EndIf If $bShowFolders <> Default And Not IsBool($bShowFolders) Then Return SetError(4, 1, False) If $bShowFiles <> Default And Not IsBool($bShowFiles) Then Return SetError(4, 2, False) If $bNavigation = Default Then $bNavigation = True If $bListViewFolderUp = Default Then $bListViewFolderUp = True If $bLVDefaultColumns = Default Then $bLVDefaultColumns = True If $bEnableSorting = Default Then $bEnableSorting = True If Not IsBool($bNavigation) Then Return SetError(4, 3, False) If Not IsBool($bListViewFolderUp) Then Return SetError(4, 4, False) If Not IsBool($bEnableSorting) Then Return SetError(4, 5, False) If Not IsInt($iLineNumber) Then Return SetError(4, 6, False) Switch $iType Case $__TreeListExplorer__Type_TreeView If $bShowFolders = Default Then $bShowFolders=True If $bShowFiles = Default Then $bShowFiles=False _GUICtrlTreeView_SetNormalImageList($hView, $__TreeListExplorer__Data.hIconList) Case $__TreeListExplorer__Type_ListView If $bShowFolders = Default Then $bShowFolders=True If $bShowFiles = Default Then $bShowFiles=True _GUICtrlListView_SetImageList($hView, $__TreeListExplorer__Data.hIconList, 1) _GUICtrlListView_SetExtendedListViewStyle($hView, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES)) Local $iListWidth = _WinAPI_GetWindowWidth($hView) If $bLVDefaultColumns Then For $i=0 To _GUICtrlListView_GetColumnCount($hView)+1 Step 1 _GUICtrlListView_DeleteColumn($hView, 0) Next Local $iColWidth = $iListWidth*0.3 If $iColWidth>140 Then $iColWidth = 140 _GUICtrlListView_AddColumn($hView, $__TreeListExplorer__Data.arLangData[$__TreeListExplorer__Data.iLang][0], $iListWidth-$iColWidth*2-5) ; filename _GUICtrlListView_AddColumn($hView, $__TreeListExplorer__Data.arLangData[$__TreeListExplorer__Data.iLang][1], $iColWidth, 1) ; size _GUICtrlListView_AddColumn($hView, $__TreeListExplorer__Data.arLangData[$__TreeListExplorer__Data.iLang][2], $iColWidth) ; date created EndIf Case $__TreeListExplorer__Type_Input $bShowFolders=False $bShowFiles=False GUICtrlSetData($hView, "") EndSwitch Local $mView[] $mView.hWnd = $hView $mView.iType = $iType $mView.iSystem = $iSystem $mView.bShowFolders = $bShowFolders $mView.bShowFiles = $bShowFiles $mView.sRoot = -1 $mView.sFolder = -1 $mView.sSelected = -1 $mView.iUpdating = 0 $mView.iPathIndex = 0 $mView.bNavigation = $bNavigation $mView.bListViewFolderUp = $bListViewFolderUp Local $mSorting[] $mSorting.bEnabled = $bEnableSorting $mSorting.iCol = $mView.iPathIndex $mSorting.iDir = 0 ; 0 ASC, 1 DESC $mView.mSorting = $mSorting $mView.sCallbackClick = Default $mView.sCallbackDoubleClick = Default $mView.sCallbackLoading = Default $mView.sCallbackFilter = Default $mView.sCallbackListViewItemCreated = Default $mView.sCallbackListViewPaths = Default $mView.iLineNumber = $iLineNumber $__TreeListExplorer__Data["mViews"][$hView] = $mView $__TreeListExplorer__Data["mSystems"][$iSystem]["mViews"][$hView] = 1 __TreeListExplorer__UpdateView($hView) Return True EndFunc ; #FUNCTION# ==================================================================================================================== ; Name ..........: __TreeListExplorer_SetCallback ; Description ...: Add/Remove a callback to a TLE TreeView/ListView. Allows for click/load handling, filtering, custom columns, sorting,... ; Syntax ........: __TreeListExplorer_SetCallback($hView, $iCallbackType[, $sCallbackFunction = Default[, $ext1 = Default]]) ; Parameters ....: $hView - the view where the callback should be added to (must be a TreeView or ListView). ; $iCallbackType - the type of the callback: ; $__TreeListExplorer_Callback_Click = 1 ; $__TreeListExplorer_Callback_DoubleClick = 2 ; $__TreeListExplorer_Callback_Loading = 4 ; $__TreeListExplorer_Callback_Filter = 8 ; $__TreeListExplorer_Callback_ListViewItemCreated = 16 (ListViews only) ; $__TreeListExplorer_Callback_ListViewPaths = 32 (ListViews only) ; $sCallbackFunction - [optional] callback function as string. Using Default will remove an existing callback function. ; $ext1 - [optional] additional parameter depending on $iCallbackType (See remarks for more information) ; Return values .: True on success ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Type $__TreeListExplorer_Callback_Click must be provided with a function with 6 parameters ($hSystem, $hView, $sRoot, $sFolder, $sSelected, $iIndex (ListView)/$hItem (TreeView)) ; and is called, when an element in the view is clicked once. ; ; Type $__TreeListExplorer_Callback_DoubleClick must be provided with a function with 6 parameters ($hSystem, $hView, $sRoot, $sFolder, $sSelected, $iIndex (ListView)/$hItem (TreeView)) ; and is called, when an element in the view is double clicked. ; ; Type $__TreeListExplorer_Callback_Loading must be provided with a function with 7 parameters ($hSystem, $hView, $sRoot, $sFolder, $sSelected, $sLoadingFolder, $bLoading) ; and is called, when a some folders or files are loading (when root/folder changes or an element in a ; TreeView is extended). $bLoading is True if loading starts and False, when it is done. $sLoadingFolder is relative ; to $sRoot and may be different then $sFolder, when the user is expanding a folder manually. ; ; Type $__TreeListExplorer_Callback_Filter must be provided with a function with 6 parameters ($hSystem, $hView, $bIsFolder, $sPath, $sName, $sExt) and is called to check, if a ; folder/file should be shown in the view. It must return True, if a folder/file should be shown and False, if it should be filtered. ; $bIsFolder is True for folders/drives and False for files. $sPath is the parent folder, the folder/file to be checked is in. ; $sName is the folder/filename without the extension and $sExt is the extension. ; ; Type $__TreeListExplorer_Callback_ListViewItemCreated must be provided with a function with 6 parameters ($hSystem, $hView, $sPath, $sFilename, $iIndex, $bFolder) and is called for every ListView item created to enable custom columns. ; $sPath contains the Folder/File path, $iIndex the index of the created listview item and $bFolder is true, if an item for a folder/drive was created and is false for files. ; ; Type $__TreeListExplorer_Callback_ListViewPaths must be provided with a function with 4 parameters ($hSystem, $hView, $sPath, ByRef $arPaths) and is called every time the ListView items are reloaded. ; The resulting 2D-Array should be returned by the function. Every row in the returned array will create a ListViewItem with the subitems defined in the columns. ; By default, the first col is the folder/filename (with extensions). To change that, the $ext1 Parameter can be provided with the column index, where the filename can be found. ; If the file extensions should be removed, make sure to create an additional column with width 0, where the original filename is saved. ; ; Errors: ; 1 - Parameter is invalid (@extended 1 - $hView, 2 - $iCallbackType, 3 - $sCallbackFunction, 4 - $ext1) ; 2 - $hView is not a (valid) control handle ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer_SetCallback($hView, $iCallbackType, $sCallbackFunction = Default, $ext1 = Default) If Not IsHWnd($hView) Then $hView = GUICtrlGetHandle($hView) If @error Then Return SetError(2, @error, False) ; $hView is not a control EndIf If Not IsHWnd($hView) Or Not MapExists($__TreeListExplorer__Data.mViews, $hView) Then Return SetError(1, 1, False) Local $mView = $__TreeListExplorer__Data.mViews[$hView] If $sCallbackFunction <> Default And Not IsFunc(Execute($sCallbackFunction)) Then Return SetError(1, 3, False) Switch $iCallbackType Case $__TreeListExplorer_Callback_Click $__TreeListExplorer__Data["mViews"][$hView]["sCallbackClick"] = $sCallbackFunction Case $__TreeListExplorer_Callback_DoubleClick $__TreeListExplorer__Data["mViews"][$hView]["sCallbackDoubleClick"] = $sCallbackFunction Case $__TreeListExplorer_Callback_Loading $__TreeListExplorer__Data["mViews"][$hView]["sCallbackLoading"] = $sCallbackFunction Case $__TreeListExplorer_Callback_Filter $__TreeListExplorer__Data["mViews"][$hView]["sCallbackFilter"] = $sCallbackFunction __TreeListExplorer__UpdateView($hView, True) Case $__TreeListExplorer_Callback_ListViewItemCreated $__TreeListExplorer__Data["mViews"][$hView]["sCallbackListViewItemCreated"] = $sCallbackFunction __TreeListExplorer__UpdateView($hView, True) Case $__TreeListExplorer_Callback_ListViewPaths $__TreeListExplorer__Data["mViews"][$hView]["sCallbackListViewPaths"] = $sCallbackFunction If $ext1<>Default Then If Not IsInt($ext1) Then Return SetError(1, 4, False) $__TreeListExplorer__Data["mViews"][$hView]["iPathIndex"] = $ext1 Else $__TreeListExplorer__Data["mViews"][$hView]["iPathIndex"] = 0 EndIf __TreeListExplorer__UpdateView($hView, True) Case Else Return SetError(1, 2, False) EndSwitch Return True EndFunc ; #FUNCTION# ==================================================================================================================== ; Name ..........: __TreeListExplorer_RemoveView ; Description ...: Remove a view from its TLE system ; Syntax ........: __TreeListExplorer_RemoveView($hView) ; Parameters ....: $hView - the TreeView/ListView handle. ; Return values .: True on success ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer_RemoveView($hView) If Not IsHWnd($hView) Then $hView = GUICtrlGetHandle($hView) If @error Then Return SetError(2, @error, False) ; $hView is not a control EndIf If Not IsHWnd($hView) Or Not MapExists($__TreeListExplorer__Data.mViews, $hView) Then Return SetError(1, 0, False) Local $mView = $__TreeListExplorer__Data.mViews[$hView] Local $iSystem = $mView.iSystem Local $iType = $mView.iType ; Remove from maps first, to prevent events (WinProc) from being handled during deletion MapRemove($__TreeListExplorer__Data.mViews, $hView) MapRemove($__TreeListExplorer__Data["mSystems"][$iSystem]["mViews"], $hView) Switch $iType Case $__TreeListExplorer__Type_TreeView _GUICtrlTreeView_BeginUpdate($hView) _GUICtrlTreeView_DeleteAll($hView) _GUICtrlTreeView_SetNormalImageList($hView, 0) _GUICtrlTreeView_EndUpdate($hView) Case $__TreeListExplorer__Type_ListView _GUICtrlListView_BeginUpdate($hView) _GUICtrlListView_DeleteAllItems($hView) While _GUICtrlListView_GetColumnCount($hView)>0 _GUICtrlListView_DeleteColumn($hView, 0) WEnd _GUICtrlListView_SetImageList($hView, 0) _GUICtrlListView_EndUpdate($hView) EndSwitch Return True EndFunc ; #FUNCTION# ==================================================================================================================== ; Name ..........: __TreeListExplorer_OpenPath ; Description ...: Set the current folder for the TLE system ; Syntax ........: __TreeListExplorer_OpenPath($hSystem[, $sPath = ""[, $sSelect = ""]]) ; Parameters ....: $hSystem - the system handle. ; $sPath - [optional] a folder relative to root as string value. Default is "". ; If the begin of $sPath is equal to the root directory, that part is removed. ; If $sPath=Default, then the folder is not changed (for easy use of $sSelect). ; $sSelect - [optional] a folder/file to select. Default is "". ; Return values .: True on success ; Author ........: Kanashius ; Modified ......: ; Remarks .......: Errors: ; 1 - $hSystem is not a valid TLE system ; 2 - Normalizing $sPath with _PathFull failed (@extended contains the error from _PathFull) ; 3 - $sPath does not point to a valid existing file or folder ; 4 - Something is wrong with $sPath or $sSelect ; @extended=1: $sPath Folder path and Filename coult not be split ; @extended=2: The Folder/File to select does not exist ; Others: See __TreeListExplorer__OpenPath ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer_OpenPath($hSystem, $sPath = "", $sSelect = "") Local $iSystem = __TreeListExplorer__GetSystemIDFromHandle($hSystem) If @error Then Return SetError(1, @error, False) If $sPath=Default Then $sPath = __TreeListExplorer__GetCurrentPath($iSystem) If $sPath<>"" Then $sPath = _PathFull($sPath) If @error Then Return SetError(2, @error, False) ; Remove root folder, if its at the beginning of $sPath Local $sRoot = __TreeListExplorer__GetCurrentRoot($iSystem) If $sRoot<>"" And StringInStr($sPath, $sRoot)=1 Then $sPath = StringTrimLeft($sPath, StringLen($sRoot)) EndIf Local $bRes = __TreeListExplorer__OpenPath($iSystem, $sPath, $sSelect) If @error Then Return SetError(@error, @extended, False) Return $bRes EndFunc ; #FUNCTION# ==================================================================================================================== ; Name ..........: __TreeListExplorer_Reload ; Description ...: Reloads the folders and files in all views of the system. ; Syntax ........: __TreeListExplorer_Reload($hSystem[, $bAllFoldersOnPath = False]) ; Parameters ....: $hSystem - the TLE system handle. ; $bAllFoldersOnPath - [optional] if false, only the current folder is reloaded. ; If true, all folders in the view will be reloaded. ; Default is False. ; Return values .: None ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer_Reload($hSystem, $bAllFoldersOnPath = False) Local $iSystem = __TreeListExplorer__GetSystemIDFromHandle($hSystem) If @error Then Return SetError(1, @error, False) $__TreeListExplorer__Data["mSystems"][$iSystem]["bReloadFolder"] = True If $bAllFoldersOnPath Then $__TreeListExplorer__Data["mSystems"][$iSystem]["bReloadAllFolders"] = True __TreeListExplorer__UpdateSystemViews($iSystem) $__TreeListExplorer__Data["mSystems"][$iSystem]["bReloadFolder"] = False If $bAllFoldersOnPath Then $__TreeListExplorer__Data["mSystems"][$iSystem]["bReloadAllFolders"] = False EndFunc ; #FUNCTION# ==================================================================================================================== ; Name ..........: __TreeListExplorer_GetPath ; Description ...: Get the current folder, relative to the root folder. ; Syntax ........: __TreeListExplorer_GetPath($hSystem) ; Parameters ....: $hSystem - the system handle. ; Return values .: The folder ; Author ........: Kanashius ; Modified ......: ; Remarks .......: Errors: ; 1 - $hSystem is not a valid TLE system ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer_GetPath($hSystem) Local $iSystem = __TreeListExplorer__GetSystemIDFromHandle($hSystem) If @error Then Return SetError(1, @error, 0) Return __TreeListExplorer__GetCurrentPath($iSystem) EndFunc ; #FUNCTION# ==================================================================================================================== ; Name ..........: __TreeListExplorer_GetSelected ; Description ...: Get the currently selected filename (Tree-/ListView) or foldername (ListView). ; Syntax ........: __TreeListExplorer_GetSelected($hSystem) ; Parameters ....: $hSystem - the system handle. ; Return values .: The file-/foldername. "" if nothing is selected. ; Author ........: Kanashius ; Modified ......: ; Remarks .......: The TreeView does not have a foldername selection, because if a folder is selected in the TreeView, ; it becomes the current folder. ; Errors: ; 1 - $hSystem is not a valid TLE system ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer_GetSelected($hSystem) Local $iSystem = __TreeListExplorer__GetSystemIDFromHandle($hSystem) If @error Then Return SetError(1, @error, 0) Return __TreeListExplorer__GetSelected($iSystem) EndFunc ; #FUNCTION# ==================================================================================================================== ; Name ..........: __TreeListExplorer_GetRoot ; Description ...: Get the current root folder. ; Syntax ........: __TreeListExplorer_GetRoot($hSystem) ; Parameters ....: $hSystem - the system handle. ; Return values .: The root folder ; Author ........: Kanashius ; Modified ......: ; Remarks .......: Errors: ; 1 - $hSystem is not a valid TLE system ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer_GetRoot($hSystem) Local $iSystem = __TreeListExplorer__GetSystemIDFromHandle($hSystem) If @error Then Return SetError(1, @error, 0) Return __TreeListExplorer__GetCurrentRoot($iSystem) EndFunc ; #FUNCTION# ==================================================================================================================== ; Name ..........: __TreeListExplorer_SetRoot ; Description ...: Set the current root folder. ; Syntax ........: __TreeListExplorer_SetRoot($hSystem[, $sPath = ""]) ; Parameters ....: $hSystem - the system handle. ; $sPath - [optional] a path as string. Default is "" (All Drives). ; Return values .: True on success ; Author ........: Kanashius ; Modified ......: ; Remarks .......: Errors: ; 1 - $hSystem is not a valid TLE system ; 2 - Normalizing $sPath with _PathFull failed (@extended contains the error from _PathFull) ; 3 - $sPath does not point to a valid existing folder ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer_SetRoot($hSystem, $sPath = "") Local $iSystem = __TreeListExplorer__GetSystemIDFromHandle($hSystem) If @error Then Return SetError(1, @error, False) If $sPath <> "" Then $sPath = _PathFull($sPath) If @error Then Return SetError(2, @error, False) EndIf If Not ($sPath = "" Or __TreeListExplorer__PathIsFolder($sPath)) Then Return SetError(3, @error, False) If $sPath<>"" And StringRight($sPath, 1)<>"\" Then $sPath&="\" ; Making sure, sFolder always ends with \ $__TreeListExplorer__Data["mSystems"][$iSystem]["sRoot"] = $sPath __TreeListExplorer__UpdateSystemViews($iSystem) Return True EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__DeleteSystem ; Description ...: Delete the TLE system and release all resources. ; Syntax ........: __TreeListExplorer__DeleteSystem($iSystem) ; Parameters ....: $iSystem - the system ID. ; Return values .: True on success ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__DeleteSystem($iSystem) Local $hGui = $__TreeListExplorer__Data["mSystems"][$iSystem]["hGui"] $__TreeListExplorer__Data["mGuis"][$hGui]["count"] -= 1 If $__TreeListExplorer__Data.mGuis[$hGui].count=0 Then _WinAPI_SetWindowLong($hGui, -4, $__TreeListExplorer__Data.mGuis[$hGui].hPrevProc) If @error Then ConsoleWrite('Error restoring the previous WinProc callback for gui "'&$hGui&'". This may be the reason for the program not exiting.'&@crlf) MapRemove($__TreeListExplorer__Data.mGuis, $hGui) EndIf Local $arViews = MapKeys($__TreeListExplorer__Data.mSystems[$iSystem].mViews) For $i=0 To UBound($arViews)-1 Step 1 __TreeListExplorer_RemoveView(HWnd($arViews[$i])) Next MapRemove($__TreeListExplorer__Data.mSystems, $iSystem) Return True EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__OpenPath ; Description ...: Open the provided path. ; Syntax ........: __TreeListExplorer__OpenPath($iSystem[, $sPath = ""[, $sSelect = ""]]) ; Parameters ....: $iSystem - the system ID. ; $sPath - [optional] a folder or file relative to root as string value. Default is "". ; If $sPath=Default, the current path is used. ; $sSelect - [optional] a folder/file to select as string value. Default is "". ; Return values .: True on success ; Author ........: Kanashius ; Modified ......: ; Remarks .......: Errors: ; 3 - $sPath does not point to a valid existing file or folder ; 4 - Something is wrong with $sPath or $sSelect ; @extended=1: $sPath Folder path and Filename coult not be split ; @extended=2: The Folder/File to select does not exist ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__OpenPath($iSystem, $sPath = "", $sSelect = "") If $sPath=Default Then $sPath = __TreeListExplorer__GetCurrentPath($iSystem) If $sPath<>"" And Not FileExists(__TreeListExplorer__GetCurrentRoot($iSystem) & $sPath) Then Return SetError(3, 0, False) If $sPath<>"" And Not __TreeListExplorer__RelPathIsFolder($iSystem, $sPath) Then ; handle file paths Local $arFolder = StringRegExp($sPath, "^(.*?\\?)([^\\]*?)$", 1) ; split path and filename If @error Or UBound($arFolder)<2 Then Return SetError(4, 1, False) $sPath = $arFolder[0] $sSelect = $arFolder[1] EndIf If $sPath<>"" And StringRight($sPath, 1)<>"\" Then $sPath&="\" ; Making sure, sFolder always ends with \ Local $sPathAbs = __TreeListExplorer__GetCurrentRoot($iSystem) & $sPath & $sSelect If $sPathAbs<>"" And Not FileExists($sPathAbs) Then Return SetError(4, 2, False) $__TreeListExplorer__Data["mSystems"][$iSystem]["sSelected"] = $sSelect $__TreeListExplorer__Data["mSystems"][$iSystem]["sFolder"] = $sPath __TreeListExplorer__UpdateSystemViews($iSystem) Return True EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__IsPathOpen ; Description ...: Check if a path is currently open ; Syntax ........: __TreeListExplorer__IsPathOpen($iSystem, $sPath) ; Parameters ....: $iSystem - the system ID. ; $sPath - the path to test. ; Return values .: True if $sPath equals the current TLE system folder ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__IsPathOpen($iSystem, $sPath) Return (__TreeListExplorer__GetCurrentPath($iSystem) = $sPath) EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__GetCurrentPath ; Description ...: Get the current TLE system folder ; Syntax ........: __TreeListExplorer__GetCurrentPath($iSystem) ; Parameters ....: $iSystem - the system ID. ; Return values .: The folder ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__GetCurrentPath($iSystem) Return $__TreeListExplorer__Data.mSystems[$iSystem].sFolder EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__GetCurrentRoot ; Description ...: Get the current TLE system root folder ; Syntax ........: __TreeListExplorer__GetCurrentRoot($iSystem) ; Parameters ....: $iSystem - the system ID. ; Return values .: The root folder ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__GetCurrentRoot($iSystem) Return $__TreeListExplorer__Data.mSystems[$iSystem].sRoot EndFunc ; #INTERNAL_USE_ONLY# ==================================================================================================================== ; Name ..........: __TreeListExplorer__GetSelected ; Description ...: Get the currently selected filename (Tree-/ListView) or foldername (ListView). ; Syntax ........: __TreeListExplorer__GetSelected($iSystem) ; Parameters ....: $iSystem - the system ID. ; Return values .: The file-/foldername ; Author ........: Kanashius ; Modified ......: ; Remarks .......: The TreeView does not have a foldername selection, because if a folder is selected in the TreeView, ; it becomes the current folder. ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__GetSelected($iSystem) Return $__TreeListExplorer__Data.mSystems[$iSystem].sSelected EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__GetSystemIDFromHandle ; Description ...: Convert a TLE system handle to a TLE system ID ; Syntax ........: __TreeListExplorer__GetSystemIDFromHandle($hSystem) ; Parameters ....: $hSystem - the system handle. ; Return values .: The system ID. ; Author ........: Kanashius ; Modified ......: ; Remarks .......: Errors: ; 1 - mSystems Map does not exists. Make sure to call __TreeListExplorer_StartUp. ; 2 - No TLE system with the handle $hSystem exists ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__GetSystemIDFromHandle($hSystem) If Not MapExists($__TreeListExplorer__Data, "mSystems") Then Return SetError(1, 0, False) Local $iSystem = $hSystem-1 If $iSystem<0 Then Return SetError(2, 0, False) ; negative key crashes autoit for some reason (and is not valid anyway) If Not MapExists($__TreeListExplorer__Data.mSystems, $iSystem) Then Return SetError(2, 0, False) Return $iSystem EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__GetHandleFromSystemID ; Description ...: Convert a TLE system ID to a TLE system handle ; Syntax ........: __TreeListExplorer__GetHandleFromSystemID($iSystem) ; Parameters ....: $iSystem - the system ID. ; Return values .: The system handle. ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__GetHandleFromSystemID($iSystem) return $iSystem+1 EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__UpdateSystemViews ; Description ...: Update all views of the given TLE system ; Syntax ........: __TreeListExplorer__UpdateSystemViews($iSystem) ; Parameters ....: $iSystem - the system ID. ; Return values .: True on success ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__UpdateSystemViews($iSystem) Local $arViews = MapKeys($__TreeListExplorer__Data["mSystems"][$iSystem]["mViews"]) For $i=0 To UBound($arViews)-1 Step 1 __TreeListExplorer__UpdateView(HWnd($arViews[$i])) Next Return True EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__UpdateView ; Description ...: Update a view to match a TLE systems root folder and current folder ; Syntax ........: __TreeListExplorer__UpdateView($hView) ; Parameters ....: $hView - the control handle. ; $bReload - [optional] Default False. Forces a reload. ; Return values .: None ; Author ........: Kanashius ; Modified ......: ; Remarks .......: Main function to handle all updates. Changes to the view mainly happen here. Only exceptions are the ; initialization (__TreeListExplorer_AddView) and the user expanding a folder (__TreeListExplorer__WinProc) ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__UpdateView($hView, $bReload = False) Local $mView = $__TreeListExplorer__Data.mViews[$hView] Local $mSystem = $__TreeListExplorer__Data.mSystems[$mView.iSystem] Local $iSystem = $mView.iSystem Switch $mView.iType Case $__TreeListExplorer__Type_TreeView _GUICtrlTreeView_BeginUpdate($hView) Case $__TreeListExplorer__Type_ListView _GUICtrlListView_BeginUpdate($hView) EndSwitch ; Root different Local $bRootOrFolderChanged = False If $mView.sRoot<>$mSystem.sRoot Then ; HANDLE LATER: $mSystem.bReloadAllFolders Or ($mView.sRoot="" And $mSystem.sFolder="" And $mSystem.bReloadFolder) If $mView.iType<>$__TreeListExplorer__Type_Input Then __TreeListExplorer__HandleViewCallback($hView, "sCallbackLoading", $mSystem.sRoot, True) If $mSystem.sRoot <> $mSystem.sRootOld Then $__TreeListExplorer__Data["mSystems"][$iSystem]["sRootOld"] = $mSystem.sRoot $bRootOrFolderChanged = True EndIf $__TreeListExplorer__Data["mViews"][$hView]["sRoot"] = $mSystem.sRoot Switch $mView.iType Case $__TreeListExplorer__Type_TreeView _GUICtrlTreeView_DeleteAll($hView) Local $hRoot If $mSystem.sRoot="" Then $hRoot = _GUICtrlTreeView_Add($hView, 0, $__TreeListExplorer__Data.arLangData[$__TreeListExplorer__Data.iLang][3], 9, 9) ; maybe remove text here Else Local $arPath = __TreeListExplorer__GetPathAndLast($mSystem.sRoot) $hRoot = _GUICtrlTreeView_Add($hView, 0, $arPath[1], 0, 0) EndIf _GUICtrlTreeView_AddChild($hView, $hRoot, "HasChilds", 10, 10) __TreeListExplorer__ExpandTreeitem($hView, $hRoot) Case $__TreeListExplorer__Type_ListView $bReload = True EndSwitch __TreeListExplorer__HandleViewCallback($hView, "sCallbackLoading", $mSystem.sRoot, False) EndIf EndIf ; callback folder changed If $mSystem.sFolder <> $mSystem.sFolderOld Then $__TreeListExplorer__Data["mSystems"][$iSystem]["sFolderOld"] = $mSystem.sFolder $bRootOrFolderChanged = True EndIf If $bRootOrFolderChanged Then __TreeListExplorer__HandleSystemCallback($iSystem, "sCallbackFolder") __TreeListExplorer__HandleSystemCallback($iSystem, "sCallbackSelect") If $mView.sFolder <> $mSystem.sFolder Or $mView.sSelected<>$mSystem.sSelected Or $mSystem.bReloadFolder Or $bReload Then Local $bFolderChanged = $mView.sFolder <> $mSystem.sFolder Local $bUpdateFolder = $bFolderChanged Or $mSystem.bReloadFolder Or $bReload $__TreeListExplorer__Data["mViews"][$hView]["sFolder"] = $mSystem.sFolder $__TreeListExplorer__Data["mViews"][$hView]["sSelected"] = $mSystem.sSelected Switch $mView.iType Case $__TreeListExplorer__Type_TreeView __TreeListExplorer__HandleViewCallback($hView, "sCallbackLoading", $mSystem.sFolder, True) Local $sPath = $mSystem.sFolder Local $arPath = StringSplit($sPath, "\", BitOR(1, 2)) Local $hItem = _GUICtrlTreeView_GetFirstItem($hView) Local $hItemBefore = $hItem Local $iMaxIndex = UBound($arPath)-2 Local $sAbsPath = $mSystem.sRoot ; expand path and select last folder (if nothing in that folder is selected) For $i=0 To $iMaxIndex Step 1 ; last is empty $hItem = _GUICtrlTreeView_GetFirstChild($hView, $hItem) If $hItem = 0 Then ExitLoop While _GUICtrlTreeView_GetText($hView, $hItem)<>$arPath[$i] $hItemBefore = $hItem $hItem = _GUICtrlTreeView_GetNextSibling($hView, $hItem) If $hItem = 0 Then ExitLoop 2 WEnd $sAbsPath&=_GUICtrlTreeView_GetText($hView, $hItem)&"\" If Not __TreeListExplorer__PathIsFolder($sAbsPath) Then ; Handle folder being deleted __TreeListExplorer__TreeViewDeleteItem($hView, $hItem) _GUICtrlTreeView_EnsureVisible($hView, $hItemBefore) _GUICtrlTreeView_SelectItem($hView, $hItemBefore) $hItem = 0 ExitLoop EndIf If $i<>$iMaxIndex Then __TreeListExplorer__ExpandTreeitem($hView, $hItem, $mSystem.bReloadAllFolders) Else ; handle last item If $mSystem.sSelected="" Then If $mSystem.bReloadFolder Then __TreeListExplorer__UpdateTreeItemContent($hView, $hItem) _GUICtrlTreeView_EnsureVisible($hView, $hItem) _GUICtrlTreeView_SelectItem($hView, $hItem) __TreeListExplorer__HandleSystemCallback($iSystem, "sCallbackSelect", $arPath[$i]) Else __TreeListExplorer__ExpandTreeitem($hView, $hItem, $mSystem.bReloadFolder) EndIf ExitLoop EndIf Next ; Select the item If $hItem<>0 And $mSystem.sSelected<>"" Then Local $sSelected = $mSystem.sSelected Local $hChild = _GUICtrlTreeView_GetFirstChild($hView, $hItem) While $hChild<>0 ; search and select the item if possible If _GUICtrlTreeView_GetText($hView, $hChild)=$sSelected Then _GUICtrlTreeView_EnsureVisible($hView, $hChild) _GUICtrlTreeView_SelectItem($hView, $hChild) __TreeListExplorer__HandleSystemCallback($iSystem, "sCallbackSelect") ExitLoop EndIf $hChild = _GUICtrlTreeView_GetNextSibling($hView, $hChild) WEnd ElseIf $hItem=_GUICtrlTreeView_GetFirstItem($hView) Then __TreeListExplorer__HandleSystemCallback($iSystem, "sCallbackSelect") EndIf __TreeListExplorer__HandleViewCallback($hView, "sCallbackLoading", $mSystem.sFolder, False) Case $__TreeListExplorer__Type_ListView If $bUpdateFolder Then __TreeListExplorer__HandleViewCallback($hView, "sCallbackLoading", $mSystem.sFolder, True) ; clear old data $__TreeListExplorer__Data["mViews"][$hView]["iIndex"] = -1 __TreeListExplorer__SetViewUpdating($hView, True, $__TreeListExplorer__Status_UpdateView) _GUICtrlListView_DeleteAllItems($hView) ; do not display .. folder in root directory,... If $mSystem.sFolder<>"" And $mView.bNavigation And $mView.bListViewFolderUp Then _GUICtrlListView_AddItem($hView, "", 0) _GUICtrlListView_SetItemText($hView, 0, "..", $mView.iPathIndex) EndIf ; collect drives/folders/files Local $sPath = $mSystem.sRoot & $mSystem.sFolder, $bDrive = False, $iFolderCount = 0 Local $arPaths[0][3] ; [Filename] => [0][0] = col for filenames If $mView.sCallbackListViewPaths<>Default Then ReDim $arPaths[0][1] If $sPath = "" Then ; drives at root level Local $arDrives = __TreeListExplorer__GetDrives() ReDim $arPaths[UBound($arDrives)][UBound($arPaths, 2)] For $i=0 To UBound($arDrives)-1 $arPaths[$i][0] = StringUpper($arDrives[$i][0]) Next $bDrive = True $iFolderCount = UBound($arDrives) Else ; files & folders Local $arFolders[1] = [0], $arFiles[1] = [0] If $mView.bShowFolders Then $arFolders = _FileListToArray($sPath, "*", 2) If $mView.bShowFiles Then $arFiles = _FileListToArray($sPath, "*", 1) ReDim $arPaths[UBound($arFolders) + UBound($arFiles) - (UBound($arFolders)>0?1:0) - (UBound($arFiles)>0?1:0)][UBound($arPaths, 2)] Local $iCount = 0 $iFolderCount = UBound($arFolders)-(UBound($arFolders)>0?1:0) For $i=1 To UBound($arFolders)-1 $arPaths[$iCount][0] = $arFolders[$i] $iCount+=1 Next For $i=1 To UBound($arFiles)-1 $arPaths[$iCount][0] = $arFiles[$i] $iCount+=1 Next EndIf ; enable changes to $arPaths by the user If $mView.sCallbackListViewPaths<>Default Then Local $hSystem = __TreeListExplorer__GetHandleFromSystemID($iSystem) Local $arEditedPaths = Call($mView.sCallbackListViewPaths, $hSystem, $hView, $sPath, $arPaths) ; call manually here to enable ByRef params If @error = 0xDEAD And @extended = 0xBEEF Then __TreeListExplorer__ConsoleWriteCallbackError($mView.sCallbackListViewPaths, "sCallbackListViewPaths", $mSystem.iLineNumber, "__TreeListExplorer_AddView") Else If IsArray($arEditedPaths) And UBound($arEditedPaths, 2)>0 Then $arPaths = $arEditedPaths EndIf Else __TreeListExplorer__ListViewPathHandler($hView, $sPath, $arPaths) EndIf ; handle default sorting If $mView.mSorting.bEnabled Then If $mView.sCallbackListViewPaths=Default And $mView.mSorting.iCol<>1 Then _ArraySort($arPaths, $mView.mSorting.iDir, 0, $iFolderCount-1, $mView.mSorting.iCol) _ArraySort($arPaths, $mView.mSorting.iDir, $iFolderCount, 0, $mView.mSorting.iCol) EndIf ; compact the bytes to readable strings (for default listviews); after sorting, to enable sorting by int, not string If $mView.sCallbackListViewPaths=Default Then For $i=$iFolderCount to UBound($arPaths)-1 $arPaths[$i][1] = __TreeListExplorer__GetSizeString($arPaths[$i][1]) Next EndIf ; add entries to listview For $i=0 to UBound($arPaths)-1 Local $sFile = $arPaths[$i][$mView.iPathIndex] Local $sFilePath = $sPath & $sFile Local $bDriveOrFolder = __TreeListExplorer__PathIsFolder($sFilePath) Local $iIconIndex = __TreeListExplorer__FileGetIconIndex($sFilePath) Local $sFileName = $sFile, $sExt = "" If Not $bDriveOrFolder Then Local $arFileParts = StringRegExp($sFilename, "^(.+?)(\.[^.]{1,5}){0,1}$", 1) If Not @error And UBound($arFileParts)>1 Then $sFilename = $arFileParts[0] $sExt = $arFileParts[1] EndIf EndIf If $mView.sCallbackFilter=Default Or __TreeListExplorer__HandleCallback($iSystem, $hView, "sCallbackFilter", True, $sPath, $sFilename, $sExt) Then If UBound($arPaths, 2)>0 Then Local $iIndex = _GUICtrlListView_AddItem($hView, $arPaths[$i][0], $iIconIndex) For $j=1 To UBound($arPaths, 2)-1 _GUICtrlListView_SetItemText($hView, $iIndex, $arPaths[$i][$j], $j) Next EndIf If $mView.sCallbackListViewItemCreated<>Default Then __TreeListExplorer__HandleCallback($iSystem, $hView, "sCallbackListViewItemCreated", $sFilePath, $sFile, $iIndex, $bDriveOrFolder) EndIf Next __TreeListExplorer__SetViewUpdating($hView, False, $__TreeListExplorer__Status_UpdateView) __TreeListExplorer__HandleViewCallback($hView, "sCallbackLoading", $mSystem.sFolder, False) EndIf If $mSystem.sSelected<>"" Then Local $sSelected = $mSystem.sSelected For $i=0 To _GUICtrlListView_GetItemCount($hView) If _GUICtrlListView_GetItemText($hView, $i, $mView.iPathIndex)=$sSelected Then _GUICtrlListView_EnsureVisible($hView, $i) Local $arSel = _GUICtrlListView_GetSelectedIndices($hView, True) For $j=1 To UBound($arSel)-1 Step 1 _GUICtrlListView_SetItemSelected($hView, $arSel[$j], False) Next _GUICtrlListView_SetSelectionMark($hView, $i) _GUICtrlListView_SetItemSelected($hView, $i) ExitLoop EndIf Next EndIf Case $__TreeListExplorer__Type_Input If $bFolderChanged Then _GUICtrlEdit_SetText($hView, $mSystem.sFolder) EndSwitch EndIf Switch $mView.iType Case $__TreeListExplorer__Type_TreeView _GUICtrlTreeView_EndUpdate($hView) $mView.bUpdating = False Case $__TreeListExplorer__Type_ListView _GUICtrlListView_EndUpdate($hView) EndSwitch EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__ListViewPathHandler ; Description ...: Default path handler to add the default columns ; Syntax ........: __TreeListExplorer__ListViewPathHandler($hView, $sPath, $sFilename, $iIndex, $bFolder) ; Parameters ....: $hView - the handle to the listview. ; $sPath - the path to the file/folder ; $arPaths - the array with files/folders ; Return values .: ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__ListViewPathHandler($hView, $sPath, ByRef $arPaths) For $i=0 to UBound($arPaths)-1 Local $sFilePath = $sPath & $arPaths[$i][0] $arPaths[$i][2] = __TreeListExplorer__GetTimeString($sFilePath) If Not __TreeListExplorer__PathIsFolder($sFilePath) Then $arPaths[$i][1] = FileGetSize($sFilePath) Next Return $arPaths EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__GetSizeString ; Description ...: Get the size formatted to the nearest magnitude (B, KB, MB, GB, TB, PB, EB). ; Syntax ........: __TreeListExplorer__GetSizeString($iSize) ; Parameters ....: $iSize - the size in bytes. ; Return values .: The formatted size string. ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__GetSizeString($iSize) Local Static $arSizeName = [" B", "KB", "MB", "GB", "TB", "PB", "EB"] For $i = UBound($arSizeName) To 1 Step -1 If $iSize >= 1024 ^ $i Then Return Round($iSize/(1024^$i), 2) & " " & $arSizeName[$i] Next Return $iSize & " " & $arSizeName[0] EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__GetTimeString ; Description ...: Get the formatted file creation date (YYYY/MM/DD HH:MM:SS) ; Syntax ........: __TreeListExplorer__GetTimeString($sPath) ; Parameters ....: $sPath - the path of the file or an array with [year, month, day, hour, minute, second] ; Return values .: The creation date ; Author ........: Kanashius ; Modified ......: ; Remarks .......: Errors: ; 1 - Error calling FileGetTime (@extended contains the error from FileGetTime) ; 2 - $sPath was an array of size <6 ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__GetTimeString($sPath) Local $arTime If IsArray($sPath) Then $arTime = $sPath If UBound($arTime)<6 Then Return SetError(2, @error, "") Else $arTime = FileGetTime($sPath, 1) If @error Then Return SetError(1, @error, "") EndIf Return StringFormat("%u/%02u/%02u %02u:%02u:%02u", $arTime[0], $arTime[1], $arTime[2], $arTime[3], $arTime[4], $arTime[5]) EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__FileGetIconIndex ; Description ...: Get the index of an icon in $__TreeListExplorer__Data.hIconList for a given extension and add missing icons. ; Syntax ........: __TreeListExplorer__FileGetIconIndex($sPath) ; Parameters ....: $sPath - the absolute path. ; Return values .: The index ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__FileGetIconIndex($sPath) ; test for drive Local $arRegExpDrive = StringRegExp($sPath, "^([^\/]+?:)\/*$", 1) If UBound($arRegExpDrive)>0 Then return __TreeListExplorer__GetDriveIconId($arRegExpDrive[0]) ; test for folder If __TreeListExplorer__PathIsFolder($sPath) Then Return 0 ; Default folder icon ; extract and handle cached extensions Local $arExt = StringRegExp($sPath, "^.*[^\\](\.[^\\]*?)$", 1) If @error Or UBound($arExt)<>1 Then Return 2 ; Default file icon Local $sExt = StringLower($arExt[0]) If MapExists($__TreeListExplorer__Data.mIcons, $sExt) Then Return $__TreeListExplorer__Data.mIcons[$sExt] If MapExists($__TreeListExplorer__Data.mIcons, $sPath) Then Return $__TreeListExplorer__Data.mIcons[$sPath] Local $sIconPath = -1, $iIconIndex = 0, $bAddForExtension = False ; handle .url (links) If $sExt=".url" Then $sIconPath = IniRead($sPath, "InternetShortcut", "IconFile", -1) $iIconIndex = IniRead($sPath, "InternetShortcut", "IconIndex", -1) EndIf ; handle .lnk (shortcuts) If $sExt=".lnk" Then ; todo maybe add the link symbol (arrow) to the icon EndIf ; Handling for special extensions Switch $sExt Case ".exe" $sIconPath = $sPath Case ".url" $sIconPath = IniRead($sPath, "InternetShortcut", "IconFile", -1) $iIconIndex = IniRead($sPath, "InternetShortcut", "IconIndex", -1) Case ".lnk" Local $arShortcutData = FileGetShortcut($sPath) If $arShortcutData[4]<>"" Then ; icon file provided $sIconPath = $arShortcutData[4] $iIconIndex = $arShortcutData[5] Else ; otherwise get icon from the linked path Return __TreeListExplorer__FileGetIconIndex($arShortcutData[0]) EndIf EndSwitch If $sIconPath=-1 Then Local $sRegData = RegRead("HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\" & $sExt, "ProgID") If @error Then $sRegData = RegRead("HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\" & $sExt & "\UserChoice", "ProgID") If @error Then $sRegData = RegRead("HKCR\" & $sExt, "") EndIf EndIf If $sRegData<>"" Then $sRegData = RegRead("HKCR\" & $sRegData & "\DefaultIcon", "") If $sRegData="" Then $sRegData = _WinAPI_AssocQueryString($sExt, $ASSOCSTR_DEFAULTICON) If StringInStr($sRegData, "@")=1 Then ; Handle urls with @{...} Local $sIconPath = _WinAPI_LoadIndirectString($sRegData) If @error Then $sIconPath = -1 Local $arRes = StringRegExp($sIconPath, "^(.*\\)(.*-)(\d+)(\.\S+)$", 1) If Not (@error And UBound($arRes)<>4) Then ; check for files with a pixel resolution closer to $iIconSize Local $iIconSize = $__TreeListExplorer__Data.iIconSize Local $arFiles = _FileListToArray($arRes[0], $arRes[1]&"*"&$arRes[3]) Local $arOptions[UBound($arFiles)-1][2], $iCount = 0 For $i=1 To UBound($arFiles)-1 Step 1 ; get icon size for all files Local $arFileParts = StringRegExp($arFiles[$i], "^.*-(\d+)\.\S+$", 1) If Not @error Then $arOptions[$iCount][0] = Int($arFileParts[0]) $arOptions[$iCount][1] = $arFiles[$i] $iCount+=1 EndIf Next ReDim $arOptions[$iCount][2] _ArraySort($arOptions) ; sort by size For $i=0 To UBound($arOptions)-1 Step 1 ; take the best icon to be used (>= target icon size); Resize will be done later If $iIconSize<=$arOptions[$i][0] Then $sIconPath = $arRes[0]&$arOptions[$i][1] ExitLoop EndIf Next EndIf ElseIf StringInStr($sRegData, ",") Then ; Handle , e.g.: ...shell32.dll, 0 Local $arParts = StringRegExp($sRegData, '"?(.*?)"?,(-?\d+)', 1) If UBound($arParts)=2 Then $sIconPath = $arParts[0] $iIconIndex = $arParts[1] EndIf ElseIf $sRegData<>"" Then ; Handle path without index $sIconPath = $sRegData EndIf $bAddForExtension = True EndIf If $sIconPath<>-1 Then Local $sIconExt = StringRight($sIconPath, 4), $sMapKey = $sPath If $bAddForExtension Then $sMapKey = $sExt If $sIconExt=".dll" Or $sIconExt=".exe" Or $sIconExt=".ico" Then ; icon to extract Local $iIconSize = $__TreeListExplorer__Data.iIconSize Local $hIcon = _WinAPI_ShellExtractIcon($sIconPath, $iIconIndex, $iIconSize, $iIconSize) If $hIcon<>0 Then Local $iIndex = _GUIImageList_ReplaceIcon($__TreeListExplorer__Data.hIconList, -1, $hIcon) If $iIndex>=0 Then $__TreeListExplorer__Data["mIcons"][$sMapKey] = $iIndex Return $iIndex EndIf EndIf Else ; normal image file Local $hBitmap = _GDIPlus_BitmapCreateFromFile($sIconPath) If @error Then Return 2 ; Default file icon Local $iIconSize = $__TreeListExplorer__Data.iIconSize Local $hBitmapResized = _GDIPlus_ImageResize($hBitmap, $iIconSize, $iIconSize) Local $hImg = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmapResized) Local $iIndex = _GUIImageList_Add($__TreeListExplorer__Data.hIconList, $hImg) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_BitmapDispose($hBitmapResized) If $iIndex>=0 Then $__TreeListExplorer__Data["mIcons"][$sMapKey] = $iIndex Return $iIndex EndIf EndIf Else Local $tSHFILEINFO = DllStructCreate($tagSHFILEINFO) Local $dwFlags = BitOR($SHGFI_USEFILEATTRIBUTES, $SHGFI_ICON, $SHGFI_ICONLOCATION) _WinAPI_ShellGetFileInfo($sPath, $dwFlags, $FILE_ATTRIBUTE_NORMAL, $tSHFILEINFO) If DllStructGetData($tSHFILEINFO, 2)<>0 Then ; ignore missing icons (SystemIcon=0 equals Default file icon) If DllStructGetData($tSHFILEINFO, 1)>0 Then Local $iIndex = _GUIImageList_ReplaceIcon($__TreeListExplorer__Data.hIconList, -1, DllStructGetData($tSHFILEINFO, 1)) If $iIndex>=0 Then $__TreeListExplorer__Data["mIcons"][$sExt] = $iIndex Return $iIndex EndIf EndIf Else If DllStructGetData($tSHFILEINFO, 1)>0 Then _WinAPI_DestroyIcon(DllStructGetData($tSHFILEINFO, 1)) EndIf EndIf Return 2 ; Default file icon EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__ExpandTreeitem ; Description ...: Expand a TreeItem and load the content of all childs (Show the extend button, if they have childs) ; Syntax ........: __TreeListExplorer__ExpandTreeitem($hView, $hItem[, $bReload = False]) ; Parameters ....: $hView - the TreeView handle. ; $hItem - the item handle. ; $bReload - [optional] if true the childs of the item are reloaded ; Return values .: True on success ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__ExpandTreeitem($hView, $hItem, $bReload = False) If _GUICtrlTreeView_GetExpanded($hView, $hItem) And Not $bReload Then Return True __TreeListExplorer__SetViewUpdating($hView, True, $__TreeListExplorer__Status_ExpandTree) _SendMessage($hView, $TVM_EXPAND, $TVE_EXPAND, $hItem, 0, "wparam", "handle") __TreeListExplorer__UpdateTreeItemContent($hView, $hItem) __TreeListExplorer__SetViewUpdating($hView, False, $__TreeListExplorer__Status_ExpandTree) Return True EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__UpdateTreeItemContent ; Description ...: Load or update the content of a treeview item to fill it with files/folders/drives ; Syntax ........: __TreeListExplorer__UpdateTreeItemContent($hView, $hItem[, $bRecursive = False]) ; Parameters ....: $hView - a treeview handle. ; $hItem - a item to update. ; $bRecursive - [optional] True if it is called recursive. Default is False. ; Return values .: True on success. ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__UpdateTreeItemContent($hView, $hItem, $bRecursive = False) Local $mView = $__TreeListExplorer__Data.mViews[$hView] Local $iSystem = $mView.iSystem Local $mSystem = $__TreeListExplorer__Data.mSystems[$iSystem] Local $bExpand = True If $mSystem.iMaxDepth<>Default Then If __TreeListExplorer__GetTreeViewItemDepth($hView, $hItem)>=$mSystem.iMaxDepth Then Return False $bExpand = Not (__TreeListExplorer__GetTreeViewItemDepth($hView, $hItem)+1>=$mSystem.iMaxDepth) EndIf If Not $bRecursive Then __TreeListExplorer__SetViewUpdating($hView, True, $__TreeListExplorer__Status_LoadTree) ; get absolute path for item Local $arPath = StringRegExp(StringReplace(_GUICtrlTreeView_GetTree($hView, $hItem), "|", "\"), "[^\\]*\\?(.*)$", 1) ; remove first element (root) If @error Or UBound($arPath)<>1 Then Return False Local $sPath = $mSystem.sRoot & $arPath[0] ; Get Content data (drives/folders/files) Local $arEntries[0][3], $bHasFilterCallback = $mView.sCallbackFilter<>Default If $sPath = "" Then ; handle root => show drives Local $arDrives = __TreeListExplorer__GetDrives() ReDim $arEntries[UBound($arDrives)][3] For $i=0 To UBound($arDrives)-1 Step 1 $arEntries[$i][0] = $arDrives[$i][0] $arEntries[$i][1] = $arDrives[$i][1] $arEntries[$i][2] = True If $bHasFilterCallback Then $arEntries[$i][2] = __TreeListExplorer__HandleCallback($iSystem, $hView, "sCallbackFilter", True, "", $arDrives[$i][0], "") EndIf Next Else ; handle any other folder Local $arFolders[0] Local $arFiles[0] If $mView.bShowFolders Then $arFolders = _FileListToArray($sPath, "*", 2) If $mView.bShowFiles Then $arFiles = _FileListToArray($sPath, "*", 1) Local $iSize = UBound($arFolders) + UBound($arFiles) - (UBound($arFolders)>0?1:0) - (UBound($arFiles)>0?1:0) ReDim $arEntries[$iSize][3] For $i=1 To UBound($arFolders)-1 Step 1 $arEntries[$i-1][0] = $arFolders[$i] $arEntries[$i-1][1] = 0 $arEntries[$i-1][2] = True If $bHasFilterCallback Then $arEntries[$i-1][2] = __TreeListExplorer__HandleCallback($iSystem, $hView, "sCallbackFilter", True, $sPath, $arFolders[$i], "") EndIf Next Local $iIndex = UBound($arFolders)-1-(UBound($arFolders)>0?1:0) For $i=1 To UBound($arFiles)-1 Step 1 $arEntries[$iIndex+$i][0] = $arFiles[$i] $arEntries[$iIndex+$i][1] = __TreeListExplorer__FileGetIconIndex($sPath & "\" & $arFiles[$i]) $arEntries[$iIndex+$i][2] = True If $bHasFilterCallback Then Local $sFilename = $arFiles[$i], $sExt = "" Local $arFileParts = StringRegExp($sFilename, "^(.+?)(\.[^.]{1,5}){0,1}$", 1) If Not @error And UBound($arFileParts)>1 Then $sFilename = $arFileParts[0] $sExt = $arFileParts[1] EndIf $arEntries[$iIndex+$i][2] = __TreeListExplorer__HandleCallback($iSystem, $hView, "sCallbackFilter", False, $sPath, $sFilename, $sExt) EndIf Next EndIf ; add/insert new items and update existing ones Local $hChild = _GUICtrlTreeView_GetFirstChild($hView, $hItem), $hChildBefore = 0 Local $sPathPrefix = $sPath & "\" If $sPath="" Then $sPathPrefix = "" ; delete Local $hChild = _GUICtrlTreeView_GetFirstChild($hView, $hItem), $iStart = 0 ; remove dummy item, if it is there If _GUICtrlTreeView_GetImageIndex($hView, $hChild) = 10 And _GUICtrlTreeView_GetText($hView, $hChild)="HasChilds" Then Local $hBefore = $hChild $hChild = _GUICtrlTreeView_GetNextSibling($hView, $hChild) __TreeListExplorer__TreeViewDeleteItem($hView, $hBefore) EndIf ; remove deleted items While $hChild<>0 Local $bFound = False For $i=$iStart To UBound($arEntries)-1 Step 1 If $arEntries[$i][2] And _GUICtrlTreeView_GetText($hView, $hChild)=$arEntries[$i][0] And _GUICtrlTreeView_GetImageIndex($hView, $hChild)=$arEntries[$i][1] Then $iStart = $i+1 ; skip all entries already found $bFound = True ExitLoop EndIf Next Local $hBefore = $hChild $hChild = _GUICtrlTreeView_GetNextSibling($hView, $hChild) If Not $bFound Then __TreeListExplorer__TreeViewDeleteItem($hView, $hBefore) WEnd ; add/insert/update Local $hChild = _GUICtrlTreeView_GetFirstChild($hView, $hItem) For $i=0 To UBound($arEntries)-1 Step 1 If $arEntries[$i][2] Then Local $sChildPath = $sPathPrefix & $arEntries[$i][0] If $hChild=0 Then Local $hNew = _GUICtrlTreeView_AddChild($hView, $hItem, $arEntries[$i][0], $arEntries[$i][1], $arEntries[$i][1]) $hChildBefore = $hNew If $bExpand Then __TreeListExplorer__UpdateTreeItemExpandable($hView, $hNew, $sChildPath, $mView.bShowFiles) Else If _GUICtrlTreeView_GetText($hView, $hChild)<>$arEntries[$i][0] Or _GUICtrlTreeView_GetImageIndex($hView, $hChild)<>$arEntries[$i][1] Then Local $hNew If $hChildBefore = 0 Then $hNew = _GUICtrlTreeView_AddChildFirst($hView, $hItem, $arEntries[$i][0], $arEntries[$i][1], $arEntries[$i][1]) Else $hNew = _GUICtrlTreeView_InsertItem($hView, $arEntries[$i][0], $hItem, $hChildBefore, $arEntries[$i][1], $arEntries[$i][1]) EndIf $hChildBefore = $hNew If $bExpand Then __TreeListExplorer__UpdateTreeItemExpandable($hView, $hNew, $sChildPath, $mView.bShowFiles) Else $hChildBefore = $hChild If _GUICtrlTreeView_GetExpanded($hView, $hChild) Then __TreeListExplorer__UpdateTreeItemContent($hView, $hChild, True) ; if child is expanded, update content Else ; if not, check if should still be expandable _GUICtrlTreeView_DeleteChildren($hView, $hChild) If $bExpand Then __TreeListExplorer__UpdateTreeItemExpandable($hView, $hChild, $sChildPath, $mView.bShowFiles) EndIf $hChild = _GUICtrlTreeView_GetNextSibling($hView, $hChild) EndIf EndIf EndIf Next If Not $bRecursive Then __TreeListExplorer__SetViewUpdating($hView, False, $__TreeListExplorer__Status_LoadTree) Return True EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__TreeViewDeleteItem ; Description ...: _GUICtrlTreeView_Delete randomly does not work using x64 AutoIt and sometimes randomly deletes controls ; This is a fix to prevent that from happening. ; Syntax ........: __TreeListExplorer__TreeViewDeleteItem($hView, $hItem) ; Parameters ....: $hView - the treeview handle. ; $hItem - the item handle. ; Return values .: True on success ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__TreeViewDeleteItem($hView, $hItem) If Not IsHWnd($hView) Then $hView = GUICtrlGetHandle($hView) If Not IsPtr($hItem) Then $hItem = _GUICtrlTreeView_GetItemHandle($hView, $hItem) Return _SendMessage($hView, $TVM_DELETEITEM, 0, $hItem, 0, "wparam", "handle", "hwnd") <> 0 EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__GetTreeViewItemDepth ; Description ...: Get the depth of a TreeView item ; Syntax ........: __TreeListExplorer__GetTreeViewItemDepth($hView, $hItem) ; Parameters ....: $hView - the treeview handle. ; $hItem - the item handle. ; Return values .: The depth ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__GetTreeViewItemDepth($hView, $hItem) Local $iDepth = 0 Local $hParent = _GUICtrlTreeView_GetParentHandle($hView, $hItem) While $hParent<>0 $hParent = _GUICtrlTreeView_GetParentHandle($hView, $hParent) $iDepth += 1 WEnd Return $iDepth - 1 ; root item does not count EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__UpdateTreeItemExpandable ; Description ...: Check if a TreeView item will have child elements. If yes, then add a dummy element to make it expandable ; Syntax ........: __TreeListExplorer__UpdateTreeItemExpandable($hView, $hItem, $sPath, $bShowFiles) ; Parameters ....: $hView - the treeview handle. ; $hItem - the item handle. ; $sPath - the path to check. ; $bShowFiles - True if files allow the item to be expanded. ; Return values .: True on success. ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__UpdateTreeItemExpandable($hView, $hItem, $sPath, $bShowFiles) If $bShowFiles Then Local $hSearch = FileFindFirstFile($sPath & "\" & "*") If $hSearch<>-1 Then FileClose($hSearch) _GUICtrlTreeView_AddChild($hView, $hItem, "HasChilds", 10, 10) EndIf Else Local $hSearch = FileFindFirstFile($sPath & "\" & "*") If $hSearch<>-1 Then While True FileFindNextFile($hSearch) If @error Then ExitLoop If @extended=1 Then _GUICtrlTreeView_AddChild($hView, $hItem, "HasChilds", 10, 10) ExitLoop EndIf WEnd FileClose($hSearch) EndIf EndIf Return True EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__GetDrives ; Description ...: Get all drives and their type ; Syntax ........: __TreeListExplorer__GetDrives() ; Parameters ....: ; Return values .: An Array with all drives. $arDrives[N][0] = Drive name, $arDrives[N][1] = Id of the type ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__GetDrives() Local $arDrives = DriveGetDrive('ALL'), $iType Local $arResult[UBound($arDrives)-1][2] For $i = 1 To UBound($arDrives)-1 $arResult[$i-1][0] = StringUpper($arDrives[$i]) Switch DriveGetType($arDrives[$i]) Case 'Fixed' $arResult[$i-1][1] = 5 Case 'CDROM' $arResult[$i-1][1] = 6 Case 'RAMDisk' $arResult[$i-1][1] = 7 Case 'Removable' $arResult[$i-1][1] = 4 If StringLeft($arDrives[$i], 2) = "A:" Or StringLeft($arDrives[$i], 2) = "B:" Then $arResult[$i-1][1] = 3 Case Else $arResult[$i-1][1] = 8 EndSwitch Next Return $arResult EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__GetDriveIconId ; Description ...: Get the icon for a drive. ; Syntax ........: __TreeListExplorer__GetDriveIconId($sDrive) ; Parameters ....: ; Return values .: Id of the icon (or 0 if not matched) ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__GetDriveIconId($sDrive) Switch DriveGetType($sDrive) Case 'Fixed' return 5 Case 'CDROM' return 6 Case 'RAMDisk' return 7 Case 'Removable' return 4 If StringLeft($sDrive, 2) = "A:" Or StringLeft($sDrive, 2) = "B:" Then return 3 Case Else return 8 EndSwitch return 0 EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__UpdateTreeViewSelection ; Description ...: Handle the selection of a TreeView item (extending/collapsing the item) ; Syntax ........: __TreeListExplorer__UpdateTreeViewSelection($hView, $hItem) ; Parameters ....: $hView - the TreeView handle. ; $hItem - the item handle. ; Return values .: True on success ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__UpdateTreeViewSelection($hView, $hItem) If MapExists($__TreeListExplorer__Data.mViews, $hView) Then Local $iSystem = $__TreeListExplorer__Data.mViews[$hView].iSystem Local $sPath = __TreeListExplorer__TreeViewGetRelPath($iSystem, $hView, $hItem) If __TreeListExplorer__RelPathIsFolder($iSystem, $sPath) Then If Not _GUICtrlTreeView_GetExpanded($hView, $hItem) Or Not __TreeListExplorer__IsPathOpen($iSystem, $sPath) Then $__TreeListExplorer__Data["mSystems"][$iSystem]["bReloadFolder"] = True __TreeListExplorer__OpenPath($iSystem, $sPath) $__TreeListExplorer__Data["mSystems"][$iSystem]["bReloadFolder"] = False Else _SendMessage($hView, $TVM_EXPAND, $TVE_COLLAPSE, $hItem, 0, "wparam", "handle") EndIf ElseIf __TreeListExplorer__RelPathIsFile($iSystem, $sPath) Then __TreeListExplorer__OpenPath($iSystem, $sPath) EndIf EndIf Return True EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__TreeViewGetRelPath ; Description ...: Get the path of the TreeView item, relative to the TLE system root ; Syntax ........: __TreeListExplorer__TreeViewGetRelPath($iSystem, $hView, $hItem) ; Parameters ....: $iSystem - the system ID. ; $hView - the TreeView handle. ; $hItem - the item handle. ; Return values .: The path ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__TreeViewGetRelPath($iSystem, $hView, $hItem) Local $sPath = StringReplace(_GUICtrlTreeView_GetTree($hView, $hItem), "|", "\") $arPath = StringRegExp($sPath, "[^\\]*\\?(.*)$", 1) ; remove first root element If UBound($arPath)>0 Then $sPath = $arPath[0] If $sPath<>"" And StringRight($sPath, 1)<>"\" And __TreeListExplorer__RelPathIsFolder($iSystem, $sPath) Then $sPath &= "\" Return $sPath EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__IsViewUpdating ; Description ...: Check if a View is currently updated (used to prevent events from propagating during view changes) ; Syntax ........: __TreeListExplorer__IsViewUpdating($hView) ; Parameters ....: $hView - the view handle value. ; $iStatus - [optional] an integer value, specifying which update status should be set. ; Possible: $__TreeListExplorer__Status_UpdateView, $__TreeListExplorer__Status_ExpandTree, ; $__TreeListExplorer__Status_LoadTree, $__TreeListExplorer__Status_WaitOpenPath ; Using Default is checking if any Status is set => anything is updating. ; Return values .: True if the view is being updated ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__IsViewUpdating($hView, $iStatus = Default) If $iStatus=Default Then Return $__TreeListExplorer__Data.mViews[$hView].iUpdating>0 Return BitAND($__TreeListExplorer__Data.mViews[$hView].iUpdating, $iStatus)>0 EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__SetViewUpdating ; Description ...: Set the update status of a View. Differentiates between different update parts. ; Syntax ........: __TreeListExplorer__SetViewUpdating($hView[, $bUpdating = False[, $iStatus = $__TreeListExplorer__Status_UpdateView]]) ; Parameters ....: $hView - a view handle value. ; $bUpdating - [optional] a boolean value. If True the View is updating, if False, the update is done. Default is False. ; $iStatus - [optional] an integer value, specifying which update status should be set. ; Possible: $__TreeListExplorer__Status_UpdateView, $__TreeListExplorer__Status_ExpandTree, ; $__TreeListExplorer__Status_LoadTree, $__TreeListExplorer__Status_WaitOpenPath ; Default is $__TreeListExplorer__Status_UpdateView. ; Return values .: None ; Author ........: Kanashius ; Modified ......: ; Remarks .......: Used to set different update states, which can occour at the same time. This is why it is not a simple boolean ; value. Each Bit represents a different type of update that is currently running. ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__SetViewUpdating($hView, $bUpdating = False, $iStatus = $__TreeListExplorer__Status_UpdateView) If $bUpdating Then $__TreeListExplorer__Data["mViews"][$hView]["iUpdating"] = BitOR($__TreeListExplorer__Data.mViews[$hView].iUpdating, $iStatus) ; add $iStatus Else $__TreeListExplorer__Data["mViews"][$hView]["iUpdating"] = BitAND($__TreeListExplorer__Data.mViews[$hView].iUpdating, BitNOT($iStatus)) ; remove $iStatus EndIf EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__PathIsFolder ; Description ...: Check if the provided path is a folder ; Syntax ........: __TreeListExplorer__PathIsFolder($sPath) ; Parameters ....: $sPath - the path to check. ; Return values .: True if $sPath is a folder ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__PathIsFolder($sPath) Return StringInStr(FileGetAttrib($sPath), "D") EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__PathIsFile ; Description ...: Check if the provided path is a folder ; Syntax ........: __TreeListExplorer__PathIsFile($sPath) ; Parameters ....: $sPath - the path to check. ; Return values .: True if $sPath is a file ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__PathIsFile($sPath) Return FileExists($sPath) And (Not StringInStr(FileGetAttrib($sPath), "D")) EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__RelPathIsFolder ; Description ...: Check if the provided relative path is a folder ; Syntax ........: __TreeListExplorer__RelPathIsFolder($iSystem, $sPath) ; Parameters ....: $iSystem - the system ID. ; $sPath - the path to check. ; Return values .: True if $sPath is a folder ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__RelPathIsFolder($iSystem, $sPath) Return __TreeListExplorer__PathIsFolder($__TreeListExplorer__Data.mSystems[$iSystem].sRoot & $sPath) EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__RelPathIsFile ; Description ...: Check if the provided relative path is a file ; Syntax ........: __TreeListExplorer__RelPathIsFile($iSystem, $sPath) ; Parameters ....: $iSystem - the system ID. ; $sPath - the path to check. ; Return values .: True if $sPath is a folder ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__RelPathIsFile($iSystem, $sPath) Return __TreeListExplorer__PathIsFile($__TreeListExplorer__Data.mSystems[$iSystem].sRoot & $sPath) EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__KeyProc ; Description ...: KeyProc message handler ; Syntax ........: __TreeListExplorer__KeyProc($nCode, $wParam, $lParam) ; Parameters ....: $nCode - the nCode. ; $wParam - wParam. ; $lParam - lParam. ; Return values .: Result of the message processing ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__KeyProc($nCode, $wParam, $lParam) Local static $bCTRL_DOWN = False, $bSHIFT_DOWN = False If $nCode < 0 Then Return _WinAPI_CallNextHookEx($__TreeListExplorer__Data.hKeyPrevHook, $nCode, $wParam, $lParam) Local $tKEYHOOKS = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam) Local $vkCode = DllStructGetData($tKEYHOOKS, "vkCode") Local $bALT_DOWN = BitAND(DllStructGetData($tKEYHOOKS, "flags"), $LLKHF_ALTDOWN)>0 Switch $wParam Case $WM_KEYDOWN If $vkCode=160 Then $__TreeListExplorer__Data.bSHIFT_DOWN = True If $vkCode=162 Then $__TreeListExplorer__Data.bCTRL_DOWN = True Case $WM_KEYUP, $WM_SYSKEYUP If $vkCode=160 Then $__TreeListExplorer__Data.bSHIFT_DOWN = False If $vkCode=162 Then $__TreeListExplorer__Data.bCTRL_DOWN = False Local $hGui = WinGetHandle("[active]") If MapExists($__TreeListExplorer__Data.mGuis, $hGui) Then Local $sControl = ControlGetFocus($hGui) Local $hView = ControlGetHandle($hGui, "", $sControl) Local $arHwnds = MapKeys($__TreeListExplorer__Data.mViews) For $i=0 To UBound($arHwnds)-1 Step 1 If $arHwnds[$i]<>$hView Then ContinueLoop Local $mView = $__TreeListExplorer__Data.mViews[$hView] Local $iSystem = $mView.iSystem Switch $__TreeListExplorer__Data.mViews[$hView].iType Case $__TreeListExplorer__Type_Input If $vkCode=13 Then __TreeListExplorer_OpenPath(__TreeListExplorer__GetHandleFromSystemID($iSystem), _GUICtrlEdit_GetText($hView)) Case $__TreeListExplorer__Type_ListView Switch $vkCode Case 13 __TreeListExplorer__ListViewOpenCurrentItem($iSystem, $hView) Case 65 If $__TreeListExplorer__Data.bCTRL_DOWN Then For $j=0 to _GUICtrlListView_GetItemCount($hView) _GUICtrlListView_SetItemSelected($hView, $j, True) Next EndIf EndSwitch EndSwitch Next EndIf EndSwitch Return _WinAPI_CallNextHookEx($__TreeListExplorer__Data.hKeyPrevHook, $nCode, $wParam, $lParam) EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__WinProc ; Description ...: WinProc gui message handler ; Syntax ........: __TreeListExplorer__WinProc($hWnd, $iMsg, $iwParam, $ilParam) ; Parameters ....: $hWnd - the gui handle. ; $iMsg - iMsg. ; $iwParam - iwParam. ; $ilParam - ilParam. ; Return values .: Result of the message processing ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__WinProc($hWnd, $iMsg, $iwParam, $ilParam) Local Static $bWasMarqueeStarted = False If $iMsg=$WM_NOTIFY Then Local $hView, $iCode, $tNMHDR $tNMHDR = DllStructCreate($tagNMHDR, $ilParam) $hView = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iCode = DllStructGetData($tNMHDR, "Code") Local $arHwnds = MapKeys($__TreeListExplorer__Data.mViews) For $i=0 To UBound($arHwnds)-1 Step 1 If $arHwnds[$i]<>$hView Then ContinueLoop Local $mView = $__TreeListExplorer__Data.mViews[$hView] Local $iSystem = $mView.iSystem Switch $__TreeListExplorer__Data.mViews[$hView].iType Case $__TreeListExplorer__Type_TreeView Switch $iCode Case $TVN_ITEMEXPANDINGA, $TVN_ITEMEXPANDINGW Local $tNMTREEVIEW = DllStructCreate($tagNMTREEVIEW, $ilParam) Local $hItem = DllStructGetData($tNMTREEVIEW, 'NewhItem') If $hItem<>0 Then Switch DllStructGetData($tNMTREEVIEW, 'Action') Case $TVE_EXPAND If Not __TreeListExplorer__IsViewUpdating($hView, $__TreeListExplorer__Status_ExpandTree) Then __TreeListExplorer__SetViewUpdating($hView, True, $__TreeListExplorer__Status_ExpandTree) Local $sPath = __TreeListExplorer__TreeViewGetRelPath($iSystem, $hView, $hItem) __TreeListExplorer__HandleViewCallback($hView, "sCallbackLoading", $sPath, True) _GUICtrlTreeView_BeginUpdate($hView) __TreeListExplorer__ExpandTreeitem($hView, $hItem) _GUICtrlTreeView_EndUpdate($hView) __TreeListExplorer__HandleViewCallback($hView, "sCallbackLoading", $sPath, False) __TreeListExplorer__SetViewUpdating($hView, False, $__TreeListExplorer__Status_ExpandTree) EndIf EndSwitch EndIf Case $NM_CLICK Local $iX =_WinAPI_GetMousePosX(True, $hView) Local $iY =_WinAPI_GetMousePosY(True, $hView) Local $hItem =_GUICtrlTreeView_HitTestItem($hView, $iX, $iY) Local $iHitStat =_GUICtrlTreeView_HitTest($hView, $iX, $iY) If $hItem<>0 And (BitAND($iHitStat, 4) Or BitAND($iHitStat, 2)) Then Local $sPath = __TreeListExplorer__TreeViewGetRelPath($iSystem, $hView, $hItem) __TreeListExplorer__OpenPath($iSystem, $sPath) __TreeListExplorer__HandleViewCallback($hView, "sCallbackClick", $hItem) EndIf Case $NM_DBLCLK Local $iX =_WinAPI_GetMousePosX(True, $hView) Local $iY =_WinAPI_GetMousePosY(True, $hView) Local $hItem =_GUICtrlTreeView_HitTestItem($hView, $iX, $iY) Local $iHitStat =_GUICtrlTreeView_HitTest($hView, $iX, $iY) If $hItem<>0 And (BitAND($iHitStat, 4) Or BitAND($iHitStat, 2)) Then __TreeListExplorer__HandleViewCallback($hView, "sCallbackDoubleClick", $hItem) EndIf Case $TVN_SELCHANGEDA, $TVN_SELCHANGEDW Local $tNMTREEVIEW = DllStructCreate($tagNMTREEVIEW, $ilParam) Switch DllStructGetData($tNMTREEVIEW, 'Action') Case $TVC_BYKEYBOARD Local $hItem = _GUICtrlTreeView_GetSelection($hView) If $hItem<>0 And Not __TreeListExplorer__IsViewUpdating($hView) Then Local $sPath = __TreeListExplorer__TreeViewGetRelPath($iSystem, $hView, $hItem) __TreeListExplorer__OpenPath($iSystem, $sPath) EndIf EndSwitch EndSwitch Case $__TreeListExplorer__Type_ListView Switch $iCode Case $NM_CLICK, $LVN_KEYDOWN Local $iIndex = _GUICtrlListView_GetSelectionMark($hView) Local $bKeyPressed = False If $iCode=$LVN_KEYDOWN Then Local $tLVKeyDown = DllStructCreate($tagNMLVKEYDOWN, $ilParam) Local $iVKey = DllStructGetData($tLVKeyDown, "VKey") $bKeyPressed = ($iVKey=40) Or ($iVKey=38) ; Key pressed: UP or DOWN If $iIndex<>-1 Then If $iVKey=40 Then ; Down $iIndex = $iIndex + 1 If $iIndex>=_GUICtrlListView_GetItemCount($hView) Then $iIndex = -1 ElseIf $iVKey=38 Then ; Up $iIndex = $iIndex - 1 If $iIndex<0 Then $iIndex=0 EndIf EndIf EndIf If $bKeyPressed And $iIndex=-1 And _GUICtrlListView_GetItemCount($hView)>0 Then $iIndex = 0 If _GUICtrlListView_GetItemCount($hView)>1 And _GUICtrlListView_GetItemText($hView, 0, $mView.iPathIndex)=".." Then $iIndex = 1 EndIf If $iCode=$NM_CLICK Or $bKeyPressed Then If $iIndex<>-1 And Not ($iIndex=0 And _GUICtrlListView_GetItemText($hView, $iIndex, $mView.iPathIndex)="..") Then If NOT $__TreeListExplorer__Data.bCTRL_DOWN Then ; do not open/select when CTRL+CLICK multiselecting Local $arPath = __TreeListExplorer__GetPathAndLast(__TreeListExplorer__GetCurrentPath($iSystem) & _GUICtrlListView_GetItemText($hView, $iIndex, $mView.iPathIndex)) Local $mOpenPathData[] $mOpenPathData.sFolder = $arPath[0] $mOpenPathData.sSelect = $arPath[1] $mOpenPathData.iSystem = $iSystem $mOpenPathData.iIndex = $iIndex $mOpenPathData.hView = $hView $mOpenPathData.bWasClick = ($iCode=$NM_CLICK) And Not $bWasMarqueeStarted $mOpenPathData.bMarquee = $bWasMarqueeStarted $__TreeListExplorer__Data["mOpenPathViews"][$hView] = $mOpenPathData __TreeListExplorer__SetViewUpdating($hView, True, $__TreeListExplorer__Status_WaitOpenPath) AdlibRegister("__TreeListExplorer__RegisteredOpenPath", $__TreeListExplorer__Data.iDoubleClickTime) EndIf EndIf EndIf If $bWasMarqueeStarted Then $bWasMarqueeStarted = False Case $NM_DBLCLK __TreeListExplorer__SetViewUpdating($hView, False, $__TreeListExplorer__Status_WaitOpenPath) __TreeListExplorer__ListViewOpenCurrentItem($iSystem, $hView) Local $iIndex = _GUICtrlListView_GetSelectionMark($hView) If $iIndex<>-1 Then __TreeListExplorer__HandleViewCallback($hView, "sCallbackDoubleClick", $iIndex) Case $LVN_COLUMNCLICK If $mView.mSorting.bEnabled Then Local $tNMListView = DllStructCreate($tagNMLISTVIEW, $ilParam) Local $iCol = DllStructGetData($tNMListView, "SubItem") Local $hHeader = _GUICtrlListView_GetHeader($hView) For $i = 0 To _GUICtrlHeader_GetItemCount($hHeader) - 1 If $i=$iCol Then ContinueLoop _GUICtrlHeader_SetItemFormat($hHeader, $i, BitAND(_GUICtrlHeader_GetItemFormat($hHeader, $i), BitNOT(BitOR($HDF_SORTDOWN, $HDF_SORTUP)))) Next $iFormat = _GUICtrlHeader_GetItemFormat($hHeader, $iCol) $__TreeListExplorer__Data["mViews"][$hView]["mSorting"]["iCol"] = $iCol If BitAND($iFormat, $HDF_SORTUP) Then ; ascending _GUICtrlHeader_SetItemFormat($hHeader, $iCol, BitOR(BitXOR($iFormat, $HDF_SORTUP), $HDF_SORTDOWN)) $__TreeListExplorer__Data["mViews"][$hView]["mSorting"]["iDir"] = 1 Else ; descending _GUICtrlHeader_SetItemFormat($hHeader, $iCol, BitOR(BitXOR($iFormat, $HDF_SORTDOWN), $HDF_SORTUP)) $__TreeListExplorer__Data["mViews"][$hView]["mSorting"]["iDir"] = 0 EndIf __TreeListExplorer__UpdateView($hView, True) EndIf Case $LVN_MARQUEEBEGIN $bWasMarqueeStarted = True EndSwitch EndSwitch ExitLoop Next EndIf If MapExists($__TreeListExplorer__Data.mGuis, $hWnd) Then Return _WinAPI_CallWindowProc($__TreeListExplorer__Data.mGuis[$hWnd].hPrevProc, $hWnd, $iMsg, $iwParam, $ilParam) EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__RegisteredOpenPath ; Description ...: Called with AdlibRegister to delay selecting the path on a single mouse click, to check if it is a double click first. ; Syntax ........: __TreeListExplorer__RegisteredOpenPath() ; Parameters ....: ; Return values .: None ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__RegisteredOpenPath() AdlibUnRegister("__TreeListExplorer__RegisteredOpenPath") Local $arViews = MapKeys($__TreeListExplorer__Data.mOpenPathViews) For $i=0 to UBound($arViews)-1 Step 1 If __TreeListExplorer__IsViewUpdating($arViews[$i], $__TreeListExplorer__Status_WaitOpenPath) Then Local $mOpenPathData = $__TreeListExplorer__Data["mOpenPathViews"][$arViews[$i]] Local $hView = $mOpenPathData.hView Local $arSel[0] If $mOpenPathData.bMarquee Then $arSel = _GUICtrlListView_GetSelectedIndices(HWnd($hView), True) __TreeListExplorer__OpenPath($mOpenPathData.iSystem, $mOpenPathData.sFolder, $mOpenPathData.sSelect) __TreeListExplorer__SetViewUpdating($hView, False, $__TreeListExplorer__Status_WaitOpenPath) If $mOpenPathData.bWasClick Then __TreeListExplorer__HandleViewCallback($hView, "sCallbackClick", $mOpenPathData.iIndex) For $j=1 To UBound($arSel)-1 _GUICtrlListView_SetItemSelected($hView, $arSel[$j], True) Next EndIf MapRemove($__TreeListExplorer__Data.mOpenPathViews, $arViews[$i]) Next EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__ListViewOpenCurrentItem ; Description ...: Get the selected item in the listview and open the folder (go back if it is ".."). Files are ignored. ; Syntax ........: __TreeListExplorer__ListViewOpenCurrentItem($iSystem, $hView) ; Parameters ....: $iSystem - an integer value. ; $hView - a handle value. ; Return values .: None ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__ListViewOpenCurrentItem($iSystem, $hView) Local $mView = $__TreeListExplorer__Data.mViews[$hView] If $mView.bNavigation Then Local $iIndex = _GUICtrlListView_GetSelectionMark($hView) If $iIndex=0 And _GUICtrlListView_GetItemText($hView, $iIndex, $mView.iPathIndex) = ".." Then Local $sPath = __TreeListExplorer__GetCurrentPath($iSystem) Local $arPath = __TreeListExplorer__GetPathAndLast($sPath) __TreeListExplorer__OpenPath($iSystem, $arPath[0]) ElseIf $iIndex<>-1 Then Local $sPath = __TreeListExplorer__GetCurrentPath($iSystem) & _GUICtrlListView_GetItemText($hView, $iIndex, $mView.iPathIndex) __TreeListExplorer__OpenPath($iSystem, $sPath) EndIf EndIf EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__HandleViewCallback ; Description ...:Handle callbacks attached to a view ; Syntax ........: __TreeListExplorer__HandleViewCallback($hView, $sFunc[, $param1 = Default[, $param2 = Default[, ; $param3 = Default[, $param4 = Default[, $param5 = Default[, $param6 = Default[, $param7 = Default]]]]]]]) ; Parameters ....: $hView - the view handle. ; $sCallbackName - the name of the function variable in the $mView map. ; $sVarName - the variable name given to __TreeListExplorer_CreateSystem. ; $param1 - [optional] additional parameter to pass to the callback. Default is None. ; $param2 - [optional] additional parameter to pass to the callback. Default is None. ; $param3 - [optional] additional parameter to pass to the callback. Default is None. ; $param4 - [optional] additional parameter to pass to the callback. Default is None. ; $param5 - [optional] additional parameter to pass to the callback. Default is None. ; $param6 - [optional] additional parameter to pass to the callback. Default is None. ; $param7 - [optional] additional parameter to pass to the callback. Default is None. ; Return values .: The return value of the callback function or 0 if the call fails ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__HandleViewCallback($hView, $sCallbackName, $param1=Default, $param2=Default, $param3=Default, $param4=Default, $param5=Default, $param6=Default, $param7=Default) Local $mView = $__TreeListExplorer__Data.mViews[$hView] If $mView[$sCallbackName]<>Default Then Local $iSystem = $mView.iSystem Local $arParams[7+@NumParams-2] $arParams[0] = "CallArgArray" $arParams[1] = $iSystem $arParams[2] = $hView $arParams[3] = $sCallbackName $arParams[4] = __TreeListExplorer__GetCurrentRoot($iSystem) $arParams[5] = __TreeListExplorer__GetCurrentPath($iSystem) $arParams[6] = __TreeListExplorer__GetSelected($iSystem) For $i=1 To @NumParams-2 Step 1 $arParams[6+$i] = Eval("param"&$i) Next Return Call("__TreeListExplorer__HandleCallback", $arParams) EndIf Return 0 EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__HandleSystemCallback ; Description ...: Handle callbacks attached to a TLE system ; Syntax ........: __TreeListExplorer__HandleSystemCallback($iSystem, $sFunc[, $param1 = Default[, $param2 = Default[, ; $param3 = Default[, $param4 = Default[, $param5 = Default[, $param6 = Default[, $param7 = Default]]]]]]]) ; Parameters ....: $iSystem - the TLE system ID. ; $sFunc - the name of the function variable in the $mSystem map. ; $sVarName - the variable name given to __TreeListExplorer_CreateSystem. ; $param1 - [optional] additional parameter to pass to the callback. Default is None. ; $param2 - [optional] additional parameter to pass to the callback. Default is None. ; $param3 - [optional] additional parameter to pass to the callback. Default is None. ; $param4 - [optional] additional parameter to pass to the callback. Default is None. ; $param5 - [optional] additional parameter to pass to the callback. Default is None. ; $param6 - [optional] additional parameter to pass to the callback. Default is None. ; $param7 - [optional] additional parameter to pass to the callback. Default is None. ; Return values .: The return value of the callback function or 0 if the call fails ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__HandleSystemCallback($iSystem, $sCallbackName, $param1=Default, $param2=Default, $param3=Default, $param4=Default, $param5=Default, $param6=Default, $param7=Default) Local $mSystem = $__TreeListExplorer__Data.mSystems[$iSystem] If $mSystem[$sCallbackName]<>Default Then Local $arParams = ["CallArgArray", $iSystem, Default, $sCallbackName, __TreeListExplorer__GetCurrentRoot($iSystem), _ __TreeListExplorer__GetCurrentPath($iSystem), __TreeListExplorer__GetSelected($iSystem)] Local $iNumParams = @NumParams-2, $iParamStart = 1 If $sCallbackName="sCallbackSelect" And @NumParams>2 Then Local $arPath = __TreeListExplorer__GetPathAndLast(__TreeListExplorer__GetCurrentPath($iSystem) & __TreeListExplorer__GetSelected($iSystem)) $arParams[4] = $arPath[0] $arParams[5] = $arPath[1] $iNumParams -= 1 $iParamStart = 2 EndIf If $sCallbackName="sCallbackSelect" Then If $mSystem.sSelected <> $mSystem.sSelectedOld Then $__TreeListExplorer__Data["mSystems"][$iSystem]["sSelectedOld"] = $mSystem.sSelected Else return 0 EndIf EndIf Local $iIndexStart = UBound($arParams) ReDim $arParams[UBound($arParams)+$iNumParams] For $i=$iParamStart To $iNumParams Step 1 $arParams[$iIndexStart] = Eval("param"&$i) $iIndexStart += 1 Next Return Call("__TreeListExplorer__HandleCallback", $arParams) EndIf Return 0 EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__HandleCallback ; Description ...: Handle callbacks ; Syntax ........: __TreeListExplorer__HandleCallback([$iSystem = Default[, $hView = Default[, $sCallbackName = ""[, ; $param1 = Default[, $param2 = Default[, $param3 = Default[, $param4 = Default[, $param5 = Default[, ; $param6 = Default[, $param7 = Default]]]]]]]]]]) ; Parameters ....: $iSystem - [optional] the system id. If Default, $hView must be set to get the system (view callbacks). ; $hView - [optional] the view handle. If Default, $iSystem must be set (system callbacks). ; $sCallbackName - [optional] the key to find the callback in $mSystem or $mView. ; $param1 - [optional] additional parameter to pass to the callback. Default is None. ; $param2 - [optional] additional parameter to pass to the callback. Default is None. ; $param3 - [optional] additional parameter to pass to the callback. Default is None. ; $param4 - [optional] additional parameter to pass to the callback. Default is None. ; $param5 - [optional] additional parameter to pass to the callback. Default is None. ; $param6 - [optional] additional parameter to pass to the callback. Default is None. ; $param7 - [optional] additional parameter to pass to the callback. Default is None. ; Return values .: The return value of the callback function or 0 if the call fails ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__HandleCallback($iSystem = Default, $hView = Default, $sCallbackName = "", $param1=Default, $param2=Default, $param3=Default, $param4=Default, $param5=Default, $param6=Default, $param7=Default) Local $sCallbackFunction, $iLineNumber If $hView<>Default Then Local $mView = $__TreeListExplorer__Data.mViews[$hView] If $iSystem=Default Then $iSystem = $mView.iSystem $sCallbackFunction = $mView[$sCallbackName] $iLineNumber = $mView.iLineNumber ElseIf $iSystem<>Default Then Local $mSystem = $__TreeListExplorer__Data.mSystems[$iSystem] $sCallbackFunction = $mSystem[$sCallbackName] $iLineNumber = $mSystem.iLineNumber EndIf If $sCallbackFunction<>Default Then Local $bHasView = $hView<>Default Local $arParams[@NumParams-1+($bHasView?1:0)], $iStart = 1+($bHasView?1:0) $arParams[0] = "CallArgArray" $arParams[1] = __TreeListExplorer__GetHandleFromSystemID($iSystem) If $bHasView Then $arParams[2] = $hView For $i=1 To @NumParams-3 Step 1 $arParams[$iStart+$i] = Eval("param"&$i) Next Local $result = Call($sCallbackFunction, $arParams) If @error = 0xDEAD And @extended = 0xBEEF Then If $hView<>Default Then __TreeListExplorer__ConsoleWriteCallbackError($sCallbackFunction, $sCallbackName, $mSystem.iLineNumber, "__TreeListExplorer_AddView") Else __TreeListExplorer__ConsoleWriteCallbackError($sCallbackFunction, $sCallbackName, $mSystem.iLineNumber, "__TreeListExplorer_CreateSystem") EndIf Else Return $result EndIf EndIf Return 0 EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__GetPathAndLast ; Description ...: Split the given path in the parent folder and the last file/folder part ; Syntax ........: __TreeListExplorer__GetPathAndLast($iSystem, $sPath) ; Parameters ....: $sPath - the path as string. ; Return values .: Array with $ar[0] = First part and $ar[1] = last folder/file ; Author ........: Kanashius ; Modified ......: ; Remarks .......: May fail, if the RegExp could not parse the path to split it. Then it returns ["", ""]. ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__GetPathAndLast($sPath) Local $arFolder = StringRegExp($sPath, "^(.*?\\?)([^\\]*?)\\?$", 3) ; split path and last file/folder If @error Or UBound($arFolder)<>2 Then Local $arResult = ["", ""] Return $arResult EndIf Return $arFolder EndFunc ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __TreeListExplorer__ConsoleWriteCallbackError ; Description ...: Write an error to the console, providing information about a wrong callback function ; Syntax ........: __TreeListExplorer__ConsoleWriteCallbackError($sFunc, $sVarName, $iLineNumber[, $sLineFunc = "__TreeListExplorer_AddView"]) ; Parameters ....: $sFunc - the function that should be called. ; $sCallbackName - the parameter name, where the function was provided to the UDF. ; $iLineNumber - the line number, where the function was provided to the UDF. ; $sLineFunc - the function name, of the function, where the callback function was provided ; to the UDF. ; Return values .: None ; Author ........: Kanashius ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __TreeListExplorer__ConsoleWriteCallbackError($sFunc, $sCallbackName, $iLineNumber, $sLineFunc) ConsoleWrite('Error calling callback function "'&$sFunc&'" provided as $'&$sCallbackName&' to "'&$sLineFunc&'" in Line: '&$iLineNumber& _ ". The function probably has the wrong number of parameters."&@crlf) EndFunc