Jump to content
Mbee

Problem with second GUI closure, etc.

Recommended Posts

Mbee

Okay, I've read several posts in the forum regarding not just multiple GUIs (there's an excellent tutorial on that, and I think I've followed every bit of advice there), but also other posts on problems relating to not being able to close the second GUI.  Unfortunately, I haven't been able to resolve my problem...

My app and all GUIs are using strictly Message Loop Mode with the "advanced" array return (I'm well aware that mixing msg & event modes is a common problem with "can't close second GUI" posts). But when I put up the second (it's a GUI with Radio Buttons), it is crucial to have the main app wait until the GUI is closed, so just before I create the second GUI I set a flag saying that we're waiting for the second GUI to close.  Here it is:

$G_SortDialogComplete = False
    _MyShowSortDialogGUI( "Choose the sort options for viewing This folder" )
;
    While Not $G_SortDialogComplete
        Sleep (100)         ; Pause for a tenth of a second
    WEnd
;
    _MyUpdStatusMsg("_MyProcessFolder() - Sort Dialog Complete is now True")

That part of the main message loop looks as follows...

While True
    $L_EventMsgAra = GUIGetMsg( $GUI_EVENT_ARRAY )
    $L_EventMsgCode = $L_EventMsgAra[0]
    $L_EventMsgGUIHdl = $L_EventMsgAra[1]               ; Handle to which GUI sent the message

    Switch $L_EventMsgGUIHdl                            ; If this msg is from the Main GUI...

; . . .

        Case $ChooseRadioButtonsGUI                 ; If this msg is from the Radio Button GUI...
            Switch $L_EventMsgCode
                Case $GUI_EVENT_NONE
                    ContinueLoop

                Case $GUI_EVENT_CLOSE
                    RUICloseBtnClick()

                Case $RUISortByFnameBtnID
                    SortByFnameClick()

                Case $RUISortByTimeBtnID
                    SortByTimeClick()

                Case $RUISortByExtBtnID
                    SortByExtClick()

                Case $RUISortBySizeBtnID
                    SortBySizeClick()

                Case $RUISortAscBtnID
                    SortAscendClick()

                Case $RUISortDescBtnID
                    SortDescendClick()

                Case $RUIOKBtnID
                    RUIOkBtnClick()
        EndSwitch
;
    EndSwitch

And in the RUICloseBtnClick() & RUIOkBtnClick() functions, I delete the second GUI and then set $G_SortDialogComplete = True.

BUT, those functions never appear to be called, so everything's stuck! The second GUI will not close, and the wait loop never completes!

What am I doing wrong?

Edited by Mbee

Share this post


Link to post
Share on other sites
Mbee

After explaining my problem and writing it up, upon further consideration a light dawns! How the heck could I have TWO loops running at the same time in a Message Loop app??  The main Messsage Loop -and- the wait loop for the second GUI?

I'm an idiot!  What's the best solution?

wish there was some kind of spin and wait in AutoIt akin to what you do in re-entrant code such as device drivers and the like -- in other words, a way to combine message loop mode with on event mode (which is considered verboten)?

 

Edited by Mbee

Share this post


Link to post
Share on other sites
AutoBert

All i one 'GuiGetMsg'-Loop, have a look at last example for MessageLoop Mode in the tut:https://www.autoitscript.com/wiki/Managing_Multiple_GUIs

35 minutes ago, Mbee said:

I'm well aware that mixing msg & event modes is a common problem with "can't close second GUI"

Yes it's often a problem, but it is possible. Here a small testscript:

#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode", 1)
Global $Radio1, $Radio2, $Form2
main()
Func main()
    #Region ### START Koda GUI section ### Form=
    $Form2 = GUICreate("Test", 117, 150, 302, 218)
    $Label1 = GUICtrlCreateLabel("Testmain", 32, 8, 47, 17)
    $Group1 = GUICtrlCreateGroup("Funktion", 10, 32, 97, 41)
    $Radio1 = GUICtrlCreateRadio("An", 18, 48, 41, 17)
    GUICtrlSetState(-1, $GUI_CHECKED)
    $Radio2 = GUICtrlCreateRadio("Aus", 59, 48, 41, 17)
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    $Button2 = GUICtrlCreateButton("GUI2", 18, 80, 75, 25)
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###
    GUICtrlSetOnEvent($Button2, "gui2")
    GUISetOnEvent($GUI_EVENT_CLOSE, "endmain")
    While 1
        Sleep(50)
    WEnd
EndFunc   ;==>main

Func gui2()
    $bOnEvent = Opt("GUIOnEventMode", 0)
    ;switch to  GuiGetMsg-Mode with saving mode before switching
    $Form2 = GUICreate("GUI2", 125, 206, 302, 218)
    $Label1 = GUICtrlCreateLabel("Testform2", 8, 8, 51, 17)
    $Button1 = GUICtrlCreateButton("Beenden", 24, 168, 75, 25)
    $Button2 = GUICtrlCreateButton("OK", 24, 136, 75, 25)
    $Label2 = GUICtrlCreateLabel("", 32, 80, 51, 20, $SS_SUNKEN)
    GUICtrlSetFont(-1, 10, 800, 0, "MS Sans Serif")
    GUICtrlSetColor(-1, 0x0000FF)
    $Input1 = GUICtrlCreateInput("", 24, 32, 73, 21)
    GUISetState(@SW_SHOW)

    While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
            Case $GUI_EVENT_CLOSE, $Button1, $Button2
                ExitLoop
            Case $Label2
                $neu = GUICtrlRead($Input1)
                GUICtrlSetData($Label2, $neu)
        EndSwitch
    WEnd
    GUIDelete($Form2)
    Opt("GUIOnEventMode", $bOnEvent)
    ;switch back to saved Mode
EndFunc   ;==>test2

Func endmain()
    Exit
EndFunc   ;==>endmain

 

Edited by AutoBert
  • Like 1

Share this post


Link to post
Share on other sites
Mbee

Thanks again for your kind help, AutoBert!

The last example of the multi-GUI tutorial remarks that some people call that "hybrid mode", but except for the fact that you can use the same event functions for any relevant GUI, to my eyes there's no message loop mode involved at all!  In other words, the main thing one would have to do is exclusively use On Event Mode. In my case, I'd have to rip out the message loop entirely, correct?

It's just that I initially wrote my app using stricly On Event mode in the first place, but since I couldn't get animated GIFs to animate, it looked like I needed to switch from Event Mode to Message mode to fix that!  So what you're saying is that now I need to go back to Event Mode again, right?

 

Share this post


Link to post
Share on other sites
AutoBert
5 minutes ago, Mbee said:

The last example of the multi-GUI tutorial remarks that some people call that "hybrid mode"

No i don't mean this example. I mean the last example for the MessageLoop Mode (maybe my edit was a little bit to late):

#include <GUIConstantsEx.au3>
 
 Global $hGUI2 = 9999, $hButton3 ; Predeclare the variables with dummy values to prevent firing the Case statements, only for GUI this time
 
 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)
                         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 <<<<<<<<<<<<<<<
                         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

Have you tried my Mixed-Mode script? It's just for showing it's possible, but i can't realy suggest for newbies. To make it this way a good knowing of both GUI concept's is needed.

  • Like 1

Share this post


Link to post
Share on other sites
Mbee

Thanks. Well, for now, I'm in the process of editing my code to switch back to Event Mode, but I'll eagerly read your Mixed-Mode stuff, which sounds fascinating, at a later time.  Yep, I'm all about developing my more detailed knowledge of AutoIt further, so I look forward to it!

Thanks again.

Share this post


Link to post
Share on other sites
Mbee

Hey, AutoBert, my kind friend -- You were, of course, completely right about your "mixed mode" advice. In fact, that's the only way what I needed could have been done!

I'm a bit ashamed of my "I'll get to it later" remark, since I needed your code example much more urgently than that.  Once I did as you suggested, my problem was completly solved!

So much for the common recommendation to avoid mixing Message and Event modes!  You have to be a bit careful, but that recomendation is just not true...

Share this post


Link to post
Share on other sites
AutoBert
33 minutes ago, Mbee said:

So much for the common recommendation to avoid mixing Message and Event modes!  You have to be a bit careful, but that recomendation is just not true...

Seems you are experienced enough and know the differences of both modes. But it isn't the only way the "hybrid mode" example is also a good way. The mixed mode saves time, when having existing scripts in different modes that have to combined in one script. But most other programmers looking at this script needs this (and maybe more) time to understand, so it's a good idea to use only one mode.

I like this mixed mode too but use it mostly for modal tool windows with only a few buttons and returning user choice at the end of the func.

Edited by AutoBert

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

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.