IanN1990 Posted July 2, 2012 Share Posted July 2, 2012 (edited) A month ago i spent my time making a context menu, one of its features is displaying all my files. Instead of hard-cording each folder/file into the autoitscript i came up with this code. expandcollapse popupMutiContextMenu("D:\Videos", $LvL2Videos, 3) Func MutiContextMenu($Directory, $LvL0ContextMenu, $Level) $LvL1FolderList = _FileListToArray($Directory,"*", 2);Level 1 Folder If $Level >= 1 then ;Level 1 Check If IsArray($LvL1FolderList) Then ;Level 1 Array For $1 = 1 to $LvL1FolderList[0] ;Level 1 For $LvL1ContextMenu = GUICtrlCreateMenu($LvL1FolderList[$1], $Lvl0ContextMenu) If $Level >= 2 then ;Level 2 Check $LvL2FolderList = _FileListToArray($Directory & "\" & $LvL1FolderList[$1],"*", 2);Level 2 Folder If IsArray($LvL2FolderList) Then ;Level 2 Array For $2 = 1 to $LvL2FolderList[0] ;Level 2 For $LvL2ContextMenu = GUICtrlCreateMenu($LvL2FolderList[$2], $LvL1ContextMenu) If $Level >= 3 then ;Level 3 Check $LvL3FolderList = _FileListToArray($Directory & "\" & $LvL1FolderList[$1] & "\" & $LvL2FolderList[$2],"*", 2);Level 3 Folders If IsArray($LvL3FolderList) Then ;Level 3 Array For $3 = 1 to $LvL3FolderList[0] ;Level 3 For $LvL3ContextMenu = GUICtrlCreateMenu($LvL3FolderList[$3], $LvL2ContextMenu) If $Level >= 4 then ;Level 4 Check $LvL4FolderList = _FileListToArray($Directory & "\" & $LvL1FolderList[$1] & "\" & $LvL2FolderList[$2] & "\" & $LvL3FolderList[$3],"*", 2);Level 4 Folders If IsArray($LvL4FolderList) Then ;Level 4 Array For $4 = 1 to $LvL4FolderList[0] ;Level 4 For $LvL4ContextMenu = GUICtrlCreateMenu($LvL4FolderList[$4], $LvL3ContextMenu) $LvL5FileList = _FileListToArray($Directory & "\" & $LvL1FolderList[$1] & "\" & $LvL2FolderList[$2] & "\" & $LvL3FolderList[$3] & "\" & $LvL4FolderList[$4] ,"*", 1);Level 5 Files If IsArray($LvL5FileList) Then For $E = 1 to $LvL5FileList[0] If Not(StringRight($LvL5FileList[$E], 4) = ".ini") Then GUICtrlCreateMenuItem($LvL5FileList[$E], $LvL4ContextMenu) Next EndIf Next ;Level 4 Next EndIf ;Level 4 Array EndIf ;Level 4 End Check $LvL4FileList = _FileListToArray($Directory & "\" & $LvL1FolderList[$1] & "\" & $LvL2FolderList[$2] & "\" & $LvL3FolderList[$3],"*", 1);Level 4 Files If IsArray($LvL4FileList) Then For $D = 1 to $LvL4FileList[0] If Not(StringRight($LvL4FileList[$D], 4) = ".ini") Then GUICtrlCreateMenuItem($LvL4FileList[$D], $LvL3ContextMenu) Next EndIf Next ;Level 3 Next EndIf ;Level 3 Array EndIf ;Level 3 End Check $LvL3FileList = _FileListToArray($Directory & "\" & $LvL1FolderList[$1] & "\" & $LvL2FolderList[$2],"*", 1);Level 3 Files If IsArray($LvL3FileList) Then For $C = 1 to $LvL3FileList[0] If Not(StringRight($LvL3FileList[$C], 4) = ".ini") Then GUICtrlCreateMenuItem($LvL3FileList[$C], $LvL2ContextMenu) Next EndIf Next ;Level 2 Next EndIf ;Level 2 End Array EndIf ;Level 2 End Check $LvL2FileList = _FileListToArray($Directory & "\" & $LvL1FolderList[$1],"*", 1);Level 2 Files If IsArray($LvL2FileList) Then For $B = 1 to $LvL2FileList[0] If Not(StringRight($LvL2FileList[$B], 4) = ".ini") Then GUICtrlCreateMenuItem($LvL2FileList[$B], $LvL1ContextMenu) Next EndIf Next ;Level 1 Next EndIf ;Level 1 End Array EndIf ;Level 2 End Check $LvL1FileList = _FileListToArray($Directory, "*", 1) ;Level 1 Files If IsArray($LvL1FileList) Then For $A = 1 to $LvL1FileList[0] If Not(StringRight($LvL1FileList[$A], 4) = ".ini") Then GUICtrlCreateMenuItem($LvL1FileList[$A], $LvL0ContextMenu) Next EndIf EndFunc Problem is, it runs very slow. About 600 mili seconds to complete "which though seams silly, when you add in the 0.300 mili seconsd for startup then a context menu starts to feel very unreasonsive when you rightclick and have to wait 1-2 seconds before anything appears". is there a better way of going about this ? I wish to load every folder and file "exluding system files *ie .ini*" into a context menu Edited September 8, 2012 by IanN1990 Link to comment Share on other sites More sharing options...
abberration Posted July 2, 2012 Share Posted July 2, 2012 Your example doesn't work. That means we have to fix it before we can think about helping you. Easy MP3 | Software Installer | Password Manager Link to comment Share on other sites More sharing options...
abberration Posted July 2, 2012 Share Posted July 2, 2012 (edited) Also, you may want to have a look at Melba23's RecFileListToArray.au3. Download his UDF here: #include <RecFileListToArray.au3> #include <array.au3> $videoFiles = _RecFileListToArray("D:Videos", "*.*", 0, 1, 0, 2, "*.ini", "") _ArrayDisplay($videoFiles) Edited July 2, 2012 by abberration Easy MP3 | Software Installer | Password Manager Link to comment Share on other sites More sharing options...
Zedna Posted July 2, 2012 Share Posted July 2, 2012 As about speed optimization: As far as I know there is done ReDim for EACH file inside _FileListToArray(). You can make modified your local copy of that function with optimization of ReDims, for example each ReDim do to double count. Resources UDF Â ResourcesEx UDF Â AutoIt Forum Search Link to comment Share on other sites More sharing options...
BrewManNH Posted July 2, 2012 Share Posted July 2, 2012 _FileListToArray doesn't use ReDim, it creates a string of all files in the folder, then it does a stringsplit on the string to get the array. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator Link to comment Share on other sites More sharing options...
Zedna Posted July 2, 2012 Share Posted July 2, 2012 _FileListToArray doesn't use ReDim, it creates a string of all files in the folder, then it does a stringsplit on the string to get the array.Sorry then. I didn't checked it, just my thought. Resources UDF Â ResourcesEx UDF Â AutoIt Forum Search Link to comment Share on other sites More sharing options...
BrewManNH Posted July 2, 2012 Share Posted July 2, 2012 Sorry then. I didn't checked it, just my thought.It's ok, I had to check it myself before I posted that. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator Link to comment Share on other sites More sharing options...
IanN1990 Posted July 2, 2012 Author Share Posted July 2, 2012 @Abberration The whole code from the context menu "and this function does work " but it seams just stripping it out and pasting does make it a non-functional example. I applogise for that. Looking at the UDF you posted, it does seam to do the trick "loading a array of over 2,000 items in 0.300 seconds which is almost instant so credits for Mebla for a powerful peice of coding". Now i just need a way to take this array information and break it down into Context menus and context menu items so it can be displayed. Link to comment Share on other sites More sharing options...
IanN1990 Posted July 3, 2012 Author Share Posted July 3, 2012 (edited) Though i had to stop for today as its 3am i figured i would post what i had at the moment. expandcollapse popup#NoTrayIcon #include 'WindowsConstants.au3' #include 'MenuConstants.au3' #include Local $GUIContextMenu = GUICreate("Context Menu", 1, 1, -5, -5, $WS_POPUP, $WS_EX_TOOLWINDOW) local $MainContextMenu = GUICtrlCreateContextMenu() local $ContextHandle = GUICtrlGetHandle($MainContextMenu) $videoFiles = _RecFileListToArray("D:Videos", "*.*", 0, 1, 2, 2, "*.ini", "") For $i = 1 to 100 if StringInStr($videoFiles[$i], "", 0, 5) Then $Level4 = GUICtrlCreateMenuItem($videoFiles[$i], $Level3) Elseif StringInStr($videoFiles[$i], "", 0, 4) Then $Level3 = GUICtrlCreateMenu($videoFiles[$i], $Level2) ElseIf StringInStr($videoFiles[$i], "", 0, 3) Then $Level2 = GUICtrlCreateMenu($videoFiles[$i], $Level1) ElseIf StringInStr($videoFiles[$i], "", 0, 2) Then $Level1 = GUICtrlCreateMenu($videoFiles[$i], $MainContextMenu) EndIf Next $ContextMenu = _GUICtrlMenu_TrackPopupMenu($ContextHandle, $GUIContextMenu, 0, 0, 1, 1, 2) $ContextMenuText = _GUICtrlMenu_GetItemText($ContextHandle, $ContextMenu, False) Func _GUICtrlMenu_TrackPopupMenu($hMenu, $hWnd, $iX = -1, $iY = -1, $iAlignX = 1, $iAlignY = 1, $iNotify = 0, $iButtons = 0) If $iX = -1 Then $iX = _WinAPI_GetMousePosX() If $iY = -1 Then $iY = _WinAPI_GetMousePosY() Local $iFlags = 0 Switch $iAlignX Case 1 $iFlags = BitOR($iFlags, $TPM_LEFTALIGN) Case 2 $iFlags = BitOR($iFlags, $TPM_RIGHTALIGN) Case Else $iFlags = BitOR($iFlags, $TPM_CENTERALIGN) EndSwitch Switch $iAlignY Case 1 $iFlags = BitOR($iFlags, $TPM_TOPALIGN) Case 2 $iFlags = BitOR($iFlags, $TPM_VCENTERALIGN) Case Else $iFlags = BitOR($iFlags, $TPM_BOTTOMALIGN) EndSwitch If BitAND($iNotify, 1) <> 0 Then $iFlags = BitOR($iFlags, $TPM_NONOTIFY) If BitAND($iNotify, 2) <> 0 Then $iFlags = BitOR($iFlags, $TPM_RETURNCMD) Switch $iButtons Case 1 $iFlags = BitOR($iFlags, $TPM_RIGHTBUTTON) Case Else $iFlags = BitOR($iFlags, $TPM_LEFTBUTTON) EndSwitch Local $aResult = DllCall("User32.dll", "bool", "TrackPopupMenu", "handle", $hMenu, "uint", $iFlags, "int", $iX, "int", $iY, "int", 0, "hwnd", $hWnd, "ptr", 0) If @error Then Return SetError(@error, @extended, 0) Return $aResult[0] EndFunc ;==>_GUICtrlMenu_TrackPopupMenu Func _GUICtrlMenu_GetItemText($hMenu, $iItem, $fByPos = True) Local $iByPos = 0 If $fByPos Then $iByPos = $MF_BYPOSITION Local $aResult = DllCall("User32.dll", "int", "GetMenuStringW", "handle", $hMenu, "uint", $iItem, "wstr", 0, "int", 4096, "uint", $iByPos) If @error Then Return SetError(@error, @extended, 0) Return SetExtended($aResult[0], $aResult[3]) EndFunc ;==>_GUICtrlMenu_GetItemText Loads up to 100 items, it seams half want and as of yet i donno how to make the folders / files display as folders > files rather then whole file names **Edit New code i wrote this morning expandcollapse popup#NoTrayIcon #include 'WindowsConstants.au3' #include 'MenuConstants.au3' #include <RecFileListToArray.au3> Local $GUIContextMenu = GUICreate("Context Menu", 1, 1, -5, -5, $WS_POPUP, $WS_EX_TOOLWINDOW) local $MainContextMenu = GUICtrlCreateContextMenu() local $ContextHandle = GUICtrlGetHandle($MainContextMenu) $videoFiles = _RecFileListToArray("D:Videos", "*.*", 0, 1, 2, 2, "*.ini", "") For $i = 1 to $videoFiles[0] if StringInStr($videoFiles[$i], "", 0, 5) Then $result = StringInStr($videoFiles[$i], "", 0, 5) if StringInStr($videoFiles[$i], ".", 0, 1) Then $Level4 = GUICtrlCreateMenuItem(StringTrimLeft($videoFiles[$i], $result), $Level3) Else $Level4 = GUICtrlCreateMenu(StringTrimLeft($videoFiles[$i], $result), $Level3) EndIf Elseif StringInStr($videoFiles[$i], "", 0, 4) Then $result = StringInStr($videoFiles[$i], "", 0, 4) If StringInStr($videoFiles[$i], ".", 0, 1) Then $Level3 = GUICtrlCreateMenuItem(StringTrimLeft($videoFiles[$i], $result), $Level2) Else $Level3 = GUICtrlCreateMenu(StringTrimLeft($videoFiles[$i], $result), $Level2) EndIf ElseIf StringInStr($videoFiles[$i], "", 0, 3) Then $result = StringInStr($videoFiles[$i], "", 0, 3) If StringInStr($videoFiles[$i], ".", 0, 1) Then $Level2 = GUICtrlCreateMenuItem(StringTrimLeft($videoFiles[$i], $result), $Level1) Else $Level2 = GUICtrlCreateMenu(StringTrimLeft($videoFiles[$i], $result), $Level1) EndIf ElseIf StringInStr($videoFiles[$i], "", 0, 2) Then $result = StringInStr($videoFiles[$i], "", 0, 2) If StringInStr($videoFiles[$i], ".", 0, 2) Then $Level1 = GUICtrlCreateMenuItem(StringTrimLeft($videoFiles[$i], $result), $MainContextMenu) Else $Level1 = GUICtrlCreateMenu(StringTrimLeft($videoFiles[$i], $result), $MainContextMenu) EndIf EndIf Next $ContextMenu = _GUICtrlMenu_TrackPopupMenu($ContextHandle, $GUIContextMenu, 0, 0, 1, 1, 2) $ContextMenuText = _GUICtrlMenu_GetItemText($ContextHandle, $ContextMenu, False) Func _GUICtrlMenu_TrackPopupMenu($hMenu, $hWnd, $iX = -1, $iY = -1, $iAlignX = 1, $iAlignY = 1, $iNotify = 0, $iButtons = 0) If $iX = -1 Then $iX = _WinAPI_GetMousePosX() If $iY = -1 Then $iY = _WinAPI_GetMousePosY() Local $iFlags = 0 Switch $iAlignX Case 1 $iFlags = BitOR($iFlags, $TPM_LEFTALIGN) Case 2 $iFlags = BitOR($iFlags, $TPM_RIGHTALIGN) Case Else $iFlags = BitOR($iFlags, $TPM_CENTERALIGN) EndSwitch Switch $iAlignY Case 1 $iFlags = BitOR($iFlags, $TPM_TOPALIGN) Case 2 $iFlags = BitOR($iFlags, $TPM_VCENTERALIGN) Case Else $iFlags = BitOR($iFlags, $TPM_BOTTOMALIGN) EndSwitch If BitAND($iNotify, 1) <> 0 Then $iFlags = BitOR($iFlags, $TPM_NONOTIFY) If BitAND($iNotify, 2) <> 0 Then $iFlags = BitOR($iFlags, $TPM_RETURNCMD) Switch $iButtons Case 1 $iFlags = BitOR($iFlags, $TPM_RIGHTBUTTON) Case Else $iFlags = BitOR($iFlags, $TPM_LEFTBUTTON) EndSwitch Local $aResult = DllCall("User32.dll", "bool", "TrackPopupMenu", "handle", $hMenu, "uint", $iFlags, "int", $iX, "int", $iY, "int", 0, "hwnd", $hWnd, "ptr", 0) If @error Then Return SetError(@error, @extended, 0) Return $aResult[0] EndFunc ;==>_GUICtrlMenu_TrackPopupMenu Func _GUICtrlMenu_GetItemText($hMenu, $iItem, $fByPos = True) Local $iByPos = 0 If $fByPos Then $iByPos = $MF_BYPOSITION Local $aResult = DllCall("User32.dll", "int", "GetMenuStringW", "handle", $hMenu, "uint", $iItem, "wstr", 0, "int", 4096, "uint", $iByPos) If @error Then Return SetError(@error, @extended, 0) Return SetExtended($aResult[0], $aResult[3]) EndFunc ;==>_GUICtrlMenu_GetItemText Edited July 3, 2012 by IanN1990 Link to comment Share on other sites More sharing options...
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