Sign in to follow this  
Followers 0

[Resolved] Adding Items Dynamically in the GUI from the User POV

26 posts in this topic

Posted (edited)

I'm currently working on a project that requires the user to dynamically be able to add and remove links (95% weblinks) to a 'toolbox' program that is being used by the entire department.

I am not sure how is best to go about this, specifically using AutoIT for now.

Any suggestions, thoughts or directions to be pointed in are always appreciated.

I guess the basic question I should ask first is, can AutoIT do something like this with it's GUI functions? I did download, and am currently investigating, Koda to see if it might speed up the process any.

Thanks again for any thoughts on the matter...

-Nick

Edited by xeroTechnologiesLLC

Share this post


Link to post
Share on other sites



Posted

The way I see it, you can have labels instead of proper "links" - when clicked, you can make it to behave like a "real" one.

Removing links? = easy, set the label's text to ""

Add a new one? = set the label's text to the desired one

You will need also a right-click menu to allow users to edit/add/delete those links.

With a little bit of tweaking you can get it working as you wish

Share this post


Link to post
Share on other sites

Posted

Nice, I didn't think about the right click idea.

Could you point me to the code to create a specific right click menu?

The way we have decided on the layout will be using menuItems so would the same concept apply?

Add a new item button runs a function to open a form that the user will fill out which menu they want the link item in, they type in the name, add the location of the item and hit save and it adds the item into the menu. Essentially that is what I am wanting to accomplish on this if possible.

I am off for the day very shortly, but will continue working on this again tomorrow if any ideas strike you tonight.

Thanks in advance.

-Nick.

Share this post


Link to post
Share on other sites

Posted (edited)

GUICtrlCreateContextMenu

Edited by enaiman

Share this post


Link to post
Share on other sites

Posted

Thank you very much enaiman. I appreciate the time taken.

I will look into it and get back to this thread with further questions if needed.

I'm still looking for code to add menucontextitems to the main top menu on the fly if possible and make the changes permanent each time the user runs the program. Perhaps save the options to a config.ini file somehow?

Share this post


Link to post
Share on other sites

Posted

So I have a theory I am going to try and follow....

When the user loads up the GUI form that will ask for the relevant data to create a new menu item, it stores/writes it to an XML file (or ini file, i guess it probably doesn't matter).

Then when the program launches it will read that XML file and fill in the sub menu items to the appropriate menu item.

It's just a theory and I honestly have no idea how to completely accomplish it, but going to start by making the second GUI form write to an XML file and see how well that goes first.

If anyone has any other ideas on how I might go about letting the user add menu options to the program as they want - let me know. I'm open for ideas!

-nick

Share this post


Link to post
Share on other sites

Posted

xeroTechnologiesLLC,

By chance I wrote this yesterday in response to another question about creating menus from ini files. Does it help at all? :)

If you think it has potential than let me know and we can work on it. ;)

M23

Share this post


Link to post
Share on other sites

Posted

....

;)

...

;):):D:)

if you're getting paid - you need a raise.... this is ... beyond perfect, thank you very very much.

I came in this morning psyched to work with ini files for the first time and this definitely sets my project ahead by leaps and bounds. I can't thank you enough.

Consdier this one resolved by your provided link... thank you!

Share this post


Link to post
Share on other sites

Posted

xeroTechnologiesLLC,

if you're getting paid - you need a raise

I am not, I am a volunteer as we all are here. But perhaps you might like to donate something to the site hosting costs. :)

M23

Share this post


Link to post
Share on other sites

Posted

One final question. My menu has a lot of prebuilt data first, then a User Added menu item which is where I want the user created data to go.

the ini....

[MenuTitles]
Menu=User_Added
[User_Added]
Item=1
Item=2
Item=3

So would I just use that same function and it is supposed to write the data in the ini file to the pre-created User Added menu item?

Share this post


Link to post
Share on other sites

Posted

actually, i lied - another question is how would you create a LOAD ALL style function that when clicked it would know to load all the menu items?

I'm theorizing using some sort of array, but I'm extremely bad with arrays.

I did figure out the other question - it just adds another menu item at the end, so for now I just commented out my static version of the same thing.

Share this post


Link to post
Share on other sites

Posted

xeroTechnologiesLLC,

actually, i lied

No problem - you are by no means the only one around here who does that! ;)

As to the new question: The code I posted shows how to load the menus form the ini when you create the GUI. Do you mean that you want to reload the menus while the script is running? :)

M23

Share this post


Link to post
Share on other sites

Posted

Melba,

Oh by no means do I want to get into the 'refresh menu' mess. lol

More of what I am looking for is in the example of this:

Menu 1

sub1

sub2

sub3

load all <--calls sub1, sub2, sub3 all at once.

So far I have code for all my other menus to load every menu item at the click of a button, but that's in a static arrangement. I know exactly how many menu items there are and what the menu item names are.

But with the array (I'm sorry I'm horrible with arrays) I won't know that information so... how do i code it to load all the items in that menu list?

Also, for further information that is relevant to this, still working on how to take information from the user (link name, and the link) and just the link name display on the menu, but when they click it it runs the according link itself. Having some trouble with how to mix that into all this as well since it's all dynamic.

Thanks again,

Nick

Share this post


Link to post
Share on other sites

Posted

Ran into another problem using the 2nd gui form to add items to the ini file.

I was using:

IniWrite($sIni, "User_Added", "Item", GUIctrlRead($menuName))
IniWrite($sIni, "Links", "Link", GUIctrlRead($location))

But this just overwrites the first line in each respective section. Is there a way to just get it to append to the end of the section?

Share this post


Link to post
Share on other sites

Posted

xeroTechnologiesLLC,

You can add/remove the additional menus like this - just use the ini file from the thread to which I linked you: ;)

#include <GUIConstantsEx.au3>

Global $aUserItems[2] = [0, 0]

; 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)

; Add the static menu
Global $mFileMenu = GUICtrlCreateMenu("&File")
Global $mExitItem = GUICtrlCreateMenuItem("E&xit", $mFileMenu)
Global $mAdminMenu = GUICtrlCreateMenu("&Admin")
Global $mPrintCurrItem = GUICtrlCreateMenuItem("&Print Currencies", $mAdminMenu)
Global $mShowHours = GUICtrlCreateMenuItem("&Show Hours", $mAdminMenu)
GUICtrlCreateMenuItem("", $mAdminMenu)
Global $mDatRestore = GUICtrlCreateMenuItem("&Restore Backup Files", $mAdminMenu)
Global $mDatImport = GUICtrlCreateMenuItem("&Import Backup Files", $mAdminMenu)
GUICtrlCreateMenuItem("", $mAdminMenu)
Global $mPasswordItem = GUICtrlCreateMenuItem("&Change Admin Password", $mAdminMenu)
Global $mHelpMenu = GUICtrlCreateMenu("&Help")
Global $mAboutItem = GUICtrlCreateMenuItem("&About", $mHelpMenu)

$hButton_Add = GUICtrlCreateButton("Add User Menus", 10, 10, 120, 30)
$hButton_Rem = GUICtrlCreateButton("Remove User Menus", 10, 50, 120, 30)


GUISetState()

While 1

    ; Get the control ID
    $iMsg = GUIGetMsg()
    Switch $iMsg
        Case $GUI_EVENT_CLOSE
            Exit
		Case $hButton_Add
			; Get the first and last ControlID created from the user menus
			$aUserItems = _Fill_Menu(0, "MenuTitles")
		Case $hButton_Rem
			; Delete all the user menus
			For $i = $aUserItems[0] To $aUserItems[1]
				GUICtrlDelete($i)
			Next
        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)

	Local $aCID[2]

	; This si the first ControlID we create
	$aCID[0] = GUICtrlCreateDummy()
    ; 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
	; And this is the last ControlID we create
	$aCID[1] = GUICtrlCreateDummy()

	Return $aCID

EndFunc

And of course it means you can have multiple ini files and so multiple user menu schemes. ;)

I will now have a think about how to get the user data into the process. :)

M23

Share this post


Link to post
Share on other sites

Posted

Well I was thinking of using a function to write the value from input boxes into the ini file, but ran into the problem of it overwrites the first line in the section.

The next item I'm not quite understanding is how to run a program or weblink off the menu items.

I'm familiar with just useing case statements, but how would you do that in this fashion with dynamically adding / removing menu options?

Share this post


Link to post
Share on other sites

Posted (edited)

xeroTechnologiesLLC,

Here is something which allows you to add menu items dynamically and link them to the required user input: ;)

#region

	#include <guiconstantsex.au3>
	#include <windowsconstants.au3>
	#include <staticconstants.au3>
	#include <guitreeview.au3>

	Global $aUserItems[2] = [0, 0]

	; 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)

	; Add the static menu
	Global $mFileMenu = GUICtrlCreateMenu("&File")
	Global $mExitItem = GUICtrlCreateMenuItem("E&xit", $mFileMenu)
	Global $mHelpMenu = GUICtrlCreateMenu("&Help")
	Global $mAboutItem = GUICtrlCreateMenuItem("&About", $mHelpMenu)

	$hButton_Ins = GUICtrlCreateButton("Show User Menus", 10, 10, 120, 30)
	$hButton_Rem = GUICtrlCreateButton("Remove User Menus", 10, 50, 120, 30)

	$hButton_Add = GUICtrlCreateButton("Add User Menu Item", 10, 90, 120, 30)

	GUISetState()

#endregion

While 1

	; Get the control ID
	$iMsg = GUIGetMsg()
	Switch $iMsg
		Case $GUI_EVENT_CLOSE, $mExitItem
			Exit
		Case $hButton_Ins
			; Get the first and last ControlID created from the user menus
			$aUserItems = _Fill_Menu(0, "UserMenu")
		Case $hButton_Rem
			; Delete all the user menus
			For $i = $aUserItems[0] To $aUserItems[1]
				GUICtrlDelete($i)
			Next
		Case $hButton_Add
			_Add_User_Items("UserMenu")
		Case $mAboutItem
			MsgBox(0, "Hi", "Hope you find this interesting")
		Case Else
			; Loop through the array to see if it 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] & @CRLF & @CRLF & _
								"Which means we will run: " & @CRLF & IniRead($sIni, "Links", StringReplace($aMenuItems[$i][1], " ", "_"), "Error"))
					; No point in looking further
					ExitLoop
				EndIf
			Next
	EndSwitch

WEnd

Func _Fill_Menu($hCID, $sText)

	Local $aCID[2]

	; This si the first ControlID we create
	$aCID[0] = GUICtrlCreateDummy()
	; 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]
			If StringInStr($aMenu[$i][0], "Item") Then
				; 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], "_", " ")
			Else
				; 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])
			EndIf
		Next
	EndIf
	; And this is the last ControlID we create
	$aCID[1] = GUICtrlCreateDummy()

	Return $aCID

EndFunc   ;==>_Fill_Menu

Func _Add_User_Items($sText)

	; Create child GUI
	$hGUI_Add = GUICreate("Add Items", 400, 400, 50, -50, -1, $WS_EX_MDICHILD, $hGUI)

	; Create a treeview
	GUICtrlCreateLabel("", 10, 10, 200, 380, $SS_BLACKFRAME)
	GUICtrlSetState(-1, $GUI_DISABLE)
	$hTreeView = GUICtrlCreateTreeView(20, 20, 180, 380);, $WS_BORDER)
	$hTV_Item = $hTreeView

	; Fill the treeview with the menu structure
	_Fill_TV($hTreeView, $sText)

	; Create other controls
	GUICtrlCreateLabel("Enter menu item text", 220, 10, 160, 20)
	$hInput_Item = GUICtrlCreateInput("", 220, 40, 160, 20)
	GUICtrlCreateLabel("Enter link", 220, 80, 160, 20)
	$hInput_Link = GUICtrlCreateInput("", 220, 100, 160, 20)
	$hButton_Addition = GUICtrlCreateButton("Add to menu", 310, 150, 80, 30)

	GUISetState()

	While 1

		Switch GUIGetMsg()
			Case $GUI_EVENT_CLOSE
				ExitLoop
			Case $hButton_Addition
				; Do we have user input
				If GUICtrlRead($hInput_Item) <> "" And GUICtrlRead($hInput_Link) <> "" Then
					; Read the selected menu from teh treeview
					$sSection = StringReplace(_GUICtrlTreeView_GetText($hTreeView, GUICtrlRead($hTreeView)), " ", "_")
					; Get the item count
					$aItems = IniReadSection($sIni, $sSection)
					$iIndex = $aItems[0][0] + 1
					; Write the new item
					$sItem = StringReplace(GUICtrlRead($hInput_Item), " ", "_")
					IniWrite($sIni, $sSection, "Item" & $iIndex, $sItem)
					; Write the link
					IniWrite($sIni, "Links", $sItem, GUICtrlRead($hInput_Link))
					ExitLoop
				EndIf
		EndSwitch

	WEnd

	; Delete GUI
	GUIDelete($hGUI_Add)
	; Delete all the user menus
	For $i = $aUserItems[0] To $aUserItems[1]
		GUICtrlDelete($i)
	Next
	; Reset menu
	$aUserItems = _Fill_Menu(0, "UserMenu")

EndFunc   ;==>_Add_User_Items

Func _Fill_TV($hTV_Item, $sText)

	; Read next level down
	$aMenu = IniReadSection($sIni, $sText)
	If Not @error Then
		; Now run through menu structure
		For $i = 1 To $aMenu[0][0]
			Switch $aMenu[$i][0]
				Case "Menu"
					; Create TreeViewItem
					$hTV_NewItem = GUICtrlCreateTreeViewItem(StringReplace($aMenu[$i][1], "_", " "), $hTV_Item)
					; Fill TV - note this is a recursive call and we need to take care
					_Fill_TV($hTV_NewItem, $aMenu[$i][1])
			EndSwitch
		Next
	EndIf

EndFunc   ;==>_Fill_TV

Still a bit rough and ready, but it shows the principle. :)

You need this ini file:

[UserMenu]
Menu=Menu_1
Menu=Menu_2

[Menu_1]
Menu=SubMenu_11
Menu=SubMenu_12

[SubMenu_11]
Item1=Item_111
Item2=Item_112
Item3=Item_113

[SubMenu_12]
Item1=Item_121
Item2=Item_122

[Menu_2]
Item1=Item_21
Item2=Item_22

[Links]
Item_111=Link 111
Item_112=Link 112
Item_113=Link 113
Item_121=Link 121
Item_122=Link 122
Item_21=Link 21
Item_22=Link 22

Note how I have added numbers to the section keys to prevent overwriting them. :)

Let me know what you think. ;)

M23

Edited by Melba23

Share this post


Link to post
Share on other sites

Posted

Getting an error when trying to add an item. - subscript used as an array on non array variable or something of the like.

I kind of see what you are doing here but it'll take me a while to read through it all.

Being new to AutoIT and HORRIBLE with arrays is never a good combo. lol

I'll reply back when I have a tangable opinion on it HAHA

Share this post


Link to post
Share on other sites

Posted

xeroTechnologiesLLC,

Obviously it worked for me or I would not have posted it. ;)

Try resaving the ini from the post above and then do the following:

- Show the user menus.

- Press the "Add" button

- Select "SubMenu 12" in the TreeView

- Enter "Item 123" and "Link 123" into the inputs

- Press the "Add" button

You should find that you now have Item 123 under Submenu 12 and pressing in will bring up the MsgBox with Link 123.

If you still get the error then let please post the content of the SciTE lower pane so I can see the exact error and where it occured. :)

M23

Share this post


Link to post
Share on other sites

Posted

helps when i have the ini file in the right directory huh?....

probably not the best day i should be this deep into arrays LOL

I have played around with what you provided and I think it will be a great method to do what I am wanting to do.

I will experiment with it some more through the day and see what I can come up with.

thank you very much for all the help M23.

I'll reply back in a few days (off next 2 days) once I've got some more work done.

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