[GUI] Start- und Stop-Button - Wie polle ich das GUI während einer Schleife?

  • Hallo zusammen,

    ich habe hier folgendes Programm gebastelt:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstants.au3>
    #include <ButtonConstants.au3>
    #include <WindowsConstants.au3>
    #include <EditConstants.au3>
    #include <Constants.au3>

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

    Global $GUI[20]

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

    $GUI[0] = GUICreate("Test", 600, 320, @DesktopWidth/2-300, @DesktopHeight/2-160, -1)
    $GUI[1] = GUICtrlCreateEdit("", 20, 20, 560, 260, $ES_READONLY + $ES_MULTILINE + $ES_AUTOVSCROLL)
    $GUI[2] = GUICtrlCreateButton("Start", 220, 290, 60, 20)
    $GUI[3] = GUICtrlCreateButton("Stop", 320, 290, 60, 20)

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

    GUISetState()

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

    $text = ""

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

    While 1
    $GUI[19] = GUIGetMsg($GUI[0])
    Select
    Case $GUI[19] = $GUI[2]
    $cmd = Run(@ComSpec & " /c ping localhost -t", @SystemDir, @SW_HIDE, $STDOUT_CHILD)
    While 1
    $line = StdoutRead($cmd)
    If @error Then ExitLoop
    $text = $text & $line
    GUICtrlSetData($GUI[1], $text)
    Sleep(500)
    WEnd
    Case $GUI[19] = $GUI[3]
    ; Programm beenden
    Case $GUI[19] = $GUI_EVENT_CLOSE
    Exit
    EndSelect
    WEnd

    [/autoit]

    Ich erhalte also ein GUI mit Edit-Feld sowie einem Start- und einem Stop-Button. Bei einem Klick auf "Start" wird ein dauerhafter Ping auf den localhost ausgeführt, dessen Output in das Edit-Feld umgeleitet wird. Funktioniert soweit gut.

    Problem: Wie bekomme ich es hin, dass das Programm bei einem Klick auf "Stop" auch stoppt (z.B. ein ProcessClose("ping.exe") o.ä. ausführt)? Denn solange ich in der WhileSchleife bin (und das soll er die ganze Zeit ja über sein), kann ich keine Ereignisse mehr pollen. Daher reagiert das GUI auch in keinster Weise auf einen Klick dieses Buttons oder des Fenster-Schließen-Buttons oben rechts.

    Über Eure Hilf würde ich mich freuen!

    Gruß
    Popopinsel

    P.S.: Ach und wie bekomme ich es hin, dass der Text im Edit-Feld automatisch zur letzten Zeile scrollt?

    Einmal editiert, zuletzt von Popopinsel (6. August 2010 um 16:30)

  • Am besten schaust du dir mal den OnEventModus an mit folgenden Befehlen

    [autoit]

    Opt("GUIOnEventMode", 1)
    GUISetOnEvent()
    GUICtrlSetOnEvent()

    [/autoit]

    Lg, Fabian

  • Hallo Popopinsel,

    herzlich willkommen im Forum nd viel Spass mit Autoit.

    Hier kannst du dir die Hilfe herunterladen.
    Hier gibt es ein AutoIt-Tutorial: http://wiki.autoit.de/wiki/index.php/TutorialSehr hilfreich ist auch das Buch von peethebee

    Das Board hat auch eine SuchFunktion (oben rechts) wenn du diese benutzt hättest wärst du auf

    [ gelöst ] Schleife beenden

    gestossen,

    Edit: dein (entsprechend abgeändertes) Skript:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstants.au3>
    #include <ButtonConstants.au3>
    #include <WindowsConstants.au3>
    #include <EditConstants.au3>
    #Include <GuiEdit.au3>
    #include <Constants.au3>

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

    Global $GUI[20]

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

    $GUI[0] = GUICreate("Test", 600, 320, @DesktopWidth / 2 - 300, @DesktopHeight / 2 - 160, -1)
    $GUI[1] = GUICtrlCreateEdit("", 20, 20, 560, 260, BitOR($ES_READONLY, $ES_MULTILINE, $ES_AUTOVSCROLL))
    $GUI[2] = GUICtrlCreateButton("Start", 220, 290, 60, 20)
    $GUI[3] = GUICtrlCreateButton("Stop", 320, 290, 60, 20)

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

    GUISetState()

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

    $text = ""

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

    While 1
    $GUI[19] = GUIGetMsg($GUI[0])
    Select
    Case $GUI[19] = $GUI[2]
    $cmd = Run("ping localhost -t", @SystemDir, @SW_HIDE, $STDOUT_CHILD)
    AdlibRegister("PingIt", 500)
    Case $GUI[19] = $GUI[3]
    PingEnde()
    Case $GUI[19] = $GUI_EVENT_CLOSE
    PingEnde()
    Exit
    EndSelect
    WEnd

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

    Func PingEnde()
    If $cmd <> 0 Then ProcessClose($cmd)
    $cmd = 0
    AdlibUnRegister("PingIt")
    EndFunc ;==>PingEnde

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

    Func PingIt()
    $line = StdoutRead($cmd)
    If Not @error Then _GUICtrlEdit_AppendText($GUI[1], $line)
    EndFunc ;==>PingIt

    [/autoit]

    mfg (Auto)Bert

    Einmal editiert, zuletzt von AutoBert (6. August 2010 um 13:30)

  • Hi,

    oder so:

    Spoiler anzeigen
    [autoit]


    While (TRUE)

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

    Switch (GUIGetMsg (FALSE))

    Case $GUI[2]

    $pid = Run("ping localhost -t", @SystemDir, @SW_HIDE, $STDOUT_CHILD)

    While (GUIGetMsg (FALSE) <> $GUI[3])

    $line = StdoutRead($cmd)
    If @error Then ExitLoop
    $text = $text & $line
    GUICtrlSetData($GUI[1], $text)
    Sleep(500)
    WEnd

    ProcessClose ($pid)

    Case $GUI_EVENT_CLOSE
    ExitLoop
    EndSwitch
    WEnd

    [/autoit]

    Gruß
    Greenhorn


  • Erstmal ein dickes Dankeschön an alle für die schnellen Antworten!

    Habe mich für die Variante mit AdlibRegister() entschieden, das ist klasse, kannte ich auch noch gar nicht! Damit wird dann quasi die Funktion innerhalb der Klammern im angegebenen Intervall aufgerufen, unabhängig davon wo sich das Hauptprogramm gerade (im Code) befindet, ja? Also die Funktion wird quasi an das Hauptprogramm angefügt, coexistent ^^

    Werd mir das dann noch so zimmern, dass der Button "Start" nach einem Klick deaktiviert wird, bis auf "Stop" geklickt wird. Sonst kann mann mit dem Start-Button zigfach die Ping.exe starten, das ist blöd. Und ich hab mir ne Funktion hier aus'm Forum geklaut (thx to blubbstar!), die die Umlaute des StdOutRead korrekt anzeigt:

    Spoiler anzeigen
    [autoit]

    Func PingIt()
    $line = StdoutRead($cmd)
    If Not @error Then _GUICtrlEdit_AppendText($GUI[1], _OEMToAnsi($line))
    EndFunc ;==>PingIt

    Func _OEMToAnsi($sOEM)
    Local $a_AnsiFName = DllCall('user32.dll', 'Int', 'OemToChar', 'str', $sOEM, 'str', '')
    If @error = 0 Then $sAnsi = $a_AnsiFName[2]
    Return $sAnsi
    EndFunc ;==>_OEMToAnsi

    [/autoit]

    P.S.: Natürlich ist das mit dem Ping nur ein Test, das Ganze wird in einem kleinen Tool Verwendung finden, mit dem ich einige Einstellungen von Windows XP (GUI, Speicherverwaltung, Dienste, etc.) automatisiert vornehmen kann (soll auf vielen Rechnern passieren). Zusätzlich werden die Temp-Ordner geleert und das Systemlaufwerk mit Defraggler (Konsolenversion) defragmentiert. Und genau hier soll der obere Kladderadatsch um StdOutRead() zum Einsatz kommen, denn ich möchte das Defrag-Programm wie den Ping im Hintergrund (unsichtbar) ausführen lassen, aber die sonst in der CMD-Shell dargestellte Fortschritssanzeige (in Prozent) darstellen lassen. Evtl. verwurste ich die Infos auch zu einer ProgressBar...

    Jedenfalls: Top Forum, so macht das Spaß! =)

  • Werd mir das dann noch so zimmern, dass der Button "Start" nach einem Klick deaktiviert wird, bis auf "Stop" geklickt wird.


    Da musst du nur diesen Bereich ändern:

    Spoiler anzeigen
    [autoit]

    GUICtrlSetState($GUI[3], $GUI_Disable) ;<===============
    While 1
    $GUI[19] = GUIGetMsg($GUI[0])
    Select
    Case $GUI[19] = $GUI[2]
    $cmd = Run("ping localhost -t", @SystemDir, @SW_DISABLE, $STDOUT_CHILD)
    GUICtrlSetState($GUI[2], $GUI_Disable) ;<===============
    GUICtrlSetState($GUI[3], $GUI_Enable) ;<===============
    AdlibRegister("PingIt", 500)
    Case $GUI[19] = $GUI[3]
    GUICtrlSetState($GUI[3], $GUI_Disable) ;<===============
    GUICtrlSetState($GUI[2], $GUI_Enable) ;<===============
    PingEnde()
    Case $GUI[19] = $GUI_EVENT_CLOSE
    PingEnde()
    Exit
    EndSelect
    WEnd

    [/autoit]

    mit ;<=============== sind die eingefügten Zeilen kenntlich gemacht

    mfg (Auto)Bert

  • autoBert

    Vielen Dank, aber damit meinte ich eigentlich, dass ich schon weiß wie das geht und es noch machen werde (bzw. bereits getan hab). Sooo unerfahren bin ich dann doch nicht, aber trotzdem danke! =)