Loop Problem

  • Hallo,

    ich habe ein Problem mit meinem Loop!

    Wie kann man während eines Loop's
    einen Button anklicken.

    Hier mal mein Beispiel

    [autoit]


    #include <ButtonConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>

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

    $Form1 = GUICreate("Form1", 438, 89, 192, 132)
    $Loop = GUICtrlCreateButton("Loop-Start", 32, 24, 179, 49)
    $Loopinfo = GUICtrlCreateButton("Info", 240, 24, 179, 49)
    GUISetState(@SW_SHOW)

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

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit

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

    Case $Loop
    Page()
    Case $Loopinfo
    info()
    EndSwitch
    WEnd
    Func Page()

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

    For $i = 1 to 10
    MsgBox(0,"",$i,1)
    next

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

    EndFunc

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

    Func info()

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

    MsgBox(0,"","test",1)

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

    EndFunc

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

    ALso, zuerst Loop starten und dann den Info Button klicken.

    Geht leider nicht...

    Liebe Grüße
    Ilse ;)

    2 Mal editiert, zuletzt von Ilse (2. November 2011 um 15:15)

    • Offizieller Beitrag

    In deinem Loop den Button abfragen.
    Bei deinem Beispiel blockiert die Messagebox aber sowieso das ganze Script. Solange die Modale Messagebox offen ist, kannst du den Button nicht abfragen.

    • Offizieller Beitrag
    Zitat von meistertoggo

    alternativ zu Raupis Lösung könntest Du auch den GUIOnEventMode verwenden, da dann das Abfragen von GUIGetMsg unnötig wird.


    Das bringt dir auch nichts, damit wird der Loop auch nicht abgebrochen, der Event wird erst nach einem Loop abgearbeitet.

  • Hallo Ilse,
    alternativ zu Raupis Lösung könntest Du auch den GUIOnEventMode verwenden, da dann das Abfragen von GUIGetMsg unnötig wird.

    [autoit]

    Opt("GUIOnEventMode", 1)

    [/autoit]


    Definitiv falsch, auch beim GuiOnEventMode werden Events (Tastendruck) erst nach dem Beenden einer laufenden Func abgearbeutet, alos genau das gleiche Problem.

    hier eine Lösung im GuiGetMsg-Modus:

    Spoiler anzeigen
    [autoit]

    #include <ButtonConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>

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

    $Form1 = GUICreate("Form1", 438, 89, 192, 132)
    $Loop = GUICtrlCreateButton("Loop-Start", 32, 24, 179, 49)
    $Loopinfo = GUICtrlCreateButton("Info", 240, 24, 179, 49)
    GUISetState(@SW_SHOW)

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

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit

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

    Case $Loop
    Page()
    Case $Loopinfo
    info()
    EndSwitch
    WEnd

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

    Func Page()

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

    For $i = 1 To 10
    ConsoleWrite($i & @CRLF)
    _MySleep($i * Random(100, 999))
    Next

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

    EndFunc ;==>Page

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

    Func info()

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

    MsgBox(0, "", "test", 1)

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

    EndFunc ;==>info

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

    Func _MySleep($iMSec)
    Local $nMsg, $dt = TimerInit()
    Do
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $Loopinfo
    info()
    EndSwitch
    Sleep(10)
    Until TimerDiff($dt) > $iMSec
    EndFunc ;==>_MySleep

    [/autoit]

    Und hier das ganze im OnEventMode:

    Spoiler anzeigen
    [autoit]

    #include <ButtonConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>

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

    Opt("GUIOnEventMode", 1)

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

    $Form1 = GUICreate("Form1", 438, 89, 192, 132)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
    $Loop = GUICtrlCreateButton("Loop-Start", 32, 24, 179, 49)
    GUICtrlSetOnEvent(-1, "Page")
    $Loopinfo = GUICtrlCreateButton("Info", 240, 24, 179, 49)
    GUICtrlSetOnEvent(-1, "Info")
    GUISetState(@SW_SHOW)

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

    While 1
    Sleep(10)
    WEnd

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

    Func Page()

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

    For $i = 1 To 10
    ConsoleWrite($i & @CRLF)
    _MySleep($i * Random(100, 999))
    Next

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

    EndFunc ;==>Page

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

    Func info()

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

    MsgBox(0, "", "test", 1)

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

    EndFunc ;==>info

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

    Func _MySleep($iMSec)
    Opt("GUIOnEventMode", 0)
    Local $nMsg, $dt = TimerInit()
    Do
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $Loopinfo
    info()
    EndSwitch
    Sleep(10)
    Until TimerDiff($dt) > $iMSec
    Opt("GUIOnEventMode", 1)
    EndFunc ;==>_MySleep

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

    Func _Exit()
    Exit
    EndFunc ;==>_Exit

    [/autoit]

    Mit WM_Command könnte es evtl auch während der Anzeige einer MsgBox funktionieren, ich denke aber diese Lösung reicht aus,

    mfg autoBert

    Einmal editiert, zuletzt von autoBert (1. November 2011 um 23:19)

  • Guten Morgen zusammen,

    mußte gestern leider wieder los
    und konnte mich nicht wieder melden.

    @ Alle...Danke für die Hilfe
    und vielen Dank AutoBert für deine Lösung.


    Liebe Grüße
    Ilse ;)

  • Hallo,

    muß mich wieder melden.

    Eine Frage noch:
    Wie kann man die Geschwindigkeit des Loops
    ändern?
    Ich meine daß der Loop z.B. Sekundenweise oder alle 4 Sekunden... durchläuft.

    Wenn ich die Funktion _MySleep deaktiviere
    dann geht das. Wie kann man das in der Funktion ändern?

    [autoit]


    #include <ButtonConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>

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

    $Form1 = GUICreate("Form1", 438, 89, 192, 132)
    $Loop = GUICtrlCreateButton("Loop-Start", 32, 24, 179, 49)
    $Loopinfo = GUICtrlCreateButton("Info", 240, 24, 179, 49)
    GUISetState(@SW_SHOW)

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

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit

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

    Case $Loop
    Page()
    Case $Loopinfo
    info()
    EndSwitch
    WEnd

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

    Func Page()

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

    For $i = 1 To 10
    ;ConsoleWrite($i & @CRLF)
    _MySleep($i * Random(100, 999))
    MsgBox(0,"",$i,1)
    Next

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

    EndFunc ;==>Page

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

    Func info()

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

    MsgBox(0, "", "test", 1)

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

    EndFunc ;==>info

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

    Func _MySleep($iMSec)
    Local $nMsg, $dt = TimerInit()
    Do
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $Loopinfo
    info()
    EndSwitch
    Sleep(10)
    Until TimerDiff($dt) > $iMSec
    EndFunc ;==>_MySleep

    [/autoit]
  • Hallo Ilse,

    einfach _MySleep($iWunschZeit) die Zeit wie lange insgesamt (Falls kein Abbruch) gewartet werden soll übergeben. Ich hatte da ja einen Zufallswert eingetragen.

    meistertogo: auch HotKeys werden erst abgearbeitet wenn die MsgBox bestätigt ist, wäre in Ilses Skript ja kein Problem da ein TimeOut von 1 Sekunde gesetzt ist.

    mfg autoBert

  • Hallo AutoBert,

    schön daß du dich wieder gemeldet hast.
    Ich bin aber leider immer noch nicht am Ziel.

    Habe es so versucht:

    [autoit]


    Func Page()

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

    For $i = 1 To 10
    ;ConsoleWrite($i & @CRLF)
    _MySleep($i500)) ; hier habe ich den Wert geändert
    MsgBox(0,"",$i,1)
    Next

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

    EndFunc ;==>Page

    [/autoit]

    Danach mußte ich die Variable deklarieren

    Global $i500

    ging aber leider auch nicht.

    Muß ich auch die Funktion ändern?

    [autoit]


    Func _MySleep($iMSec)
    Local $nMsg, $dt = TimerInit()
    Do
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $Loopinfo
    info()
    EndSwitch
    Sleep(10)
    Until TimerDiff($dt) > $iMSec
    EndFunc ;==>_MySleep

    [/autoit]

    Es geht um die Schnelligkeit der Loopdurchläufe.

    Liebe Grüße
    Ilse ;)

    • Offizieller Beitrag

    Ich würde es mal mit

    [autoit]

    _MySleep(500)

    [/autoit]


    probieren ;)
    Oder du deklarierst die Variable $i500 und weist ihr auch einen Wert zu.

    [autoit]

    Global $i500 = 500

    [/autoit]


    Wenn du eine Variable ohne Wertzuweisung deklarierst, dann hat sie den Wert 0 :!:

    Btw., deine Codezeile

    [autoit]

    _MySleep($i500)) ; hier habe ich den Wert geändert

    [/autoit]


    kann gar nicht funzen, 1 mal ) zuviel und das bemängelt auch AutoIt, wenn du versuchst den Code auszuführen.

  • Hallo Raupi,

    habe das mal so eingebaut.
    Der Ablauf ist soweit in Ordnung.

    Wie kann ich aber den Loop vorzeitig beenden?

    Habe ExitLoop eingebaut, das geht aber leider nicht!

    [autoit]


    #include <ButtonConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>

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

    $Form1 = GUICreate("Form1", 438, 89, 192, 132)
    $Loop = GUICtrlCreateButton("Loop-Start", 32, 24, 179, 49)
    $Loopinfo = GUICtrlCreateButton("Info", 240, 24, 179, 49)
    GUISetState(@SW_SHOW)
    Global $i500 = 500

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

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit

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

    Case $Loop
    Page()
    Case $Loopinfo
    info()
    EndSwitch
    WEnd

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

    Func Page()

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

    For $i = 1 To 10
    ConsoleWrite($i & @CRLF)

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

    _MySleep($i500)
    Next

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

    EndFunc ;==>Page

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

    Func info()

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

    MsgBox(0, "", "test", 1)
    ;ExitLoop

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

    EndFunc ;==>info

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

    Func _MySleep($iMSec)
    Local $nMsg, $dt = TimerInit()
    Do
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $Loopinfo

    info()
    ExitLoop ; Loop verlassen klappt leider nicht!

    EndSwitch
    Sleep(10)
    Until TimerDiff($dt) > $iMSec
    EndFunc ;==>_MySleep

    [/autoit]

    Grüße ;)
    Ilse

    • Offizieller Beitrag

    Du mußt die Func _MySleep verlassen mit Return. Damit die Schleife in der Func Page abgebrochen werden kann, muß ein Rückgabewert gesetzt werden. In dem Fall die 1.
    Diese Rückgabe muß in der Func Page abgefragt werden, sonst wird bis zum Schleifenende wieder die Func _MySleep aufgerufen.

    Spoiler anzeigen
    [autoit]

    #Region - Timestamp
    ; 2011-11-03 16:31:35
    #EndRegion

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

    #include <ButtonConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>

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

    $Form1 = GUICreate("Form1", 438, 89, 192, 132)
    $Loop = GUICtrlCreateButton("Loop-Start", 32, 24, 179, 49)
    $Loopinfo = GUICtrlCreateButton("Info", 240, 24, 179, 49)
    GUISetState(@SW_SHOW)
    Global $i500 = 500

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

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit

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

    Case $Loop
    Page()
    Case $Loopinfo
    info()
    EndSwitch
    WEnd

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

    Func Page()

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

    For $i = 1 To 10
    ConsoleWrite($i & @CRLF)
    If _MySleep($i500) = 1 Then ExitLoop; _MySleep wurde aufgrund von drücvken des Loopinfobutton verlassen, Schleife abbrechen
    Next

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

    EndFunc ;==>Page

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

    Func info()

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

    MsgBox(0, "", "test", 1)
    ;ExitLoop

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

    EndFunc ;==>info

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

    Func _MySleep($iMSec)
    Local $nMsg, $dt = TimerInit()
    Do
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $Loopinfo

    info()
    Return 1; Button wurde gedrückt, Funktion mit Rückgabe 1 verlassen. Diese Rückgabe wird in deiner For Next Schleife abgefragt
    EndSwitch
    Sleep(10)
    Until TimerDiff($dt) > $iMSec
    EndFunc ;==>_MySleep

    [/autoit]