jcpetu 4 Posted November 24, 2020 (edited) Hi people, I'm developing a file browser and I found an erratic behavior of TreeView, it some times brings data OK and sometimes repeats all directory structure. I don't get to see what I'm doing wrong. I'll appreciate any help. expandcollapse popup#include <File.au3> #include <GUIConstantsEx.au3> #include <GUITreeView.au3> #include <GuiListView.au3> #include <WindowsConstants.au3> ;---------------------------------------------------------------------------------------------------------------------- Opt("GUIOnEventMode", 1) #Region Variables ----------------------------------------------------------------------------------------------------- Global $times Global $GuiFileExplorer, $TVFileExplorer, $BChangeProperties, $LVBrowseItems, $drives Global $DeskW = 700, $DeskH = 700, $TVLVHeigth = 550 Global $TVImage = _GUIImageList_Create(16, 16, 5, 2) _GUIImageList_AddIcon($TVImage, @SystemDir & "\shell32.dll", 3) ;--Folder _GUIImageList_AddIcon($TVImage, @SystemDir & "\shell32.dll", 4) ;--Folder Open _GUIImageList_AddIcon($TVImage, @SystemDir & "\shell32.dll", 181) ;-Cdr _GUIImageList_AddIcon($TVImage, @SystemDir & "\shell32.dll", 8) ;--Fixed _GUIImageList_AddIcon($TVImage, @SystemDir & "\shell32.dll", 7) ;--Removable _GUIImageList_AddIcon($TVImage, @SystemDir & "\shell32.dll", 9) ;--Network _GUIImageList_AddIcon($TVImage, @SystemDir & "\shell32.dll", 11) ;-CDRom _GUIImageList_AddIcon($TVImage, @SystemDir & "\shell32.dll", 109) ;No Symbol for Burner #EndRegion Variables ----------------------------------------------------------------------------------------------------- $GuiFileExplorer = GUICreate('File Browser OM - v1.0', $DeskW, $DeskH, -1, -1, $WS_SIZEBOX + $WS_SYSMENU + BitOR($WS_MAXIMIZEBOX, $WS_MINIMIZEBOX)) GUISetOnEvent($GUI_EVENT_CLOSE, "CloseGUI") $TVFileExplorer = GUICtrlCreateTreeView(16, 40, ($DeskW / 2) - 26, $TVLVHeigth, BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_SHOWSELALWAYS, $WS_GROUP, $WS_TABSTOP, $WS_BORDER)) GUICtrlSetResizing(-1, 1) _GUICtrlTreeView_SetNormalImageList(-1, $TVImage) $LVBrowseItems = GUICtrlCreateListView('', ($DeskW / 2) + 10, 40, ($DeskW / 2) - 25, $TVLVHeigth, -1, BitOR($LVS_EX_CHECKBOXES, $LVS_EX_SUBITEMIMAGES, $LVS_EX_CHECKBOXES, $LVS_EX_FULLROWSELECT, $LVS_EX_HEADERDRAGDROP, $LVS_EX_DOUBLEBUFFER)) _GUICtrlListView_AddColumn(-1, 'Name', 110, 0) ;2=left aligned _GUICtrlListView_AddColumn(-1, 'Type', 110, 0) _GUICtrlListView_AddColumn(-1, 'Size', 110, 0) ColumnResize($GuiFileExplorer) $BChangeProperties = GUICtrlCreateButton('Change', 10, 630, 81, 21) GUICtrlSetResizing(-1, 1) GUICtrlSetOnEvent(-1, 'ChangeProperties') $drives = DriveGetDrive('ALL') If Not @error Then For $x = 1 To $drives[0] $icon = 0 If DriveGetType($drives[$x]) = 'Fixed' Then $icon = 3 If DriveGetType($drives[$x]) = 'Removable' Then $icon = 4 If DriveGetType($drives[$x]) = 'Network' Then $icon = 5 If DriveGetType($drives[$x]) = 'CDROM' Then $icon = 6 If DriveGetType($drives[$x]) = 'REMOVABLE' Then $icon = 6 If $icon = 0 Then $new = _GUICtrlTreeView_AddChild($TVFileExplorer, '', $drives[$x], 0, 1) Else $new = _GUICtrlTreeView_AddChild($TVFileExplorer, '', $drives[$x], $icon, $icon) EndIf Next EndIf GUISetState(@SW_SHOW, $GuiFileExplorer) GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY') PopulateTreeViewi($TVFileExplorer, $drives[1]) ;First drive=ROOT While Sleep(5) WEnd Func CloseGUI() GUIDelete() Exit EndFunc ;==>CloseGUI Func ChangeProperties() ConsoleWrite('Button pressed ' & @CR) EndFunc ;==>ChangeProperties Func ColumnResize(ByRef $hWnd, $type = 0) $winpos = WinGetPos($GuiFileExplorer) _GUICtrlListView_SetColumnWidth($hWnd, 0, $winpos[2] * .2375) _GUICtrlListView_SetColumnWidth($hWnd, 1, $winpos[2] * .1575) _GUICtrlListView_SetColumnWidth($hWnd, 2, $winpos[2] * .1) EndFunc ;==>ColumnResize Func PopulateTreeViewi($hWnd, $drive) ;Initial TreeView population $item = _GUICtrlTreeView_GetSelection($hWnd) ;Get the first item to populate folders If _GUICtrlTreeView_GetChildCount($hWnd, $item) <= 0 Then ;To ensure it wasn't populated _GUICtrlTreeView_BeginUpdate($hWnd) ;----------------------------------------------| $aFolders = _FileListToArray($drive, '*', 2) ;Search folders only For $i = 1 To UBound($aFolders) - 1 _GUICtrlTreeView_AddChild($hWnd, $item, $aFolders[$i], 0, 1) Next _GUICtrlTreeView_EndUpdate($hWnd) ;-------------------------------------------------| EndIf EndFunc ;==>PopulateTreeViewi Func PopulateTreeView($hWnd) $item = _GUICtrlTreeView_GetSelection($TVFileExplorer) If _GUICtrlTreeView_GetChildCount($TVFileExplorer, $item) <= 0 Then ;avoid load twice _GUICtrlTreeView_BeginUpdate($TVFileExplorer) ;----------------------------------------------| $txt = _GUICtrlTreeView_GetText($TVFileExplorer, $item) Do $parent = _GUICtrlTreeView_GetParentHandle($TVFileExplorer, $item) If $parent <> 0 Then $txt = _GUICtrlTreeView_GetText($TVFileExplorer, $parent) & "\" & $txt ;ConsoleWrite($txt&@CRLF) ; <----------- $item = $parent EndIf Until $parent = 0 ConsoleWrite('-----------------------'&@CRLF) ConsoleWrite($parent&@CRLF) ConsoleWrite($txt&@CRLF) ; <----------- ConsoleWrite($item&@CRLF) $item = _GUICtrlTreeView_GetSelection($TVFileExplorer) $aFolders = _FileListToArray($txt, "*", 2) If IsArray($aFolders) Then For $i = 1 To UBound($aFolders) - 1 _GUICtrlTreeView_AddChild($TVFileExplorer, $item, $aFolders[$i], 0, 1) Next EndIf _GUICtrlTreeView_EndUpdate($TVFileExplorer) ;-------------------------------------------------| EndIf EndFunc ;==>PopulateTreeView Func PopulateListView($hWnd) EndFunc Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR $HTVFileExplorer = ControlGetHandle($hWnd, '', $TVFileExplorer) ;TreeView handeler $HLVBrowseItems = ControlGetHandle($hWnd, '', $LVBrowseItems) ;ListView handeler $tNMHDR = DllStructCreate($tagNMHDR, $ilParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") If $iCode = -12 Or $iCode = -17 Then Return False Switch $hWndFrom Case $HLVBrowseItems ;ListView Switch $iCode Case $NM_DBLCLK ;double click on ListView #cs If $item[0] <> 0 Then $filefolder = _GUICtrlListView_GetSelectedIndices($LVBrowseItems, True) If _GUICtrlListView_GetItemText($LVBrowseItems, $filefolder[1], 1) = "Folder" Then $idx = _GUICtrlTreeView_GetSelection($TVFileExplorer) $item = StringTrimLeft($item[1], StringInStr($item[1], "\", 0, -1)) $found = _GUICtrlTreeView_FindItem($TVFileExplorer, $item, False, $idx) _GUICtrlTreeView_SelectItem($TVFileExplorer, $found) PopulateTreeView($TVFileExplorer) PopulateListView($TVFileExplorer) Else Run(@ComSpec & " /c " & Chr(34) & $item[1] & Chr(34), "", @SW_HIDE) Sleep(800) EndIf EndIf #ce Return True EndSwitch Case $HTVFileExplorer ;TreeView Switch $iCode Case -451 PopulateTreeView($TVFileExplorer) ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<------------ ;PopulateListView($TVFileExplorer) Return True EndSwitch EndSwitch EndFunc ;==>WM_NOTIFY The first printout shows the erratic behavior and the second is after I stop the script and run it again without changing anything. Edited November 24, 2020 by jcpetu Add info. Share this post Link to post Share on other sites
Nine 993 Posted November 24, 2020 Unable to replicate your issue... Not much of a signature but working on it... Spoiler Block all input without UAC Save/Retrieve Images to/from Text Tool to search content in au3 files Date Range Picker Sudoku Game 2020 Overlapped Named Pipe IPC x64 Bitwise Operations Multi-keyboards HotKeySet Fast and simple WCD IPC GIF Animation (cached) Share this post Link to post Share on other sites
jcpetu 4 Posted November 24, 2020 Hi Nine, thanks for trying anyway. Yes, it's strange, it happens randomly and I don't have any idea why. I got last Autoit & SciTe versions and Win 8.11, but I don't get any connection with this behavior. Share this post Link to post Share on other sites
water 2,387 Posted November 24, 2020 Works fine on Windows 10 and AutoIt 3.3.14.5. My UDFs and Tutorials: Spoiler UDFs:Active Directory (NEW 2020-10-10 - Version 1.5.2.1) - Download - General Help & Support - Example Scripts - WikiOutlookEX (NEW 2020-12-15 - Version 1.6.3.1) - Download - General Help & Support - Example Scripts - WikiOutlookEX_GUI (2020-06-27 - Version 1.3.2.0) - DownloadOutlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - WikiExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example ScriptsPowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & SupportExcel - Example Scripts - WikiWord - WikiTask Scheduler (2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - WikiTutorials:ADO - Wiki, WebDriver - Wiki Share this post Link to post Share on other sites
LarsJ 1,074 Posted November 24, 2020 The techniques that you demonstrate in the code in the first post only work for folders and files that are actually stored on disk. Many of the folders and files especially near the top of the C drive are virtual folders and files that are not stored on disk. These virtual folders and files are identified through PIDLs. You can find information about the concepts in Common Explorer Concepts. The information in the link appears to be about Windows XP. However, in modern file systems like in Windows 10, PIDLs are not used to traverse a file system. Here you use COM interfaces. In AutoIt, COM interfaces are implemented through the ObjCreateInterface() function. There are two essential interfaces for traversing a file system. One is INameSpaceTreeControl used to implement the treeview on the left side of File/Windows Explorer. The other is IExplorerBrowser used to implement the listview on the right side of File/Windows Explorer. File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsControl related: Hot-Track Enabled Toolbar Menu, Simulating a modeless Choose Color Dialog, Colors and fonts in TreeViewsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Share this post Link to post Share on other sites
jcpetu 4 Posted November 25, 2020 (edited) Hi LarsJ, very interesting info, unfortunately I don't know how to implement it in Autoit. Would you mind to provide me an example for a File/Windows Explorer please? My idea was to create an explorer to been able to find & select a file, and view or change file properties. Edited November 25, 2020 by jcpetu Add info. Share this post Link to post Share on other sites
LarsJ 1,074 Posted November 25, 2020 (edited) You can find a File/Windows Explorer implementation based on IExplorerBrowser in this post. It's the Toolbar example in the 7z-file. The code is from March 2015 and is Windows 7 code. I think the code can run as it is on Windows 10. You can see several of these virtual folders in the treeview on the left side of the image. The 7z-file below contains treeview code based on INameSpaceTreeControl. The code is from the last day of July 2016 and is probably made on a rainy day during the summer holidays. It's an absolute minimum implementation. I think the code can run as it is on Windows 10. This is an image of the GUI: In addition to problems accessing some of the folders, the huge disks used now can become a problem. These disks can contain a very large number of folders and files. Sooner or later you'll run into performance issues when in pure AutoIt code you have to fill in a treeview and a listview with all these folders and files. Again, the solution is to use code implemented in Microsoft DLL-files such as these COM interfaces. If you can limit the number of folders and files e.g. on the basis of a search or the like, it's certainly possible to implement a GUI in pure AutoIt code. But you can still easily run into a number of problems. Getting the right icons is not always easy. Implementing a proper right-click menu to set file properties is not entirely trivial. Especially not if you have multiple selections enabled in the listview. Again, the solution is to implement the functionality through Microsoft code in a DLL-file. LeftPane.7z Edited November 25, 2020 by LarsJ 1 jcpetu reacted to this File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsControl related: Hot-Track Enabled Toolbar Menu, Simulating a modeless Choose Color Dialog, Colors and fonts in TreeViewsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Share this post Link to post Share on other sites
Melba23 3,456 Posted November 25, 2020 jcpetu, If you want to see how I went about producing an Explorer-like TreeView then take a look at my ChooseFileFolder UDF (the link is in my sig). As LarsJ points out, pure AutoIt code is pretty slow and so the UDF only expands branches when needed to reduce the overhead. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Share this post Link to post Share on other sites
jcpetu 4 Posted November 25, 2020 LarsJ, thanks for the code I'll study it. Melba23, thanks a lot I'll also study it and see what I can pick of both examples. And yes, I noticed TreView & ListView population are to slow with large folders, as windows for instance, and it hangs the program because WM_NOTIFY fires both populations and can't wait for so long. Thanks again. Share this post Link to post Share on other sites