icu Posted June 25, 2011 Share Posted June 25, 2011 (edited) Dear AutoIt Community,I would like help pointing the way to a solution.I've got a GUI, lets call it '$Form_Main' and I want it to launch a settings GUI, lets call it '$Form_Settings'.I've made both $Form_Main and $Form_Settings in Koda and both lots of code are in MessageLoop Mode.What I can't figure out is how to launch $Form_Settings from inside $Form_Main (with a button) and how I would then handle passing variable changes in $Form_Settings back to $Form_Main and how to handle $GUI_EVENT_CLOSE in $Form_Settings without closing $Form_Main.I have tried to use the Wiki article on managing multiple GUIs as a guide but I don't see how I can apply it's sample code. The example shows two GUIs opening up simultaneously, whereas I want $Form_Main always running and $Form_Settings to only start once I click a button and only close itself if $GUI_EVENT_CLOSE is triggered.Please don't ask for code, I've got several hundred lines ;-) If possible I need a conceptual answer (I'm happy to do the homework if pointed in the right direction) otherwise example code would be greatly appreciated.Many thanks for any and all help!-icu Edited June 27, 2011 by icu Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted June 25, 2011 Moderators Share Posted June 25, 2011 icu, The example shows two GUIs opening up simultaneouslyNo it does not! I wrote the tutorial and the proposed solution shows the second GUI opening when a button on the first is pressed. If you want to prevent the first GUI from reacting when the second GUI is present, you need to disable/enable it like this (look for <<<<<<<< as usual): expandcollapse popup#include <GUIConstantsEx.au3> Global $hGUI2 = 9999, $hButton3 = 9999 ; Predeclare the variables with dummy values to prevent firing the Case statements gui1() Func gui1() $hGUI1 = GUICreate("Gui 1", 200, 200, 100, 100) $hButton1 = GUICtrlCreateButton("Msgbox 1", 10, 10, 80, 30) $hButton2 = GUICtrlCreateButton("Show Gui 2", 10, 60, 80, 30) GUISetState() While 1 $aMsg = GUIGetMsg(1) ; Use advanced parameter to get array Switch $aMsg[1] ; check which GUI sent the message Case $hGUI1 Switch $aMsg[0] ; Now check for the messages for $hGUI1 Case $GUI_EVENT_CLOSE ; If we get the CLOSE message from this GUI - we exit <<<<<<<<<<<<<<< ExitLoop Case $hButton1 MsgBox("", "MsgBox 1", "Test from Gui 1") Case $hButton2 GUICtrlSetState($hButton2, $GUI_DISABLE) WinSetState($hGUI1, "", @SW_DISABLE) ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< gui2() EndSwitch Case $hGUI2 Switch $aMsg[0] ; Now check for the messages for $hGUI2 Case $GUI_EVENT_CLOSE ; If we get the CLOSE message from this GUI - we just delete the GUI <<<<<<<<<<<<<<< WinSetState($hGUI1, "", @SW_ENABLE) ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< GUIDelete($hGUI2) GUICtrlSetState($hButton2, $GUI_ENABLE) Case $hButton3 MsgBox("", "MsgBox", "Test from Gui 2") EndSwitch EndSwitch WEnd EndFunc ;==>gui1 Func gui2() $hGUI2 = GUICreate("Gui 2", 200, 200, 350, 350) $hButton3 = GUICtrlCreateButton("MsgBox 2", 10, 10, 80, 30) GUISetState() EndFunc ;==>gui2 All clear? M23 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 columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
icu Posted June 25, 2011 Author Share Posted June 25, 2011 (edited) @Melba23: Whoops! Thanks for the quick reply and for the correction. My mistake! A couple of things I don't quite understand... Q1: Why did you put the main GUI into a function with a loop and put the sub-GUI into another function without one? Q2: Why should I copy this idea? I.e. Predeclare some dummy GUI variables, create a function for Form_Main with a loop inside it and create another function for Form_Settings? Is there something I'm not seeing here because it seems extreme to me to encapsulate each GUI into a function. Why can't there be two GUIs defined outside of a loop and a loop with a switch and a trigger to start the sub-GUI? Many thanks, -icu Edited June 25, 2011 by icu Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted June 25, 2011 Moderators Share Posted June 25, 2011 icu,Q1: Why did you put the main GUI into a function with a loop and put the sub-GUI into another function without one?Because if you use the "advanced" parameter with GUIGetMsg you only need one loop. You could very well have 2 loops, one for each GUI, but you would still have the problem of distinguishing which GUI sent the $GUI_EVENT_CLOSE message unless you disable the main while the child is active or use the "advanced" parameter - which rahter defeats the .Q2: Why should I copy this idea?You do not have to. There are many ways of coding a main GUI and a child - I just used this method for the tutorial to demonstrate how you can use the "advanced" parameter with GUIGetMsg. You can write your code as you wish - I will not get annoyed, promise! M23 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 columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
icu Posted June 26, 2011 Author Share Posted June 26, 2011 @Melba23: Thanks again for your easy to understand explanations. I've followed the structure of your code, i.e. predeclare some dummy variables, put the main GUI into a function with a loop and put the sub-GUI into another function without one and it works... but then you knew that would happen :-) So this handles the 'Click here in the Main GUI and a new child GUI pops up' problem and the 'Click close on the child GUI and the Main GUI doesn't close' problem. However I'm having trouble thinking of a way to simply pass variables and variable changes from the child GUI back to the main GUI because the GUIs are encapsulated within functions and as far as I can gather, the variables only exist within each separate function and not the whole program. Declaring Global variables with a function won't work (and I don't know why... I thought if you declare something Global no matter where it would be Global everywhere). My only idea at this point is to pre-declare a large set of 'buffer' Global variables outside of the GUI functions to capture any changes to the matching variables in the child GUI so the main GUI can 'read' them. I imagine this is going to be messy and I was hoping you could point the way to an easier solution? Kind regards, -icu Link to comment Share on other sites More sharing options...
icu Posted June 26, 2011 Author Share Posted June 26, 2011 (edited) I've given up on the idea to pre-declare a large set of 'buffer' Global variables to maintain all the MessageLoop code I've written. I just can't seem to figure it out and it's getting too complicated to conceptualise all of the changes I need to make to my existing code. So I went back to the drawing board and re-thought about using OnEvent code (having never used it). I played with Koda (thankfully I saved all those .kxf files) until it spat out OnEvent code for my two GUIs and it seems like this is the best solution for having variables interact and be changed between a main and child GUI. So while it pains me to re-write everything in OnEvent mode, it seems like a more modular and robust solution if I want to add more child GUIs to my program. If you are going to code a 'settings' child GUI I think you should choose OnEvent code as the way to go. Edited June 27, 2011 by icu Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted June 26, 2011 Moderators Share Posted June 26, 2011 icu, I'm having trouble thinking of a way to simply pass variables and variable changes from the child GUI back to the main GUI because the GUIs are encapsulated within functions and as far as I can gather, the variables only exist within each separate function and not the whole programBut you can pass variables as parameters to and from functions in MessageLoop mode - that is what parameters are for. If you are going to code a 'settings' child GUI I think you should choose [OnEvent mode] as the way to go.Not at all, you can easily use either mode for this - I have a script with many dialogs, many of which change settings in the main script. There are advantages and disadvantages to both modes - you need to choose the one that best suits the situation. And if you are worried about the number of variables you need to pass - just remember that you can pass arrays as parameters! Good luck with your script - whichever mode you choose. M23 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 columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
icu Posted June 27, 2011 Author Share Posted June 27, 2011 (edited) @Melba23: Thanks again for your reply:But you can pass variables as parameters to and from functions in MessageLoop mode - that is what parameters are for.I have no idea how to do this and I haven't found any resources to learn from or adapt for my purpose. Any ideas?Not at all, you can easily use either mode for thisI would debate the use of the word "easily"... perhaps for a 'Code God' like yourself ;-) I'm a mere mortal without previous coding experience trying to make sense of it all. I certainly feel I've come a long way thanks to the efforts of the AutoIt community putting together an excellent help file, how-to resources, and the forum. I've stuck to AutoIt because solutions always seemed obvious or when I got stuck and asked for help the solutions suggested by others seemed obvious in hindsight. This has not been my experience for getting MessageLoop mode working with a main and child GUI. When you are self taught you are always caught in the trap of not knowing what you don't know.In my frustration I turned to experimenting with OnEvent mode and it was instantly understandable... no more $GUI_EVENT_CLOSE problem and each input for either GUI (i.e. a button) is a function that can easily manipulate and interact with any other function or variable in the rest of the program.I'm still clueless how it would work with MessageLoop mode (and not for lack of trying)... and that's my point really. If it was so easy to use MessageLoop mode I would have got it by now!-icu Edited June 27, 2011 by icu Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted June 27, 2011 Moderators Share Posted June 27, 2011 icu, pass variables as parameters to and from functions in MessageLoop modeA very simple example: ; Declare our values $iVar_1 = 2 $iVar_2 = 3 ; Pass the 2 variables as parameters to the function and get a value in return $iResult = _Multiply($iVar_1, $iVar_2) ; Display the result MsgBox(0, "Result", $iVar_1 & " x " & $iVar_2 & " = " & $iResult) ; The function takes 2 parameters as input Func _Multiply($x, $y) ; These parameters take the value of the variables passed to the function MsgBox(0, "In the function", "$x = " & $x & @CRLF & "$y = " & $y) ; And you can return a value directly - here is is the value of the product of the parameters Return $x * $y EndFunc As to not understanding MessageLoop mode - do not worry, it will come to you in the end. As I said earlier, there is not hard and fast rule as to which mode to use - I tend to use MessageLoop most the time as I prefer it, others here use OnEvent almost exclusively. You just pick the one which best suits you for the task you are coding. But do try and get yuur head around MessageLoop mode - without it you are missing a valuable tool in your coding toolbox. As a help to your education, here is a short script in MessageLoop mode with a child settings dialog - see if you can follow it: expandcollapse popup#include <GUIConstantsEx.au3> _Main() Func _Main() Local $hGUI = GUICreate("Test", 500, 500) Local $hLabel_1 = GUICtrlCreateLabel("Label 1", 10, 10, 200, 70) GUICtrlSetBkColor(-1, 0xFF8080) Local $hLabel_2 = GUICtrlCreateLabel("Label 2", 10, 100, 200, 70) GUICtrlSetBkColor(-1, 0xFF8080) Local $hLabel_3 = GUICtrlCreateLabel("Label 3", 10, 190, 200, 70) GUICtrlSetBkColor(-1, 0xFF8080) Local $hLabel_4 = GUICtrlCreateLabel("Label 4", 10, 280, 200, 70) GUICtrlSetBkColor(-1, 0xFF8080) Local $hLabel_5 = GUICtrlCreateLabel("Label 5", 10, 370, 200, 70) GUICtrlSetBkColor(-1, 0xFF8080) Local $hButton_Settings = GUICtrlCreateButton("Settings", 400, 10, 80, 30) GUISetState() While 1 $iMsg = GUIGetMsg() If $iMsg <> 0 Then ConsoleWrite($iMsg & @CRLF) Switch $iMsg Case $GUI_EVENT_CLOSE Exit Case $hButton_Settings ; We pass the Local variables to another function _Settings($hGUI, $hLabel_1, $hLabel_2, $hLabel_3, $hLabel_4, $hLabel_5) EndSwitch WEnd EndFunc Func _Settings($hWnd, $h1, $h2, $h3, $h4, $h5) ; This function can now use these parameters as Local variables GUISetState(@SW_DISABLE, $hWnd) Local $hGUI_Settings = GUICreate("Settings", 300, 300) ; I would actually use a loop and an array here, but I have kept it simple for this demo GUIStartGroup() GUICtrlCreateLabel("Label 1 Colour", 10, 10, 200, 20) Local $hRadio_1_Red = GUICtrlCreateRadio(" Red", 10, 30, 100, 20) GUICtrlSetState(-1, $GUI_CHECKED) GUICtrlCreateRadio(" Green", 110, 30, 100, 20) GUIStartGroup() ; make each pair of radios a separater group so that you can only select one colour for each label GUICtrlCreateLabel("Label 2 Colour", 10, 60, 200, 20) Local $hRadio_2_Red = GUICtrlCreateRadio(" Red", 10, 80, 100, 20) GUICtrlSetState(-1, $GUI_CHECKED) GUICtrlCreateRadio(" Green", 110, 80, 100, 20) GUIStartGroup() GUICtrlCreateLabel("Label 3 Colour", 10, 110, 200, 20) Local $hRadio_3_Red = GUICtrlCreateRadio(" Red", 10, 130, 100, 20) GUICtrlSetState(-1, $GUI_CHECKED) GUICtrlCreateRadio(" Green", 110, 130, 100, 20) GUIStartGroup() GUICtrlCreateLabel("Label 4 Colour", 10, 160, 200, 20) Local $hRadio_4_Red = GUICtrlCreateRadio(" Red", 10, 180, 100, 20) GUICtrlSetState(-1, $GUI_CHECKED) GUICtrlCreateRadio(" Green", 110, 180, 100, 20) GUIStartGroup() GUICtrlCreateLabel("Label 5 Colour", 10, 210, 200, 20) Local $hRadio_5_Red = GUICtrlCreateRadio(" Red", 10, 230, 100, 20) GUICtrlSetState(-1, $GUI_CHECKED) GUICtrlCreateRadio(" Green", 110, 230, 100, 20) Local $hButton_Apply = GUICtrlCreateButton("Apply", 10, 260, 80, 30) GUISetState() While 1 Switch GUIGetMsg() Case $hButton_Apply ; Check which radios are set - gain a loop and array woudl be better but this is a demo If GUICtrlRead($hRadio_1_Red) = 1 Then GUICtrlSetBkColor($h1, 0xFF8080) Else GUICtrlSetBkColor($h1, 0x80FF80) EndIf If GUICtrlRead($hRadio_2_Red) = 1 Then GUICtrlSetBkColor($h2, 0xFF8080) Else GUICtrlSetBkColor($h2, 0x80FF80) EndIf If GUICtrlRead($hRadio_3_Red) = 1 Then GUICtrlSetBkColor($h3, 0xFF8080) Else GUICtrlSetBkColor($h3, 0x80FF80) EndIf If GUICtrlRead($hRadio_4_Red) = 1 Then GUICtrlSetBkColor($h4, 0xFF8080) Else GUICtrlSetBkColor($h4, 0x80FF80) EndIf If GUICtrlRead($hRadio_5_Red) = 1 Then GUICtrlSetBkColor($h5, 0xFF8080) Else GUICtrlSetBkColor($h5, 0x80FF80) EndIf ; And then exit using the same code as the real exit ContinueCase Case $GUI_EVENT_CLOSE ; Important to reenable the main GUI before deleting the child GUISetState(@SW_ENABLE, $hWnd) GUIDelete($hGUI_Settings) ExitLoop EndSwitch WEnd ; Not really necessary as the function returns automatically as the code ends Return EndFunc And not a Global variable in sight! Please ask if you have any questions - after all, the idea is that you understand! M23 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 columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
icu Posted June 27, 2011 Author Share Posted June 27, 2011 (edited) @Melba23: You're awesome! Thanks again, I'll digest it all and if I got any more questions I'll post :-) Edited June 27, 2011 by icu Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now