Jump to content

[Solved] A better way to load information


Recommended Posts

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
Link to comment
Share on other sites

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
Link to comment
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

Link to comment
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

Link to comment
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.

Link to comment
Share on other sites

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
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...