WildByDesign Posted January 22 Posted January 22 I have an issue in Files Au3 that might benefit from an added function to the UDF. Whenever a user navigates to a new directory, it runs an Adlib function to get a total count of items in the ListView with _GUICtrlListView_GetItemCount. Then that total count of items (files and folders) gets updated on the statusbar. This works good most of the time. However, some directories have more contents and are therefore slower to load and the Adlib function gets the wrong item count or no count at all. The problem, from outside of the UDF, I don't know how to determine when the ListView is done updating the items. I wonder if something like this might be better done within the UDF. One of the two possibilities would be good: The UDF gives some indication of when the ListView is done updating, by some query function This way, I know it's done and can run my function to get an accurate item count Or The UDF keeps its own ListView item count that is cleared at BeginUpdate and updated count at EndUpdate This way, I can query the UDF directly for ListView item count If count is 0 or Null, I know that ListView item update is still in progress (or empty directory) I suppose the return would need to be unique (maybe not 0) if still in progress Not necessary, but if you wanted to take it a step further: have a directory count, file count and total count to query with a function.
Kanashius Posted January 22 Author Posted January 22 3 hours ago, WildByDesign said: The UDF gives some indication of when the ListView is done updating, by some query function You mean something like the existing $__TreeListExplorer_Callback_Loading ? This provides True, when the Tree-/ListView is filled and False, when it is done. WildByDesign 1 My Website: Kanashius Webside (Some of my Programs you can find there)
WildByDesign Posted January 22 Posted January 22 37 minutes ago, Kanashius said: $__TreeListExplorer_Callback_Loading That is perfect. You are always thinking so far ahead which is awesome. This existing callback should do the job wonderfully. Thanks. Kanashius 1
Kanashius Posted January 25 Author Posted January 25 Hey there, a new version is out. Now with support for ComboBox/ComboBoxEx. Every view can get its own icon size now: __TreeListExplorer_SetViewIconSize There is now a __TreeListExplorer_FileGetIconBitmap function to allow the icon to be retrieved. It is possible to get the icons for a provided path with a customizable icon size. If there are a lot of repeating calls with the same path/extension to this function, consider adding your own cache for better performance. Have fun with v2.13 WildByDesign 1 My Website: Kanashius Webside (Some of my Programs you can find there)
WildByDesign Posted January 25 Posted January 25 (edited) 1 hour ago, Kanashius said: Have fun with v2.13 I've only just started to play around with the updated Examples, but this is super impressive! EDIT: 1 hour ago, Kanashius said: Now with support for ComboBox/ComboBoxEx. I suppose this opens the door to the possibility of switching the path edit box into a ComboBox with the combination of using the History.au3 UDF to show previously visited directories in the combo? Edited January 25 by WildByDesign
WildByDesign Posted January 27 Posted January 27 (edited) @Kanashius I have had success getting tooltips to load the icon obtained from the treeview and listview imagelists. However, I have spent about an hour this morning trying to get the icons directly from the updated __TreeListExplorer_FileGetIconBitmap but I have had no luck so far. I've tried about a dozen different things but I don't understand it very well. I will share a small example that I am using to try to get it working. expandcollapse popup#include <GUIConstantsEx.au3> #include <GuiToolTip.au3> #include "TreeListExplorer.au3" Example() Func Example() ; start TreeListExplorer __TreeListExplorer_StartUp($__TreeListExplorer_Lang_EN) ; attempt to get icon from Notepad Local $sPath = "C:\Windows\System32\notepad.exe" ;Local $hIcon = __TreeListExplorer_FileGetIconBitmap($sPath, 32) Local $hBitmap = __TreeListExplorer_FileGetIconBitmap($sPath, 32) Local $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap, 0x00000000) _GDIPlus_BitmapDispose($hBitmap) ;Local $hIcon = _GDIPlus_HICONCreateFromBitmap($hBitmap) ; Create a GUI with various controls. Local $g_hGUI = GUICreate("Example", 400, 400) $hToolTip3 = _GUIToolTip_Create(0) _GUIToolTip_AddTool($hToolTip3, $g_hGUI, " ", $g_hGUI) _GUIToolTip_UpdateTipText($hToolTip3, $g_hGUI, $g_hGUI, "Press Esc to Close") ;_GUIToolTip_SetTitle($hToolTip3, 'Custom Icon Example', $TTI_INFO_LARGE) _GUIToolTip_SetTitle($hToolTip3, 'Custom Icon Example', $hHBitmap) _GUIToolTip_TrackActivate($hToolTip3, True, $g_hGUI, $g_hGUI) ; Display the GUI. GUISetState(@SW_SHOW, $g_hGUI) ; Loop until the user exits. While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch ; track position of tooltip Local $aPosTool3 = MouseGetPos() _GUIToolTip_TrackPosition($hToolTip3, $aPosTool3[0], $aPosTool3[1]) WEnd ; close TreeListExplorer __TreeListExplorer_Shutdown() _GUIToolTip_Destroy($hToolTip3) ; Delete the previous GUI and all controls. GUIDelete($g_hGUI) EndFunc ;==>Example In this example, I am just trying to get the icon from Notepad. However, aside from this example the path could really be anything in the file system. Edited January 27 by WildByDesign
SOLVE-SMART Posted January 27 Posted January 27 I also will have a look into it @WildByDesign. I just realized that function __TreeListExplorer_FileGetIconBitmap is only available in the newest UDF v2.13. So you also have to update "files-au3" later on, but I am sure you did this already. I'll get back to you when I have some information. Here or via Discord, etc. Best regards Sven WildByDesign 1 ==> AutoIt related: 🔗 Organization AutoIt Community, 🔗 GitHub, 🔗 Discord Server, 🔗 Cheat Sheet, 🔗 autoit-webdriver-boilerplate Spoiler 🌍 Au3Forums 🎲 AutoIt (en) Cheat Sheet 📊 AutoIt limits/defaults 💎 Code Katas: [...] (comming soon) 🎭 Collection of GitHub users with AutoIt projects 🐞 False-Positives 🔮 Me on GitHub 💬 Opinion about new forum sub category 📑 UDF wiki list ✂ VSCode-AutoItSnippets 📑 WebDriver FAQs 👨🏫 WebDriver Tutorial (coming soon)
SOLVE-SMART Posted January 27 Posted January 27 (edited) This way it worked for me: expandcollapse popup#include-once #include <GuiToolTip.au3> #include "../lib/TreeListExplorer.au3" ; Adjust this and use >= v2.13 of the UDF. Example() Func Example() __TreeListExplorer_StartUp($__TreeListExplorer_Lang_EN) ; Notepad icon Local $sPath = "C:\Windows\System32\notepad.exe" Local $hBitmap = __TreeListExplorer_FileGetIconBitmap($sPath, 32) Local $hIcon = _GDIPlus_HICONCreateFromBitmap($hBitmap) _GDIPlus_BitmapDispose($hBitmap) ; GUI Local $g_hGUI = GUICreate("Example", 400, 400) Local $hToolTip3 = _GUIToolTip_Create(0) _GUIToolTip_AddTool($hToolTip3, $g_hGUI, " ", $g_hGUI) _GUIToolTip_UpdateTipText($hToolTip3, $g_hGUI, $g_hGUI, "Press Esc to Close") _GUIToolTip_SetTitle($hToolTip3, 'Custom Icon Example', $hIcon) _GUIToolTip_TrackActivate($hToolTip3, True, $g_hGUI, $g_hGUI) GUISetState(@SW_SHOW, $g_hGUI) ; Event loop While True Switch GUIGetMsg() Case -3 ExitLoop EndSwitch ; Track position of tooltip Local $aPosTool3 = MouseGetPos() _GUIToolTip_TrackPosition($hToolTip3, $aPosTool3[0], $aPosTool3[1]) WEnd ; Dispose __TreeListExplorer_Shutdown() _GUIToolTip_Destroy($hToolTip3) _GDIPlus_ImageDispose($hIcon) GUIDelete($g_hGUI) EndFunc I cannot provide much explanation, because I am at work and have to continue. Best regards Sven FYI: @WildByDesign, @Kanashius Edited January 27 by SOLVE-SMART WildByDesign 1 ==> AutoIt related: 🔗 Organization AutoIt Community, 🔗 GitHub, 🔗 Discord Server, 🔗 Cheat Sheet, 🔗 autoit-webdriver-boilerplate Spoiler 🌍 Au3Forums 🎲 AutoIt (en) Cheat Sheet 📊 AutoIt limits/defaults 💎 Code Katas: [...] (comming soon) 🎭 Collection of GitHub users with AutoIt projects 🐞 False-Positives 🔮 Me on GitHub 💬 Opinion about new forum sub category 📑 UDF wiki list ✂ VSCode-AutoItSnippets 📑 WebDriver FAQs 👨🏫 WebDriver Tutorial (coming soon)
WildByDesign Posted January 27 Posted January 27 7 minutes ago, SOLVE-SMART said: I cannot provide much explanation, because I am at work and have to continue. Confirmed, that works perfectly. Thanks Sven. SOLVE-SMART 1
WildByDesign Posted February 9 Posted February 9 (edited) @Kanashius I am thinking about adding the TreeListExplorer version to the About dialog in Files Au3 so that we know what is under-the-hood in any given release and to give some extra credit to your UDF. But I am not sure what the best way for parsing the string is. ; Version .......: 2.13 I am not the best when it comes to manipulating strings. I suppose it would involve reading the UDF file and grabbing what comes after ; Version .......: I just want to ensure that whatever method is used to get the version is as future-proof as possible. EDIT: Now that I think about it, this may not work in a situation where it’s compiled to binary. Edited February 9 by WildByDesign
Kanashius Posted February 9 Author Posted February 9 (edited) 2 hours ago, WildByDesign said: I just want to ensure that whatever method is used to get the version is as future-proof as possible. I'am using the default for comments/librarys/... for AutoIt. So I wrote this script, which should work for up to 4 version numbers and a possible a/b/rc at the end for the alpha, beta and release candidate versions. expandcollapse popup#include <File.au3> ConsoleWrite(_VersionPrint(_UDFGetVersion("AutoItIPC\IPC.au3"))&@crlf) ConsoleWrite(_VersionPrint(_UDFGetVersion("AutoItTreeListExplorer\TreeListExplorer.au3"))&@crlf) Local $sAutoItIncludeFolder = StringLeft(@AutoItExe, StringInStr(@AutoItExe, "\", 0, -1)-1)&"\"&"Include" Local $arFiles = _FileListToArray($sAutoItIncludeFolder) For $i = 1 to UBound($arFiles)-1 Step 1 ConsoleWrite(_VersionPrint(_UDFGetVersion($sAutoItIncludeFolder&"\"&$arFiles[$i]))&" >> "&$arFiles[$i]&@crlf) Next Func _VersionToString($arVersion, $sSep = " ") If Not IsArray($arVersion) Or UBound($arVersion, 0)<2 Or UBound($arVersion, 1)<2 Then Return SetError(1, 1, "Version not parsed.") Local $sVersion = "" If $arVersion[0][0]>0 Then $sVersion &= "AutoIt Version: " $sVersion&=$arVersion[0][1]&" [" For $i=1 to $arVersion[0][0]-1 If $i>1 Then $sVersion &= ", " $sVersion &= $arVersion[0][1+$i] Next If $arVersion[0][0]>0 Then $sVersion&="]" If $arVersion[1][0]>0 Then $sVersion &= $sSep EndIf If $arVersion[1][0]>0 Then $sVersion &= "UDF Version: " $sVersion&=$arVersion[1][1]&" (" For $i=1 to $arVersion[1][0]-1 If $i>1 Then $sVersion &= ", " $sVersion &= $arVersion[1][1+$i] Next If $arVersion[1][0]>0 Then $sVersion&="]" EndIf If $sVersion = "" Then Return "Version unknown" Return $sVersion EndFunc Func _UDFGetVersion($sFile) Local $sCode = FileRead($sFile) If @error Then Return SetError(@error, @extended, 0) Local $arVersion = _GetVersion($sCode) If @error Then Return SetError(@error, @extended, -1) Return $arVersion EndFunc ; #FUNCTION# ==================================================================================================================== ; Name ..........: _GetVersion ; Description ...: Get the AutoIt Version as well as the UDF Version. ; Syntax ........: _GetVersion($sUdfCode) ; Parameters ....: $sUdfCode - the sourcecode of the udf ; Return values .: Array with version information. ; Author ........: Kanashius ; Modified ......: ; Remarks .......: @extended (1 - Only AutoIt Version found, 2 - Only UDF Version found, 3 - Both found) ; Resurns a 2D-Array with: ; [0][0] being the amount of version parts found for the AutoIt Version + 1 ; [0][1] If [0][0]>0 then this is the full autoit version as string ; [0][2] The first part of the autoit version (index 2-5 is a number) ; ... ; [0][6] The last part of the autoit version (last part is a/b/rc) ; [1][0] being the amount of version parts found for the UDF Version + 1 ; [1][1] If [1][0]>0 then this is the full udf version as string ; [1][2] The first part of the udf version (index 2-5 is a number) ; ... ; [1][6] The last part of the udf version (last part is a/b/rc) ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _GetVersion($sUdfCode) Local $iExtended = 0 Local $arAutoItVersion = StringRegExp($sUdfCode, "(?m)(?s)^;\s*#INDEX#\s*=*.*?;\s*AutoIt\s*Version\s*\.*:\s((\d+)(?:\.(\d+)(?:\.(\d+)(?:\.(\d+))?)?)?(a|b|rc)?)\s*$", 1) If Not @error Then $iExtended = 1 Local $arUDFVersion = StringRegExp($sUdfCode, "(?m)(?s)^;\s*#INDEX#\s*=*.*?;\s*Version\s*\.*:\s((\d+)(?:\.(\d+)(?:\.(\d+))?)?(a|b|rc)?)\s*$", 1) If Not @error Then $iExtended += 2 Local $iVerNumbers = UBound($arAutoItVersion) If UBound($arUDFVersion)>$iVerNumbers Then $iVerNumbers = UBound($arUDFVersion) Local $arResult[2][$iVerNumbers+1] $arResult[0][0] = UBound($arAutoItVersion) For $i=0 to UBound($arAutoItVersion)-1 Step 1 $arResult[0][$i+1] = $arAutoItVersion[$i] Next $arResult[1][0] = UBound($arUDFVersion) For $i=0 to UBound($arUDFVersion)-1 Step 1 $arResult[1][$i+1] = $arUDFVersion[$i] Next Return SetExtended($iExtended, $arResult) EndFunc This can detect AutoIt Version and Version and the following version numbers: 1 1.1 1.1.1 1.1.1.1 1.1.1.1a 1.1.1.1b 1.1.1.1rc with 1 being detected by \d+ => one or more numbers. Hope this helps you Edited February 9 by Kanashius WildByDesign 1 My Website: Kanashius Webside (Some of my Programs you can find there)
WildByDesign Posted February 12 Posted February 12 On 2/9/2026 at 11:19 AM, Kanashius said: Hope this helps you This script helps a lot. It works very well and I can see others benefiting from it too. I do have one problem though. When the script (in this case Files Au3) is compiled to binary, it can no longer obtain the UDF version to show in the About dialog. And I'm not sure how else to generate it other than manually each release. Do you know of any other way? For example, during compilation of the binary, maybe it can call that function and store the result in a variable or string. But I just don't know how I could achieve that. I could have it write it to a text file or something but that would be not good. There is probably something easy that I am missing and just can't think of it right now.
WildByDesign Posted February 12 Posted February 12 (edited) Feature Request: I was thinking about this the other day. By default, TreeListExplorer UDF shows all of the files and folders that are not normally shown in File Explorer that I believe are related to the "Hide protected operating system files" option. For example, showing the $RECYCLE.BIN folders on each drive, the Documents and Settings folder, System Volume Information, etc. "Hide protected operating system files" seems to be quite a bit different from the "Show hidden files, folders, and drives" option. I am not entirely sure what attributes are set to determine "Hide protected operating system files" or how File Explorer handles that internally. If it is possible to add such an option for TreeListExplorer UDF, in a way where you could enable/disable either of those settings, I think that would be an excellent feature to have. EDIT: Looks like we would just have to look for the "S" = SYSTEM attribute. Edited February 12 by WildByDesign
Kanashius Posted February 12 Author Posted February 12 (edited) 8 hours ago, WildByDesign said: If it is possible to add such an option for TreeListExplorer UDF, in a way where you could enable/disable either of those settings, I think that would be an excellent feature to have. I thought about that and then I remembered, that the filter callback exists, so I thought it is not really needed: __TreeListExplorer_SetCallback($hView, $__TreeListExplorer_Callback_Filter, "_filterListView") Func _filterListView($hSystem, $hView, $bIsFolder, $sPath, $sName, $sExt) Return Not StringInStr(FileGetAttrib($sPath&$sName&$sExt), "S") EndFunc (Check if $sPath&$sName&$sExt is the correct absolute path, I am not entirely sure and cannot test at the moment.) The Filter callback is checked AFTER $__TreeListExplorer_Callback_ListViewPaths. It is a little bit redundant with the new $__TreeListExplorer_Callback_ListViewPaths callback (because that can be used to remove entries as well), but I thought to leave it there, because it may be easier to use, if simple filtering without sorting is sufficient. 8 hours ago, WildByDesign said: Do you know of any other way? I published the functions as UDF: You can use the UDF to store the version in global const variables. The first time, they will be positioned at the top, but you can move them and if you run the script again, it will update them at their current location. So you need to run your script once, after changing a UDF file to a different version. It was the closest, I could think of and I hope this helps you Edited February 12 by Kanashius WildByDesign 1 My Website: Kanashius Webside (Some of my Programs you can find there)
WildByDesign Posted February 13 Posted February 13 2 hours ago, Kanashius said: (Check if $sPath&$sName&$sExt is the correct absolute path, I am not entirely sure and cannot test at the moment.) Yes, this does give the correct full path. 2 hours ago, Kanashius said: The Filter callback is checked AFTER $__TreeListExplorer_Callback_ListViewPaths. It is a little bit redundant with the new $__TreeListExplorer_Callback_ListViewPaths callback (because that can be used to remove entries as well), but I thought to leave it there, because it may be easier to use, if simple filtering without sorting is sufficient. The example function _filterListView that you shared works well. I created a similar callback function for the TreeView and it worked good. Thank you. 2 hours ago, Kanashius said: You can use the UDF to store the version in global const variables. The first time, they will be positioned at the top, but you can move them and if you run the script again, it will update them at their current location. So you need to run your script once, after changing a UDF file to a different version. It was the closest, I could think of and I hope this helps you This is fantastic. I haven't got a chance to test the new UDF yet but I will test it tonight. Kanashius 1
WildByDesign Posted February 13 Posted February 13 It seems that using the Filter Callback to filter out files/folders with the system attribute causes some random issues. Screenshot in spoiler: Spoiler It is especially reproducible in the System32 directory. It displays duplicates of those 4-digit language related folders. And, as seen in screenshot, sometimes display them as files instead of folders. And being random, it will show differently each time you open the System32 directory. System32 is the easiest place to repro it but it likely happens in other areas too.
Kanashius Posted February 13 Author Posted February 13 3 hours ago, WildByDesign said: It seems that using the Filter Callback to filter out files/folders with the system attribute causes some random issues. I looked into that and could not find a problem with the filter callback (see example file). The callback is also just one additional If, preventing the listview-entry from being added, so I think the problem you have cannot even come from that. I assume you are using the $__TreeListExplorer_Callback_ListViewPaths callback (for sorting,...). There you are really editing/changing the array, with which the data is added. I think the probability is high, that something is going wrong there (before the filter callback is even called). TreeListExplorer-Example-HiddenSystemFiles.au3 My Website: Kanashius Webside (Some of my Programs you can find there)
WildByDesign Posted February 13 Posted February 13 7 minutes ago, Kanashius said: I looked into that and could not find a problem with the filter callback (see example file). The callback is also just one additional If, preventing the listview-entry from being added, so I think the problem you have cannot even come from that. You are right. I just confirmed by disabling the Callback_Filter that I was testing. The issue still persisted. 7 minutes ago, Kanashius said: I assume you are using the $__TreeListExplorer_Callback_ListViewPaths callback (for sorting,...). There you are really editing/changing the array, with which the data is added. I think the probability is high, that something is going wrong there (before the filter callback is even called). I had already done my testing with both Callback_ListViewPaths and Callback_ListViewItemCreated disabled. The AddView is also set to the default options so that there is no additional processing going on. To my surprise, the issue still persists. With all default settings, that random issue (at least noticeable in System32) is still happening. I will have to dig into this some more. Kanashius 1
WildByDesign Posted February 13 Posted February 13 (edited) So far I have not been able to reproduce the phantom file/folder on TLE 2.12 at all. On 2.13, it seems to happen (randomly) even when I don’t have any callbacks or custom columns. All default views and so on. Sometimes it does not do it at all. Sometimes it does it many times. So completely random and I don’t even understand how folders are turning into files and showing duplicate entries and more. I will keep doing more testing to figure out what is causing it and let you know if I can make sense of it. EDIT: I figured out the issue. It seems to be only a visual glitch that only shows if I have the cursor hovering over the ListView while it is still populating a large directory such as System32. It does not show with your examples since they don't have the theme styles applied to them. I already have the Callback_Loading function for certain purposes. So I think what I can do to fix this (in Files Au3) is by disabling input to the ListView from the time that loading has started until loading is complete and then enable the input again. EDIT2: It ended up being an easy fix and worked perfectly. In the Callback_Loading function, I just had to do the following: If $bLoading Then _WinAPI_EnableWindow($g_hListview, False) Else _WinAPI_EnableWindow($g_hListview, True) EndIf What a weird problem. Thankfully it was only a visual glitch and with an easy fix. Edited February 13 by WildByDesign
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now