Per Button eine Schleife abbrechen?



  • Hallo liebe Programmierer!

    Ich habe eine Frage zum Programmieren... Da ich ein Programm mit einer Oberfläche programmiert habe, die auf Knopfdruck eine durch Werte in Edit1, ...2 etc. eingestellte Schleife durchläuft, möchte ich wissen wie man diese Schleife mitten im Durchlauf Ihrer selbst mittels eines zweiten Buttons abbrechen kann und ob das geht! Würde mich um schnelle Antworten freuen! 🙂

    Das soll also so wie bei der Windows-Suche funktionieren, dass man während der Suche (In meinem Fall die Schleife) abbrechen kann!

    MfG - Andy



  • Du kannst in der Schleife prüfen, ob z.B. die boolsche Variable Abbruch den Wert true hat und diese dann beenden.

    Auf Buttonclick setzt Du in diesem Fall Abbruch auf true.
    Bei dieser Variante musst Du aber ProcessMessages(Hilfe) aufrufen.

    Gruss



  • Ich vergas... Das Problem an dieser Sache ist, dass das Programm keinen Buttonklick oder sonstiges mehr akzeptiert, sobald die Schleife läuft!

    Somit ist das Programm in dem Zeitraum nur über den Taskmanager, in Windows, schließbar...

    Gibt es da eine Lösung / einen Code wie man z.B. einen Button in der Zeit trotzdem noch klickbar setzen kann?

    MfG - Andy



  • Wie gesagt: ProcessMessage()
    Frag die Hilfe mal dazu 😉



  • Solang eine Schleife durchläuft kannst du im Grunde nur schwer etwas drücken (einen Button) ...

    evtl. geht es, wenn du auf FormCreate (doppelklick auf Form) folgendes eingibst:

    ProcessMessages();
    DoubleBuffered = true;
    

    bei ProcessMessages(); bin ich mir nicht ganz sicher, schau einfach in der Hilfe nach Processmessages ...

    Gruß
    MWJK



  • @MWJK
    DoubleBuffered = true hat keinen Einfluss auf die Bearbeitung der Ereignis-Warteschleife. Und das ist an dieser Stelle der Knackpunkt. Der Button wird zwar geklickt, der Prozess ist aber mit der Schleife beschäftigt und unterbricht deshalb nicht für die Ereigniswarteschlange.
    Und wenn du ProcessMessages() in den Konstruktor schreibst, bringt das rein gar nix, ließ mal noch mal in der Hilfe nach 😉

    mfg
    xXx



  • -=]xXx[=- schrieb:

    @MWJK
    Und wenn du ProcessMessages() in den Konstruktor schreibst, bringt das rein gar nix, ließ mal noch mal in der Hilfe nach 😉

    mfg
    xXx

    Ich glaube da muss ein "Application" davor - aber ich habe ja geschrieben er soll nochmal in der Hilfe nachschauen weil ich mir nicht ganz sicher bin ...
    Lerne das ja selber erst 😉

    Gruß
    MWJK



  • Hallo DerNeueAndy
    Füge Application->ProcessMessages(); in deine Schleife ein.
    Wenn die Schleife komplizierter ist , noch einen zweiten.
    Das müsste reichen um das System aufzutauen.

    MfG Schlumpi



  • Herzlichen Dank an Euch alle! Das funktioniert soweit! Aber es hält ja nur an, wenn man ins Menü klickt etc aber nach dem Verlassen oder einem klick auf Schließen oder sonstigem geht es ja weiter... Gibt es einen Code z.B. für Button2, um die schleife oder Abarbeitung ganz zu beenden / terminieren?

    MfG - Andy



  • Du setzt die Abbruchbedingung deiner Schleife auf im Buttonklick auf true, schon wird sie abgebrochen. Wo ist das Problem?



  • Wie wärs mit break? 🙄



  • Das ist mir jetzt ein bisschen peinlich aber ich bringe mir das Programmieren im C++ Builder so gesehen selber bei, deswegen kenn ich mich nicht so sehr aus... wie kann ich denn den Button2 zu der Abbruchbedingung verlinken bzw. wie sollte ich den Code denn formulieren?

    Es handelt sich um eine FOR-Schleife!



  • for (X = 0; X < GrosseZahl; X++)
    {
      DoSomething();
      Application->ProcessMessages();
      Do EvenMore();
      Application->ProcessMessages();
      LotsMore();
    }
    
    // ButtonClick
    X = GrosseZahl;
    

    oder

    for (int i = 0; i < GrosseZahl; i++)
    {
      DoSomething();
      Application->ProcessMessages();
    
      if (Abbruch  == true)
        break;
    
      Do EvenMore();
      Application->ProcessMessages();
      LotsMore();
    }
    
    // ButtonClick
    Abbruch = true;
    


  • Es will nicht funktionieren... hier mal ein Ausschnitt aus dem Code:

    //---
    void __fastcall THauptfenster::Button1Click(TObject *Sender)
    {
     char Abbruch;
     int a = Edit1->Text.ToInt();
     int b = Edit2->Text.ToInt();
     int c = Edit3->Text.ToInt();
     int d = Edit4->Text.ToInt();
     int e = Edit5->Text.ToInt();
    
     for(int z=1;z<=e;z=z+1)
     {
      if (ComboBox1->ItemIndex == 0)
      {
       for(int y=a;y<=b;y=y+c)
       {
        Beep(y,d);
        Application->ProcessMessages();
        if (Abbruch  == true)
        break;
       }
      }
     }
    }
    
    //---
    void __fastcall THauptfenster::Button2Click(TObject *Sender)
    {
     char Abbruch;
     Abbruch = true;
    }
    


  • char ist ungünstig, nimm lieber bool.

    Dann muß die Variable natürlich Unit-weit verfügbar sein. So wie du es gemacht hast, hast Du in den zwei Funktionen jeweils eine eigenständige Variable 'Abbruch'. Die wissen von einander nichts und sind nach dem verlassen der Funktion auch nicht mehr verfügbar.

    Du mußt also in der Headerdatei des Formulars, unter private eine Variable definieren. Zum Beispiel bool Abbruch. Diese ist dann in beidem Funktionen verfügbar und kann somit in der einen gesetzt und in der anderen ausgewertet werden.
    Sinnvollerweise muß diese auch erst einmal mit false initialisiert werden. Am besten direkt vor Beginn der Schleife, sonst funktionert das entweder gar nicht, oder bestenfalls nur ein einziges Mal.



  • Danke, danke! Mit ein bisschen Überlegung ist das ja logisch... Klappt auf jeden Fall sehr gut!

    Hab noch ein Anliegen aber dazu sollte ich ein neues Posting anlegen! 🙂

    MfG - Andy


Log in to reply