Sign in to follow this  
Followers 0
katoNkatoNK

Update array from file..to dynamic menu [solved]

37 posts in this topic

#1 ·  Posted (edited)

I've finally managed to understand the basics about creating an array, but i'm stuck with the more complicated things..even after looking through many many posts.

Could someone help me add/remove menu items according the array aswell as help create the 'Case' in which the menu's item is clicked from the array.

(and just as a reference - the code is outside the While statement inside the main Func)

$pRead = IniReadSectionNames($sFile)
    If IsArray($pRead) Then
        For $i = 1 To UBound($pRead) - 1
            GUICtrlCreateMenuItem($pRead[$i], $pLoad)
            TrayCreateItem($pRead[$i], $tPreset)
        Next
    EndIf

Thanks in advance!

Edited by katoNkatoNK

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Just an Example:

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>

Opt('MustDeclareVars', 1)
Opt("GUIOnEventMode", 1)

Example()

Func Example()

    ; $a_menu:
    ; 0 = Description / Text
    ; 1 = Parent Object
    ; 2 = Default?
    ; 3 = Will be used for Handle
    Local $a_menu[7][5]
    $a_menu[0][0] = 6
    $a_menu[1][0] = "&File"
    $a_menu[1][1] = 0
    $a_menu[2][0] = "Open"
    $a_menu[2][1] = 1
    $a_menu[2][2] = 1
    $a_menu[3][0] = "Save"
    $a_menu[3][1] = 1
    $a_menu[4][0] = "Exit"
    $a_menu[4][1] = 1
    $a_menu[4][0] = "?"
    $a_menu[4][1] = 0
    $a_menu[5][0] = "Info"
    $a_menu[5][1] = 4
    $a_menu[6][0] = "Test"
    $a_menu[6][1] = 4

    GUICreate("My GUI menu", 300, 200)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")

    For $i=1 To $a_menu[0][0]
        ConsoleWrite($a_menu[$i][0] & @TAB & $a_menu[$i][1] & @TAB & $a_menu[$i][2] & @TAB & $a_menu[$i][3] & @CRLF)
        If $a_menu[$i][1] = 0 Then
            $a_menu[$i][3] = GUICtrlCreateMenu($a_menu[$i][0])
        Else
            $a_menu[$i][3] = GUICtrlCreateMenuItem($a_menu[$i][0], $a_menu[$a_menu[$i][1]][3])
            If $a_menu[$i][2] = 1 Then GUICtrlSetState(-1, $GUI_DEFBUTTON)
        EndIf
        GUICtrlSetOnEvent(-1, "_"&StringReplace($a_menu[$i][0], "&", ""))
    Next

    GUISetState()
    While 1
        Sleep(200)
    WEnd
    GUIDelete()
EndFunc   ;==>Example

Func _Exit()
    Exit
EndFunc

Func _Open()
    ConsoleWrite("Open Menu Selected" & @CRLF)
EndFunc


Func _Save()
    ConsoleWrite("Save Menu Selected" & @CRLF)
EndFunc

You'll need to create a Function for every Menutitem with _<MenuitemText>()

Hope this helps.

Edited by Hannes123

Regards,Hannes[spoiler]If you can't convince them, confuse them![/spoiler]

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Thanks for the reply,

Problem is i'm trying to keep things quite simple as this is a small part of the project i'm busy with and I really don't know much about the the more 'complicated' code as in your example :unsure:

Is there any simple way of doing it for example > Case $pLoad[$i] - in my switch switch statement - a simple reference to the tagged code in my post?

(I'm also trying to keep it simple because, it's for a preset's menu so i would need to load the relevant sections values to the gui AND the rest of the gui is quite a bit and not set to use GUIOnEventMode..)

I hope it's not too much to ask.

Edit|

Here is my entire config just as a reference, as I don't want to roll back all the work done on this array in case it needs to be used elsewhere that I am unaware of..

LazyIP.au3

Edited by katoNkatoNK

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Maybe this can help you

Opt("TrayMenuMode", 1)

Global $array[2] = [9999, 9999]
Global $tray_array[2] = [9999, 9999], $last="", $titles[2]

$main = GUICreate("Test")
$choose_ini = GUICtrlCreateButton("Browse", 10, 10)
$menu = GUICtrlCreateMenu("File")
$tray = TrayCreateMenu("Test")

$ini_path = @ScriptDir & "\test.ini"
$num_of_sections = IniReadSectionNames($ini_path)
ConsoleWrite($num_of_sections)
_Load($ini_path)


GUISetState()

While 1
    $tmsg = TrayGetMsg()
    $msg = GUIGetMsg()
    Switch $msg
        Case -3
            ExitLoop
        Case $array[1] To $array[UBound($array) - 1]
            ConsoleWrite("text=" & GUICtrlRead($msg, 1) & @CRLF)
        Case $titles[1] To $titles[UBound($titles) - 1]
            ConsoleWrite(GUICtrlRead($msg,1) & @CRLF)
    EndSwitch
    Switch $tmsg
        Case $tray_array[1] To $tray_array[UBound($tray_array) - 1]
            ConsoleWrite("tray_text=" & TrayItemGetText($tmsg) & @CRLF)
    EndSwitch
    If FileExists($ini_path) Then
    $current = IniReadSectionNames($ini_path)
    $new = "" ; >>>>>>>>>>>>>>>>>>>>
    For $i = 1 To $current[0]
        $new = $new & $current[$i]
    Next
    If $new <> $last Then  ; >>>>>>>>>>>>>>>>>>>> check contents
        _Load($ini_path)
    EndIf
    EndIf
WEnd

Func _Load($path)
    If FileExists($path) Then
        For $i = 0 To UBound($array) - 1
            GUICtrlDelete($array[$i])
            TrayItemDelete($tray_array[$i])
        Next
        $num_of_sections = IniReadSectionNames($path)
        Global $array[$num_of_sections[0] + 1], $tray_array[$num_of_sections[0] + 1], $titles[$num_of_sections[0] + 1]
        For $i = 1 To $num_of_sections[0]
            $array[$i] = GUICtrlCreateMenu($num_of_sections[$i], $menu)
            $tray_array[$i] = TrayCreateItem($num_of_sections[$i], $tray)
            $section=IniReadSection ($path,$num_of_sections[$i])
;~          For $j=1 To $section[0][0]
                $titles[$i]=GUICtrlCreateMenuItem($section[1][1],$array[$i])
;~          Next
        Next
        $last = "" ;>>>>>>>>>>>>>>>>>>>>>>> the flag
        For $i = 1 To $num_of_sections[0]
            $last = $last & $num_of_sections[$i]
        Next
    EndIf
EndFunc   ;==>_Load
Edited by ahmet

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Yes thanks a lot, that did help!

I managed to tweak it a bit to suit my config but i'm still stuck on the part getting it to update the list as i'd rather not use a user defined file since the same file is going to be the entire configs resource where needed..

I've tried using an AdlibRegister function but that didn't seem to work for me, could someone help me on this?

Edit:

The main reason why i'd prefer it this way is because the user is going to be saving,editing and loading when they choose, so i guess i'd also need something foolproof so that i can understand it well enough :unsure:

Edited by katoNkatoNK

Share this post


Link to post
Share on other sites

If the file is going to be edited by some other app than this yours then you can put this

For $i = 0 To UBound($array) - 1
                    GUICtrlDelete($array[$i])
                Next
                $num_of_sections = IniReadSectionNames($ini_path)
                Global $array[$num_of_sections[0] + 1]
                For $i = 1 To $num_of_sections[0]
                    $array[$i] = GUICtrlCreateMenuItem($num_of_sections[$i], $menu)
                Next
            EndIf

in your while loop.Also you can use a flag to see if file contents have been changed.

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

no, what i meant that its going to be changed while the config is open (and only by the config) so it would need a 'passive' update cycle, would this do that aswell?

..and i have a question - when i first started to create this array for the 'inireadsectionnames', whenever i put the For/Next in the while statement it would repeat the array to no end, so would giving the 'GUICtrlCreateMenuItem' a handle '$array[$i]' (in your reply), stop this from happening?

What do you mean/how would i go about creating the flag to see if changes have been made?

If i need to add items to multiple controls would i just add another line like

$array[$i] = GUICtrlCreateMenuItem($num_of_sections[$i], $menu)

to the code?

(Sorry but i can't seem to understand arrays entirely)

Edit:

I've played around with it and come up with the following:

Global $pRead = IniReadSectionNames($sFile)
Global $pReadx = GUICtrlRead($msg, 1)

Global $pItem[2] = [9999, 9999]
Global $pItem[$pRead[0] + 1]

And inside the While statement:

If IsArray($pRead) Then
        For $i = 0 To UBound($pItem) - 1
            GUICtrlDelete($pItem[$i])
        Next
        $pRead = IniReadSectionNames($sFile)
        For $i = 1 To $pRead[0]
            $pItem[$i] = GUICtrlCreateMenuItem($pRead[$i], $pLoad)
            $pItem[$i] = TrayCreateItem($pRead[$i], $tPreset)
        Next
    Else
    EndIf

Case $pItem[1] To $pItem[UBound($pItem) -1]
                MsgBox(0, $pReadx, $pReadx)

To me it seems to be correct :?, but whenever i open the gui all i get is blank controls with a msgbox popping up with "0" & "0" as the title and content..

Edit[2]:

If i remove the MsgBox then the menu is created but with everytime being repeated multiple times..

I don't understand what i am doing wrong:(

Edited by katoNkatoNK

Share this post


Link to post
Share on other sites

After user saves changes then to refresh you use the above part

About the flag:

Once the app reads from ini store array data in a variable and then after some time check if file has been changed.

By items to multiple controls do you mean to add to menu and traymenu? If yes then you can add this TrayCreateItem, but you need another array that will hold trayitem IDs

Ask if something is unclear

Share this post


Link to post
Share on other sites

^See the edits in my previous post^

Share this post


Link to post
Share on other sites

After you create menu item you give a new value to $pItem[$i] by using TrayCreateItem.You need another array for that.

I don't know nothig about tthat with msgbox.

First post updated

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

Thanks, i realised that, the msgbox stopped showing after i made another array for the trayitem..

BUT for some reason the array created in the menu is still repeated over and over (i noticed that this is because it is in the while loop which technically keeps on looping) but there is no other way to do so that the array updates dynamically it seems.

How do i stop the menu items from being created over and over again?

(the reason your code doesn't do it is because it is an 'active' update because of clicking the 'browse' button - but also does it passively somehow, i'm trying to do it only passively so that no button needs to be clicked)

Global $pRead = IniReadSectionNames($sFile)
Global $pReadx = GUICtrlRead($msg, 1)
Global $pX_gui[2] = [9999, 9999]
Global $pX_gui[$pRead[0] + 1]
Global $pX_tray[2] = [9999, 9999]
Global $pX_tray[$pRead[0] + 1]

While 1
    $msg = GUIGetMsg()
    
    If IsArray($pRead) Then
        $pRead = IniReadSectionNames($sFile)
        For $i = 1 To $pRead[0]
            $pX_gui[$i] = GUICtrlCreateMenuItem($pRead[$i], $pLoad)
            $pX_tray[$i] = TrayCreateItem($pRead[$i], $tPreset)
        Next
    Else
    EndIf
Switch $msg
Case $pX_gui[1] To $pX_gui[UBound($pX_gui) -1]
    MsgBox(0, $pReadx, $pReadx)
EndSwitch
WEnd
Edited by katoNkatoNK

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

You need to setup a flag.

But why do you want it in while loop when it can be done whwn user loads or saves changes?

I made a mistake.See next post

Edited by ahmet

Share this post


Link to post
Share on other sites

Maybe this can help you

Opt("TrayMenuMode", 1)

Global $array[2] = [9999, 9999]
Global $tray_array[2] = [9999, 9999]

$main = GUICreate("Test")
$choose_ini = GUICtrlCreateButton("Browse", 10, 10)
$menu = GUICtrlCreateMenu("File")
$tray = TrayCreateMenu("Test")

$ini_path = @ScriptDir & "\test.ini"
For $i = 0 To UBound($array) - 1
    GUICtrlDelete($array[$i])
    TrayItemDelete($tray_array[$i])
Next
$num_of_sections = IniReadSectionNames($ini_path)
Global $array[$num_of_sections[0] + 1], $tray_array[$num_of_sections[0] + 1]
For $i = 1 To $num_of_sections[0]
    $array[$i] = GUICtrlCreateMenuItem($num_of_sections[$i], $menu)
    $tray_array[$i] = TrayCreateItem($num_of_sections[$i], $tray)
Next

$last = "" ;>>>>>>>>>>>>>>>>>>>>>>> the flag
For $i = 1 To $num_of_sections[0]
    ConsoleWrite($num_of_sections[$i] & @CRLF)
    $last = $last & $num_of_sections[$i]
Next
ConsoleWrite($last & @CRLF)


GUISetState()

While 1
    $tmsg = TrayGetMsg()
    $msg = GUIGetMsg()
    Switch $msg
        Case -3
            ExitLoop
        Case $array[1] To $array[UBound($array) - 1]
            ConsoleWrite("text=" & GUICtrlRead($msg, 1) & @CRLF)
    EndSwitch
    Switch $tmsg
        Case $tray_array[1] To $tray_array[UBound($tray_array) - 1]
            ConsoleWrite("tray_text=" & TrayItemGetText($tmsg) & @CRLF)
    EndSwitch
    $current = IniReadSectionNames($ini_path)
    $new = "" ; >>>>>>>>>>>>>>>>>>>> 
    For $i = 1 To $current[0]
        $new = $new & $current[$i]
    Next
    If $new <> $last Then  ; >>>>>>>>>>>>>>>>>>>> check contents
        ConsoleWrite("$current=" & $new & @CRLF)
        ConsoleWrite("$last=" & $last & @CRLF)
        For $i = 0 To UBound($array) - 1
            GUICtrlDelete($array[$i])
            TrayItemDelete($tray_array[$i])
        Next
        $num_of_sections = IniReadSectionNames($ini_path)
        Global $array[$num_of_sections[0] + 1], $tray_array[$num_of_sections[0] + 1]
        For $i = 1 To $num_of_sections[0]
            $array[$i] = GUICtrlCreateMenuItem($num_of_sections[$i], $menu)
            $tray_array[$i] = TrayCreateItem($num_of_sections[$i], $tray)
        Next

        $last = ""
        For $i = 1 To $num_of_sections[0]
            $last = $last & $num_of_sections[$i]
        Next
    EndIf
WEnd

Share this post


Link to post
Share on other sites

:> I will have a look at this again and play around with it tomorrow..

Thank you for your help its greatly appreciated!

I did notice that if the file doesn't exist it give the 'non-array' 'incorrect subscript' error, how could i avoid this so that it gives an error msgbox instead?

(I just tried with 'If FileExists' but i didn't seem to work :unsure:)

Share this post


Link to post
Share on other sites

I tried with fileexists and it works

Share this post


Link to post
Share on other sites

#16 ·  Posted (edited)

mm ok, ill give it another try, otherwise i'm sure 'If IsArray' should do the trick..

Where did you place it may i ask? with the statement outside the 'While 1'?

About the 'ConsoleWrite', do i need to use this in my case or is it there in case i want to later read from the console?

Edited by katoNkatoNK

Share this post


Link to post
Share on other sites

#17 ·  Posted (edited)

I placed outside and inside while loop.Now I created function for the part being repeated so if you want to add or remove somtehing you do it on one place.Look at my first post.

ConsoleWrite is just to check if everything is ok

Edited by ahmet

Share this post


Link to post
Share on other sites

Ok, great, that's what I had in mind.

I noticed my attempt with FileExists wasn't working because i declared the variable at the start of the script not within the statement like you had done it.

Thanks again for all your help.

Share this post


Link to post
Share on other sites

You are welcome

Share this post


Link to post
Share on other sites

#20 ·  Posted (edited)

I have another question, about gui's and using 'Func()' in general..

Say I have a "variable = ..." in my main gui's While statement then a button is pressed that calls a function that has a new gui in it, would i need to recall the "variable = ..." in the new function's while statement to be able to use it? Or does the main gui's While statement's variables apply to all the functions called within it?

(If my question is unclear then have a look at the attachment in my second post for examples)

Edit:

Well what i'm really asking is if there is an alternative to do this with having to 'redeclare'..:unsure:

Edited by katoNkatoNK

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