Sign in to follow this  
Followers 0
IanN1990

[Solved] A better way to load information

9 posts in this topic

#1 ·  Posted (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.

MutiContextMenu("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 by IanN1990

Share this post


Link to post
Share on other sites



Your example doesn't work. That means we have to fix it before we can think about helping you.


RAID Calculator | Software Installer

The truth has been suppressed since the dawn of time.

Share this post


Link to post
Share on other sites

#3 ·  Posted (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 by abberration

RAID Calculator | Software Installer

The truth has been suppressed since the dawn of time.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

_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 Gude
How 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

Share this post


Link to post
Share on other sites

_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.

Share this post


Link to post
Share on other sites

Sorry then. I didn't checked it, just my thought.

It's ok, I had to check it myself before I posted that. :D

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 Gude
How 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

Share this post


Link to post
Share on other sites

@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.

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Though i had to stop for today as its 3am i figured i would post what i had at the moment.

#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

#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 by IanN1990

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0