Jump to content

creating menu's using arrays


insomnai
 Share

Recommended Posts

Hi guys and gals, i've been experimenting with the great advice given by Melba23 and would like to ask further questions on how to proceed with the next part...

Here is what I have now I understand the basic concept of an array:

'thetoolkit' and 'menutitles.ini'

menutitles.ini is very basic, pretty much as follows:

[installers]

[special]

[Technicians Only]

[Help]

'thetoolkit' script reads the 'menutitles.ini' and creates the top menu based on it's contents as follows:

#include <GUIConstantsEx.au3>

;vars
;NOT IN USE $ScriptDir = StringLeft(@ScriptDir,2) ; specifies the drive letter and colon i.e. g:
;NOT IN USE $Config = $ScriptDir & "\config\"    ; specifies where the .ini files will be kept
 
; Read ini section names
$menuTitles = IniReadSectionNames("menutitles.ini")
 
; Create an array to hold the CIDs of the menu-names
Global $aMenuTitle[$menuTitles[0] + 1] = [$menuTitles[0]]
 
; Create the GUI
$hGUI = GUICreate("Test Toolkit", 500, 100)
GUISetBkColor(0x000000)
 
; Create the main menu
For $i = 1 To $menuTitles[0]
$aMenuTitle[$i] = GUICtrlCreateMenu($menuTitles[$i])
Next
 
GUISetState()
 
While 1
$iMsg = GUIGetMsg()
Switch $iMsg
        Case $GUI_EVENT_CLOSE
            Exit
EndSwitch
WEnd

As you can probably guess, what i'm wanting is to adapt the script so that I can add extra ini files which correspond with the menutitles.ini, so perhaps 'installers.ini', 'special.ini', 'technicians.ini' and 'help.ini'.

This is all well and good but what I can't figure out is how to attach an ini file i.e. 'installers.ini' so that when I click on the appropriate menutitle, the menuitems read from 'installers.ini' are read and selecting them runs the appropriate program which ideally, is also listed in the ini. for example:

menutitles.ini

[installers]

installers.ini

[antivirus]

antivirus.ini ; (Program Name, To Run, File Name)

[Norton 360]

To Run=n360.exe

The whole point of this is so that I can control how everything works from outside the script...

As always, any help would be very much appreciated.

insomnai

Link to comment
Share on other sites

I would pack it together in one ini file:

[MenuTitles]
Title=Installers
Title=Special
Title=Technicians Only
Title=Help

[Installers]
ToRun=Norton.exe

You can read all menu titles with function IniReadSection into an array.

So you don't get lost with too many ini files.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

ok, this idea is interesting, could you show me how I could possibly edit my script to resemble what you mean here? Also, the alternative ini section [installers] isn't the only variant, if I could turn your attention to the following:

menutitles.ini

[installers]

installers.ini

[antivirus]

antivirus.ini ; (Program Name, To Run, File Name)

[Norton 360]

To Run=n360.exe

My GUI will have a menu title of 'Installers' and in that menu title, there is a submenu called 'AntiVirus' and in that submenu there is a list of different AntiVirus Installers to chose from, selecting one of those will tell the script to begin running the appropriate file.

Does my explanation here change the way you would lay out the INI file?

Still trying to wrap my head around this bit :-)

Many thanks all

Link to comment
Share on other sites

  • Moderators

insomnai,

You asked me to look in - so do not blame me if you find the code is complicated! :)

I would do it something like this: ;)

#include <GUIConstantsEx.au3>

; Create an array to hold the menu items when created
Global $aMenuItems[1][2] = [[0]]

; Declare ini file
$sIni = "M:ProgramAu3 Scriptsmenu.ini"

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

; And start the menu creation process
_Fill_Menu(0, "MenuTitles")

GUISetState()

While 1

    ; Get the control ID
    $iMsg = GUIGetMsg()
    Switch $iMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case Else
            ; Loop through the array to see ifit is a menuitem controlID
            For $i = 1 To $aMenuItems[0][0]
                If $aMenuItems[$i][0] = $iMsg Then
                    ; It is!
                    MsgBox(0, "Menu", "You clicked " & @CRLF & $aMenuItems[$i][1])
                    ; No point in looking further
                    ExitLoop
                EndIf
            Next
    EndSwitch

WEnd



Func _Fill_Menu($hCID, $sText)

    ; Read next level down
    $aMenu = IniReadSection($sIni, $sText)
    If Not @error Then
        ; Now either create a further submenu or a menuitem
        For $i = 1 To $aMenu[0][0]
            Switch $aMenu[$i][0]
                Case "Item"
                    ; Increase the count of menuitems
                    $aMenuItems[0][0] += 1
                    ; Increase the array size by adding a new element
                    ReDim $aMenuItems[$aMenuItems[0][0] + 1][2]
                    ; Add the ControlID and text to the newly created array element
                    $aMenuItems[$aMenuItems[0][0]][0] = GUICtrlCreateMenuItem(StringReplace($aMenu[$i][1], "_", " "), $hCID)
                    $aMenuItems[$aMenuItems[0][0]][1] = StringReplace($aMenu[$i][1], "_", " ")
                Case "Menu"
                    ; Create menu
                    If $hCID Then
                        ; It is a submenu
                        $aMenu[$i][0] = GUICtrlCreateMenu(StringReplace($aMenu[$i][1], "_", " "), $hCID)
                    Else
                        ; It is a top level menu
                        $aMenu[$i][0] = GUICtrlCreateMenu(StringReplace($aMenu[$i][1], "_", " "))
                    EndIf
                    ; Fill menu - note this is a recursive call and we need to take care
                    _Fill_Menu($aMenu[$i][0], $aMenu[$i][1])
            EndSwitch
        Next
    EndIf

EndFunc

And here is the ini file:

[MenuTitles]
Menu=Installers
Menu=Special
Menu=Technicians_Only
Menu=Help

[Installers]
Menu=AntiVirus
Menu=Editor
Menu=Hex_Editor

[AntiVirus]
Item=Norton.exe
Item=AVG.exe
Item=Avast.exe

[Editor]
Item=SciTE.exe
Item=EditPad.exe

[Hex_Editor]
Item=frhed.exe

[Special]
Item=Special_1
Item=Special_2

[Help]
Item=Help
Item=About

I used the underscore at times as you can have only a single word as a section title in the ini file - but we needed multiple words in the menu itself - you can see where I replaced it when required. ;)

See how you get on following the code. 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

I'm actually doing something somewhat similar. It is all in 1 ini file though, and the script allows for the user to either run a demo of the menu, or have the script write another (static) script independent of the ini file. If you like, I can uploade it within the next 24 hours. I have not quite got it up to scratch yet, there are still a few things that I wish to do, however, I am happy to upload it if you wish.

Link to comment
Share on other sites

  • Moderators

insomnai,

Is this what they call 'multi dimensional arrays' by any chance?

It certainly is. ;)

But do not get too alarmed - think of them as grids like this:

[0]  [1]

[0]    a    b
[1]    c    d

So element [0][0] = a, [0][1] = b, [1][0] = c and [1][1] = d. Does that make it any easier to grasp? :)

Try and follow the code, but as I said, do ask if you cannot. As always my aim as to get you to understand what is going on so you can do it yourself in future. ;)

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

Wow, I just can't see what is going on in there... I can't see where $hCID get's any of its information, and I don't understand the 'function' that you have created at the bottom of the script or how it affects the earlier section.

The aim was to see if the ini's could be seperated so that information could be handled like 'categories'.

I think I need to find another hobby :/

Link to comment
Share on other sites

  • Moderators

insomnai,

Then let us walk through it slowly. ;)

I assume you have no problem with the standard GUI stuff, so I will just explain the _Fill_Menu function and the "clever stuff" in the While...WEnd loop. ;)

We call the function initially from within the main script with this syntax: _Fill_Menu(0, "MenuTitles")

So we arrive in the function and assign $hCID = 0 and $sText = "MenuTitles" (because they are the parameters the function expects).

We next read the ini section "MenuTitles" (because that is what the variable $sText holds). If we find some values in that section we loop through them to decide what to do.

- If the key tells us it is an "Item" then we need to add it to the menu that it belongs to - but we will come back to this in a moment.

- If the key tells us it is a "Menu" than we add this submenu to the menu we are currently exploring - its ControlID is in $hCID as you will see in a minute. But for the first run through, $hCID is set to 0 (see above) as we are dealing with the top level menus and not submenus. This is why we have the If $iCID section - you can see that we do not use the menuID parameter in the GUICtrlCreateMenu function as the top-level menus do not need it.

Once we have created the submenu we need to see what is inside it - so we call the function again (this is known as recursion and it is a very powerful tool but one that needs to be treated with great care). This time we pass the function the ControlID of the menu we have just created and its name - so when the function runs again it knows which values to put into the $hCID and $sText variables.

Now we can discuss the MenuItems. They can only be added to a Menu - and the menu to which they will be added is passed in the $iCID variable (you cannot have items in the top level which is why we do not need to check for $hCID when creating them). When we create a menuitem we add an entry to the $aMenuItems array - the [0] element gets the ControlId and the [1] element gets the text. The ReDim part just adds another row to the array so there is room for the new MenuItem. Similarly we add any submenus and then call the function again to fill them.

Now when we have created the menu we look in the While...WEnd loop to see if any of the MenuItem ControlIDs appear by running through the array and comparing the [0] elements (which contain the ControlIDs) match the GUIGetMsg return value. if we find a match we show the MsgBox with the matching [1] element of the array (which holds the text).

Does that make it any clearer? :)

I did warn you that it was a bit complicated - but try and follow what I have just explained using a piece of paper. Remember that each time you run the function you create a new set of variables and do NOT overwrite the existing ones - that is why recursion is both powerful and dangerous. :)

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