Mehrere GUIs in Funktionen -> Problem mit Timer(?)

  • Hey,

    ich schreibe mal eine Einleitung für mein Problem
    (vielleicht teilweise überflüssig, aber zu viele Informationen können ja eigentlich nicht schaden):

    Mein Script soll sozusagen ein Hauptfenster haben, zu dem immer wieder zurückgekehrt wird. In dem Hauptfenster sind verschiedene Buttons, über die man ein jeweils anderes Fenster (das ist jeweils ein Spiel) öffnet. Wenn man also vom Hauptfenster aus ein Spiel öffnet, soll nur das Fenster des jeweiligen Spiels offen sein und das Hauptfenster nicht. Ich hoffe, das ist einigermaßen verständlich.

    Das Script ist ungefähr folgendermaßen aufgebaut:

    [autoit]

    - includes
    ...
    ...
    - globale variablen
    ...
    ...
    - aufruf der funktion main()
    - alle funktionen in Func/EndFunc tags
    ...
    ...

    [/autoit]


    Die einzelnen Funktionen, also die main()-Funktion und die Funktionen der verschiedenen Spiele, haben alle ein eigenes mit GUICreate() erstelltes Fenster, dann eben der Code und dann jeweils eine While-Schleife:

    [autoit]

    GuiSetState()

    While 1
    $msg = GUIGetMsg()
    Select
    Case $msg = $GUI_EVENT_CLOSE
    Exit
    Case $msg = $spiel3_button ;irgendwas, z.B. ein Spiel
    GUIDelete($mainGUI) ;$mainGUI ist das Hauptfenster
    spiel3()
    ;usw.
    EndSelect
    WEnd

    [/autoit]

    Wenn ich z.B. Case $msg = $spiel3_button ausführe, klappt alles noch wunderbar. Der Übergang geht problemlos und das Spiel auch. Wenn aber dann das Spiel beendet ist und ich zurück zum Hauptfenster will, klappt es einfach nicht! (Es klappt schon, wenn ich das Spiel durch die While-Schleife des Spiels verlasse, jedoch nicht bei Ablauf des Timers.)

    In z.B. dem Spiel habe ich einen Timer, den ich so erstelle:

    [autoit]

    $timeLeft = 60
    $timer = _Timer_SetTimer($gameGUI, 1000, "timerCountdown")

    [/autoit]

    Der ruft dann immer die Funktion auf:Func

    [autoit]

    timerCountdown($hWnd, $Msg, $iIDTimer, $dwTime)
    $timeLeft-=1
    GUICtrlSetData($timeLeftLabel, $timeLeft)
    If $timeLeft = 0 Then
    _Timer_KillTimer($gameGUI, $timer)
    ; HIER SPIEL BEENDEN!!
    MsgBox(0, "spiel zu ende", "diese msg box wird noch angezeigt")
    GUIDelete($gameGUI) ; wird auch noch gelöscht
    main() ; hier möchte ich einfach zurück zum Hauptfenster, klappt aber nicht
    EndIf
    EndFunc

    [/autoit]

    Bis zum Aufruf main() in der timerCountdown()-Funktion scheint alles zu klappen. Jedoch wird dann nur noch das Fenster von main() erstellt, ohne irgendwelche Controls.
    Außerdem stürzt Autoit ab. Weder Rechtsklick in der Taskleiste klappt, nocht Prozess des Scripts beenden.

    Ich muss dann über den Taskmanager Autoit komplett beenden, damit es wieder geht...

    Sorry, war vielleicht jetzt etwas lang, vergebt mir :s
    ...und bitte helft mir! Ich weiß nicht weiter

    Danke im Voraus

    EDIT: Beispielcode siehe Post #5

    3 Mal editiert, zuletzt von pete_gzome (1. Mai 2011 um 01:05)

  • GUIs muss man nicht löschen, man kann sie auch einfach verstecken ;)

    [autoit]

    GUISetState(@SW_HIDE, $hWnd)

    [/autoit]

    Ja das stimmt, habe ich auch schon ausprobiert, funktioniert aber leider nicht bei Timerablauf :(

  • Ok, habe schnell ein Beispiel mit dem problembehafteten Code zusammengeschnitten:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <StaticConstants.au3>
    #include <Timers.au3>
    #include <Misc.au3>
    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt('MustDeclareVars', 1)

    [/autoit] [autoit][/autoit] [autoit]

    Global $msg
    Global $inGame = false
    Global $mainGUI
    Global $gameGUI
    Global $playButton
    Global $timer
    Global $timeLeftLabel
    Global $timeLeft = 5

    [/autoit] [autoit][/autoit] [autoit]

    HotKeySet("{Esc}", "captureEscape")

    [/autoit] [autoit][/autoit] [autoit]

    main()

    [/autoit] [autoit][/autoit] [autoit]

    Func main()
    $inGame = false

    [/autoit] [autoit][/autoit] [autoit]

    $mainGUI = GUICreate("main", 150, 100)

    $playButton = GUICtrlCreateButton("spiel", 15, 25, 50, 35)

    GuiSetState()

    While 1
    $msg = GUIGetMsg()
    Select
    Case $msg = $GUI_EVENT_CLOSE
    Exit
    Case $msg = $playButton
    GUIDelete($mainGUI)
    $inGame = true
    spiel()
    EndSelect
    WEnd
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func spiel()
    $gameGUI = GUICreate("spiel", 300, 300)
    $timeLeftLabel = GUICtrlCreateLabel($timeLeft, 70, 100, 24, 22)

    [/autoit] [autoit][/autoit] [autoit]

    GuiSetState()

    [/autoit] [autoit][/autoit] [autoit]

    $timeLeft = 5
    $timer = _Timer_SetTimer($gameGUI, 1000, "timerCountdown")

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $msg = GUIGetMsg()
    Select
    Case $msg = $GUI_EVENT_CLOSE
    If $inGame = true Then
    $timeLeft = 5
    _Timer_KillTimer($gameGUI, $timer)
    GUIDelete($gameGUI)
    main()
    Else
    Exit
    EndIf
    EndSelect
    WEnd
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func timerCountdown($hWnd, $Msg, $iIDTimer, $dwTime)
    $timeLeft-=1
    GUICtrlSetData($timeLeftLabel, $timeLeft)
    If $timeLeft = 0 Then
    GUICtrlSetData($timeLeftLabel, "0")
    _Timer_KillTimer($gameGUI, $timer)
    MsgBox(0, "", "zu Ende")
    GUIDelete($gameGUI)
    main()
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func captureEscape()
    If $inGame = true Then
    $timeLeft = 5
    _Timer_KillTimer($gameGUI, $timer)
    GUIDelete($gameGUI)
    main()
    Else
    Exit
    EndIf
    EndFunc

    [/autoit]

    Es funktioniert fast alles, bis auf:
    Wenn man das Spiel startet und der Timer (5 Sekunden) abläuft, gelangt man zurück zuum Hauptfenster, jedoch stürzt AutoIt dann ab! Genau das ist mein Problem.

  • Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <StaticConstants.au3>
    #include <Timers.au3>
    #include <Misc.au3>
    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt('MustDeclareVars', 1)

    [/autoit] [autoit][/autoit] [autoit]

    Global $msg
    Global $inGame = False
    Global $mainGUI
    Global $gameGUI
    Global $playButton
    Global $timer
    Global $timeLeftLabel
    Global $timeLeft = 5
    Global $gameover = 0
    HotKeySet("{Esc}", "captureEscape")

    [/autoit] [autoit][/autoit] [autoit]

    main()

    [/autoit] [autoit][/autoit] [autoit]

    Func main()
    $inGame = False

    [/autoit] [autoit][/autoit] [autoit]

    $mainGUI = GUICreate("main", 150, 100)

    [/autoit] [autoit][/autoit] [autoit]

    $playButton = GUICtrlCreateButton("spiel", 15, 25, 50, 35)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $msg = GUIGetMsg()
    Select
    Case $msg = $GUI_EVENT_CLOSE
    Exit
    Case $msg = $playButton
    GUIDelete($mainGUI)
    $inGame = True
    spiel()
    EndSelect
    WEnd
    EndFunc ;==>main

    [/autoit] [autoit][/autoit] [autoit]

    Func spiel()
    $gameover = 0
    $gameGUI = GUICreate("spiel", 300, 300)
    $timeLeftLabel = GUICtrlCreateLabel($timeLeft, 70, 100, 24, 22)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    $timeLeft = 5
    $timer = _Timer_SetTimer($gameGUI, 1000, "timerCountdown")

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $msg = GUIGetMsg()
    Select
    Case $msg = $GUI_EVENT_CLOSE Or $gameover = 1
    If $inGame = True Then
    $timeLeft = 5
    _Timer_KillTimer($gameGUI, $timer)
    GUIDelete($gameGUI)
    main()
    Else
    Exit
    EndIf
    EndSelect
    WEnd
    EndFunc ;==>spiel

    [/autoit] [autoit][/autoit] [autoit]

    Func timerCountdown($hWnd, $msg, $iIDTimer, $dwTime)
    $timeLeft -= 1
    GUICtrlSetData($timeLeftLabel, $timeLeft)
    If $timeLeft = 0 Then
    GUICtrlSetData($timeLeftLabel, "0")
    _Timer_KillTimer($gameGUI, $timer)
    MsgBox(0, "", "zu Ende")
    $gameover = 1
    EndIf
    EndFunc ;==>timerCountdown

    [/autoit] [autoit][/autoit] [autoit]

    Func captureEscape()
    If $inGame = True Then
    $timeLeft = 5
    _Timer_KillTimer($gameGUI, $timer)
    GUIDelete($gameGUI)
    main()
    Else
    Exit
    EndIf
    EndFunc ;==>captureEscape

    [/autoit]
  • Jetzt stürzt AutoIt schon einmal nicht mehr ab :thumbup:

    Aber ich möchte ja auch, dass sich bei $timeLeft = 0 das Fenster schließt und man zurück zum Hauptfenster gelangt.

    Wieso geht das nicht? Wieso stürzt AutoIt ab, wenn ich in timerCountdown() nach $gameOver = 1 den Code einfüge:

    [autoit]

    GUIDelete($gameGUI)
    main()

    [/autoit]

    Großes Fragezeichen

    Edit: Ah, ich habe jetzt in spiel() in die While-Schleife folgenden Code eingebaut:

    [autoit]

    If $gameOver = 1 Then
    GUIDelete($gameGUI)
    main()
    EndIf

    [/autoit]


    und es klappt. Warum man das nicht gleich in die Funktion timerCountdown() einbauen kann, verstehe ich nicht, aber es scheint ja so jetzt so klappen

    Tausend Dank, jetzt funktioniert's!

    Einmal editiert, zuletzt von pete_gzome (1. Mai 2011 um 01:05)

  • Ach, die Zeile habe ich total übersehen... sorry :P

    Jetzt klappt alles, Dankeschön

  • Mit

    [autoit]

    GUISwitch ( winhandle [, tabitemID] )

    [/autoit]


    Könnte es auch klappen :)
    Ersten Beitrag editen -> Präfix auf [gelöst] setzen