Jump to content

Automatic Create Menu in GUI


Recommended Posts

Hi all!!

My English is not good!, sorry everyone!

I have a structure folder shown below:

Posted Image

I want a function to automatic create this menu (see figure):

note: parameter is path of folder

Posted Image

how to create its?

helps me, please!!

Edited by dien44
Link to comment
Share on other sites

Here is a basic example, you can make it more performant:

$MAIN = GUICreate("Example")
$MENU = CreateMenuFromINI("Test.ini")
GUISetState(@SW_SHOW,$MAIN)

While True
    Switch GUIGetMsg()
        Case $MENU[1]
            TrayTip("MenuClick","1.1.1",1)
        Case $MENU[2]
            TrayTip("MenuClick","1.1.2",1)
        Case $MENU[3]
            TrayTip("MenuClick","1.2.1",1)
        Case $MENU[4]
            TrayTip("MenuClick","1.2.2",1)
        Case $MENU[5]
            TrayTip("MenuClick","1.3.1",1)
        Case $MENU[6]
            TrayTip("MenuClick","1.3.2",1)
        Case -3
            Exit
    EndSwitch
    Sleep(10)
WEnd

Func CreateMenuFromINI($INI)
    Local $CTRL[1]
    Local $SECTIONS = IniReadSectionNames($INI)
    For $MENU = 1 To $SECTIONS[0]
        Local $SECTION = IniReadSection($INI,$SECTIONS[$MENU])
        Local $MENU_CTRL = GUICtrlCreateMenu($SECTIONS[$MENU])
        For $ITEM = 1 To $SECTION[0][0]
            ReDim $CTRL[UBound($CTRL)+1]
            $CTRL[UBound($CTRL)-1] = GUICtrlCreateMenuItem($SECTION[$ITEM][1],$MENU_CTRL)
            $CTRL[0] = UBound($CTRL)-1
        Next
    Next
    Return $CTRL
EndFunc

Test.ini

[1.1]

Item1=1.1.1

Item2=1.1.2

[1.2]

Item1=1.2.1

Item2=1.2.2

[1.3]

Item1=1.3.1

Item2=1.3.2

When the words fail... music speaks.

Link to comment
Share on other sites

  • Moderators

dien44,

Welcome to the AutoIt forum. :)

You will need my RecFileListToArray UDF (look in my sig :P) and then you can do this:

#include <GUIConstantsEx.au3>
#include <RecFileListToArray.au3>

$aReturn = _RecFileListToArray(@DesktopDir & "\1", "*", 2, 1, 1)

$hGUI = GUICreate("Test", 500, 500)

$mLevel_0 = GUICtrlCreateMenu("1")

For $i = 1 To $aReturn[0]

    StringReplace($aReturn[$i], "\", "")
    $iLevel = @extended

    Switch $iLevel
        Case 0
            $mLevel_1 = GUICtrlCreateMenu($aReturn[$i], $mLevel_0)
        Case 1
            $sText = StringRegExpReplace($aReturn[$i], ".*\\(.*)", "$1")
            GUICtrlCreateMenuItem($sText, $mLevel_1)
    EndSwitch

Next

GUISetState()

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch

WEnd

Please ask if you have any questions. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png 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 columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Thanks Andreik, but, suppose, i have very much folders same level (EX: 1.1; 1.2;...;1.100; ....), when, in order to create menus are difficult.

;;-------------------------------------------;;

Thanks Melba23, UDF work nice!, but:

+ if i select $iReturnPath = 2 (full path), menu do not create

+ when i add folders other, menu do not create, too. EX: add folders: 1.1.1.1 and 1.1.1.2 in 1.1.1 folder --> 1.1.1.1 and 1.1.1.2 don't create in menu

+ Example, when i create menu complete, how to manage it ?

Sorry, because i understand a little.

THANKS ALL!!

Link to comment
Share on other sites

  • Moderators

dien44,

That was an interesting exercise: :P

#include <GUIConstantsEx.au3>
#include <RecFileListToArray.au3>

Global $aLevel[25]
Global $aItem[25][2] = [[0, 0]]

$sRoot = @DesktopDir ; You can put any path here to get the folder tree into the menu <<<<<<<<<<<<<<<<<<<<<<<<<<<<<

StringReplace($sRoot, "\", "")
$iBase = @extended

$aReturn = _RecFileListToArray($sRoot, "*", 2, 1, 1, 2)

$hGUI = GUICreate("Test", 500, 500)

$aLevel[0] = GUICtrlCreateMenu($sRoot)

For $i = 1 To $aReturn[0] - 1

    ; Examine current return
    StringReplace($aReturn[$i], "\", "")
    $iLevel = @extended - $iBase

    ; Look at next return
    StringReplace($aReturn[$i + 1], "\", "")
    $iNext_Level = @extended - $iBase

    ; Is current an item or a menu
    If $iLevel < $iNext_Level Then
        $aLevel[$iLevel] = GUICtrlCreateMenu($aReturn[$i], $aLevel[$iLevel - 1])
    Else
        $aItem[0][0] += 1
        If UBound($aItem) <= $aItem[0][0] Then ReDim $aItem[UBound($aItem) * 2][2]
        $aItem[$aItem[0][0]][0] = GUICtrlCreateMenuItem($aReturn[$i], $aLevel[$iLevel - 1])
        $aItem[$aItem[0][0]][1] = $aReturn[$i]
    EndIf

Next

; Final element must be an item
StringReplace($aReturn[$i], "\", "")
$iLevel = @extended - $iBase
$aItem[0][0] += 1
If UBound($aItem) <= $aItem[0][0] Then ReDim $aItem[UBound($aItem) * 2][2]
$aItem[$aItem[0][0]][0] = GUICtrlCreateMenuItem($aReturn[$i], $aLevel[$iLevel - 1])
$aItem[$aItem[0][0]][1] = $aReturn[$i]
ReDim $aItem[$aItem[0][0] + 1][2]

GUISetState()

While 1

    $iMsg = GUIGetMsg()
    Switch $iMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $aItem[1][0] To $aItem[$aItem[0][0]][0]
            For $i = 1 To $aItem[0][0]
                If $iMsg = $aItem[$i][0] Then
                    MsgBox(0, "Menu", "You selected Item " & $aItem[$i][1])
                    ExitLoop
                EndIf
            Next
    EndSwitch

WEnd

However, I do NOT recommend using menus in this way to select folders as you can ONLY select those folders at the end of a branch, which is a serious limitation. :)

I would suggest using FileSelectFolder or my ChooseFileFolder UDF instead as they offer a lot more flexibility by permitting the selection of any folder in the tree. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png 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 columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Thanks for helps me!.

That right!. but i feel confusing ( because my knowledge is not good. :)( ). but, i have writed some few functions ( through UDF RecFileListToArray your ). It can find file, folder and create menu. But, this happen problem below:

+ i can't determine when to end folder of path.

+ Other problems with ini file. i have a ini file. i used "IniReadSection" to read all key, but it don't return all key. content are 1147 line, but it return 323 line.

Melba23 read, repair and advice for me, please.

Posted Image

#include<RecFileListToArray.au3>
Opt("GUIOnEventMode",1)

$gui = GUICreate("menu", 100,100)
GUISetOnEvent( -3, "_exit")

$root = @DesktopDir & "\1"
$path_and_text = split_path( $root )
$menu_base = GUICtrlCreateMenu( $path_and_text[1])
IniWrite("data.ini", "section", $root & "\", $menu_base )

start( $root )

GUISetState(@SW_SHOW)

While 1
    Sleep(60)
WEnd

Func start( $root )
    $all_path = _RecFileListToArray( $root, "*", 0, 1, 1, 2 )
    For $i = 1 To $all_path[0]
        $path_finded = $all_path[$i]
        ;;
        $path_unsplit = $path_finded
        $path_text = split_path( $path_unsplit )
        ;;
        $path_splited = $path_text[0]
        $paren_id = get_id( $path_splited )
        ;;
        $text = $path_text[1]
        $new_id = create_menu( $path_unsplit, $text, $paren_id )
        ;;
        save_id( $path_finded, $new_id )
        ;;
    Next
EndFunc

Func split_path( $path_unsplit )
    Local $return[2]
    $split = StringInStr( $path_unsplit, "\" , 0,  -1 ) ; -1: tim tu ben phai tim qua
    $path_splited = StringLeft( $path_unsplit, $split )
    ;; kiem tra ky tu cuoi co phai la "\" hay khong, neu khong co thi them vao
    ;to check end character maybe "\". if end character's path is not "\", we add "\" to path.
    $kt = StringRight( $path_splited, 1 )
    If $kt <> "\" Then
        $path_splited_new = $path_splited & "\"
    Else
        $path_splited_new = $path_splited
    EndIf
    ;;
    $text_menu = StringRight( $path_unsplit, StringLen( $path_unsplit ) - $split )
    $return[0] = $path_splited_new
    $return[1] = $text_menu
    Return $return
EndFunc

Func get_id( $path_splited )
    $old_id = IniRead( "data.ini", "section", $path_splited, "ktt")
    Return $old_id
EndFunc

Func create_menu( $path_unsplit, $text_menu, $paren_id )
    ;kiem tra xem duong dan "path_unsplit" nay la cua file hay folder.
    ;neu la file thi tao menu item, con folder thi tao menu ( nhung doi voi nhung folder cuoi cung thi cung tao menuitem, nhung hien tai chua biet cach )
    ;test path to know file or folder

;~  I CAN'T DETERMINE END FOLDER TO USE GUICtrlCreateMenuItem
    $test1 = FileGetAttrib( $path_unsplit )
    $test2 = FileGetSize ( $path_unsplit )
    If $test1 <> "D" And $test2 <> 0 Then ; tuc la 1 file (sure! path is a file)
        $new_id = GUICtrlCreateMenuItem( $text_menu, $paren_id ) ; ONLY FILE
                                                                ;ABOUT FOLDER ??
    Else
        $new_id = GUICtrlCreateMenu( $text_menu, $paren_id )
    EndIf
    Return $new_id
EndFunc

Func save_id( $path_unsplit, $new_id )
    ;; kiem tra neu cuoi path khong co "\" thi them vao
    $kt = StringRight( $path_unsplit, 1 )
    If $kt <> "\" Then
        $path_unsplit_new = $path_unsplit & "\"
    Else
        $path_unsplit_new = $path_unsplit
    EndIf
    ;;
    IniWrite( "data.ini", "section", $path_unsplit_new, $new_id )
EndFunc

Func _exit()
;~  FileDelete("data.ini")
    Exit
EndFunc

data2.rar

Edited by dien44
Link to comment
Share on other sites

  • Moderators

dien44,

i can't determine when to end folder of path

As you are using my RecFileListToArray UDF, all you need to do is to make sure that the path ends in a "\". Then all folders have a trailing \ and files do not - so a simple StringRight($vVar, 1) test will tell you whether the return is a file or a folder. I designed it that way for precisely that reason. :)

i have a ini file. [...] but it don't return all key. content are 1147 line, but it return 323 line.

That is because ini files are limited to 32kb - your file is over 127kb. :)

Two solutions:

- 1. Do not use an ini file, just a txt file. It will make the coding a little more complex but you do not have the size limitation.

- 2. Use SmOke_N's IniEx UDF to read the file.

But I still believe you would be better served by using FileOpenDialog or my ChooseFileFolder UDF to select a file than by creating a menu structure. :P

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png 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 columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Melba23

thanks Melba23 very much! :)

the ini file has resolved. Thanks!.

About your FileOpenDialog or ChooseFileFolder UDF. I like its. I'm sure!. But, here I have a reason.

And I have a question:

In your RecFileListToArray UDF. when finding, if a Folder is empty, progrem will continue. I want when progrem to find a empty folder, it will continue and set this path is empty, ie,.. add "empty" to end this path. Thank you so much!

Example:

i have structure folder shown bellow:

Posted Image

when use RecFileListToArray. It return:

C:\Users\DIEN_DIEM\Desktop\1

C:\Users\DIEN_DIEM\Desktop\1\1.1

C:\Users\DIEN_DIEM\Desktop\1\1.2

C:\Users\DIEN_DIEM\Desktop\1\1.2\1.2.1

C:\Users\DIEN_DIEM\Desktop\1\1.2\1.2.2

C:\Users\DIEN_DIEM\Desktop\1\1.3

C:\Users\DIEN_DIEM\Desktop\1\1.3\New folder

C:\Users\DIEN_DIEM\Desktop\1\1.4

C:\Users\DIEN_DIEM\Desktop\1\1.4\1.44.1

C:\Users\DIEN_DIEM\Desktop\1\1.4\1.44.2

I want:

C:\Users\DIEN_DIEM\Desktop\1

C:\Users\DIEN_DIEM\Desktop\1\1.1empty

C:\Users\DIEN_DIEM\Desktop\1\1.2

C:\Users\DIEN_DIEM\Desktop\1\1.2\1.2.1empty

C:\Users\DIEN_DIEM\Desktop\1\1.2\1.2.2empty

C:\Users\DIEN_DIEM\Desktop\1\1.3

C:\Users\DIEN_DIEM\Desktop\1\1.3\New folderempty

C:\Users\DIEN_DIEM\Desktop\1\1.4

C:\Users\DIEN_DIEM\Desktop\1\1.4\1.44.1empty

C:\Users\DIEN_DIEM\Desktop\1\1.4\1.44.2empty

Link to comment
Share on other sites

  • Moderators

dien44,

This now creates (empty) folder items to end a branch: :)

#include <GUIConstantsEx.au3>
#include <RecFileListToArray.au3>

Global $aLevel[25]
Global $aItem[25][2] = [[0, 0]]

$sRoot = @DesktopDir ; You can put any path here to get the folder tree into the menu <<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; Ensure final \
If StringRight($sRoot, 1) <> "\" Then $sRoot &= "\"

; Get base \ count
StringReplace($sRoot, "\", "")
$iBase = @extended

; Get folder tree
$aReturn = _RecFileListToArray($sRoot, "*", 0, 1, 1, 2)

; Create GUI
$hGUI = GUICreate("Test", 500, 500)

; Create menu
$aLevel[0] = GUICtrlCreateMenu($sRoot)

; Move through tree
For $i = 1 To $aReturn[0]

    ; Examine current return
    StringReplace($aReturn[$i], "\", "")
    $iLevel = @extended - $iBase
    If StringRight($aReturn[$i], 1) = "\" Then
        $fFolder = True
    Else
        $fFolder = False
    EndIf

    ; Check ahead if not final element
    $fNext_Folder = True
    If $i < $aReturn[0] Then
        If StringRight($aReturn[$i + 1], 1) <> "\" Then
            $fNext_Folder = False
        EndIf
    EndIf

    ; How to display current return
    ; If folder
    If $fFolder = True Then
        ; - followed by a folder
        If $fNext_Folder = True Then
            ; - then must be empty folder so create menu item
            GUICtrlCreateMenuItem($aReturn[$i] & " (empty)", $aLevel[$iLevel - 1])
        ; - followed by a file
        Else
            ; - create menu to hold file
            $aLevel[$iLevel] = GUICtrlCreateMenu($aReturn[$i], $aLevel[$iLevel - 1])
        EndIf
    ; If file
    Else
        ; - create menuitem for file and add to return list
        $aItem[0][0] += 1
        If UBound($aItem) <= $aItem[0][0] Then ReDim $aItem[UBound($aItem) * 2][2]
        $aItem[$aItem[0][0]][0] = GUICtrlCreateMenuItem($aReturn[$i], $aLevel[$iLevel])
        $aItem[$aItem[0][0]][1] = $aReturn[$i]
    EndIf

Next

GUISetState()

While 1

    $iMsg = GUIGetMsg()
    Switch $iMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $aItem[1][0] To $aItem[$aItem[0][0]][0]
            For $i = 1 To $aItem[0][0]
                If $iMsg = $aItem[$i][0] Then
                    MsgBox(0, "Menu", "You selected Item " & $aItem[$i][1])
                    ExitLoop
                EndIf
            Next
    EndSwitch

WEnd

But that is the end of my assistance. This is NOT a good way of selecting files in a tree - even if you "have a reason". :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png 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 columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

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