Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Abbrechen einer Schleife mit Button (https://www.delphipraxis.net/117274-abbrechen-einer-schleife-mit-button.html)

raena 15. Jul 2008 08:58


Abbrechen einer Schleife mit Button
 
Hallo,

wie kann eine Schleife durch Drücken eines Buttons abgebrochen werden?
Das Problem ist, dass während die Schleife läuft mein Stop Button garnicht akzeptiert wird!!

Vielen Dank, Raena :o

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    b_start: TButton;
    b_stop: TButton;
    procedure b_startClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.b_startClick(Sender: TObject);
begin
repeat
sleep (200);
until 1=0;
end;

end.

Forlan 15. Jul 2008 09:00

Re: Abbrechen einer Schleife mit Button
 
Klick mich!

hättest du hier erst geguckt dann wüsstest du es! :warn:

Sharky 15. Jul 2008 09:01

Re: Abbrechen einer Schleife mit Button
 
Hai raena,

zum einen solltest Du nicht Sleep verwenden sondern lieber ein Delay (funktionen dafür findest Du in der Codelibrary).
Dann musst Du in der Schleife noch dafür sorgen das die Windowsnachrichten von deinem Programm "abgerufen" werden. Also ein Delphi-Referenz durchsuchenApplication.ProcessMessages in die Schleife. Jetzt noch eine zusätzliche Variable die beim drücken des Button gesetzt wird und und in die Abbruchbedingung einbinden.

RavenIV 15. Jul 2008 09:27

Re: Abbrechen einer Schleife mit Button
 
Zitat:

Zitat von Sharky
zum einen solltest Du nicht Sleep verwenden sondern lieber ein Delay (funktionen dafür findest Du in der Codelibrary).
Dann musst Du in der Schleife noch dafür sorgen das die Windowsnachrichten von deinem Programm "abgerufen" werden. Also ein Delphi-Referenz durchsuchenApplication.ProcessMessages in die Schleife. Jetzt noch eine zusätzliche Variable die beim drücken des Button gesetzt wird und und in die Abbruchbedingung einbinden.

Das nützt alles nichts, weil der Ansatz schon falsch ist.
Überdenk doch nitte nochmal, was Du genau machen willst.

raena 15. Jul 2008 09:34

Re: Abbrechen einer Schleife mit Button
 
Hallo Forlan,

das klappt schon gut mit der ESC Taste. Die Schleife wird schön abgebrochen.
Wie kann man das jetzt mit einem Button machen oder geht das nicht?

Danke. :?:


Zitat:

Zitat von Forlan
Klick mich!

hättest du hier erst geguckt dann wüsstest du es! :warn:



Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    b_start: TButton;
    b_stop: TButton;
    procedure b_startClick(Sender: TObject);
    procedure ResetEscPressed;
    function EscPressed():Boolean;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.b_startClick(Sender: TObject);
begin
resetescpressed;
repeat
sleep (200);
until EscPressed();
end;

procedure TForm1.ResetEscPressed;
begin
  GetAsyncKeyState(VK_ESCAPE);
  GetAsyncKeyState(VK_PAUSE);
end;

function TForm1.EscPressed():Boolean;
begin
  Result := ((GetAsyncKeyState(VK_ESCAPE) and $8001) <> 0) or
    ((GetAsyncKeyState(VK_PAUSE) and $8001) <> 0);
end;
end.

Forlan 15. Jul 2008 09:39

Re: Abbrechen einer Schleife mit Button
 
Zitat:

Zitat von raena
Hallo Forlan,

das klappt schon gut mit der ESC Taste. Die Schleife wird schön abgebrochen.
Wie kann man das jetzt mit einem Button machen oder geht das nicht?

Schau dir mal die onKeyDown events an...

Z.B. ord('W') für W gedrückt etc...

Für F1 etc --> ord(VK_F1)

Für Pfeil nach oben --> ord(VK_Up)

wobei man das ord bei den VK_ Sachen glaub ich auch weglassen kann^^

raena 15. Jul 2008 09:48

Re: Abbrechen einer Schleife mit Button
 
Liste der Anhänge anzeigen (Anzahl: 1)
nö ich meine mit so einem BUTTON.

:?

Forlan 15. Jul 2008 09:50

Re: Abbrechen einer Schleife mit Button
 
Zitat:

Zitat von raena
nö ich meine mit so einem BUTTON.

:?

ach so einen button meinst du :mrgreen:

müsste das nicht über das onClick event laufen??? :gruebel:

OldGrumpy 15. Jul 2008 09:54

Re: Abbrechen einer Schleife mit Button
 
Tut es ja auch, allerdings kann der Hauptthread natürlich nur einen Eventhandler auf einmal bearbeiten, wenn man nicht so Krücken wie Application.ProcessMessages verwendet, die einem später dann immer wieder ganz derbe Probleme bringen können.

Die richtige Lösung wäre ein Workerthread, der die Arbeit tut und dem signalisiert wird, dass er abbrechen soll. Damit hätte man zum einen eine GUI die ständig auf Benutzereingaben reagiert, und zum anderen den Pfusch mit Application.ProcessMessages vermieden. Ist zwar einmal etwas Einarbeitungsaufwand, sich in das Thema Threads einzulesen, aber früher oder später kommt man eh nicht mehr darum herum. von daher: Erst gar keinen Pfusch zur Gewohnheit werden lassen, gleich richtig machen.

RavenIV 15. Jul 2008 09:56

Re: Abbrechen einer Schleife mit Button
 
Gehe ich recht in der Annahme, dass Du folgendes machen willst:
- beim Anzeigen des Forms soll eine Schleife loslaufen
- die Schliefe macht ständig irgendwelche Sachen
- wird auf dem Formular ein Button gedrückt, soll die Schleife gestoppt werden

Dann würde ich:
- in FormShow die Schleife rein setzen
- in der Schleife Application.ProcessMessages aufrufen
- dann in der Schleife die Arbeit erledigen
- weiterhin braucht man eine Member-Variable fAbbrechen: Boolean (im private-Abschnitt)
- vor der Schleife diese auf False setzen
- in ButtonClick fAbbrechen := True
- die Schleife: while not fAbbrechen do

Falls Du etwas anderes erreichen wolltest, hab ich Dich wohl falsch verstanden.
Dann musst Du es mir nochmal erläutern.

P.S. der Hinweis mit dem Thread ist absolut richtig.

raena 15. Jul 2008 09:56

Re: Abbrechen einer Schleife mit Button
 
ja schon, aber wenn die Schleife läuft reagiert der Button gar nicht
:gruebel:

RavenIV 15. Jul 2008 09:58

Re: Abbrechen einer Schleife mit Button
 
Zitat:

Zitat von raena
ja schon, aber wenn die Schleife läuft reagiert der Button gar nicht
:gruebel:

Hast Du das so umgesetzt, wie ich geschrieben habe?
Dann sollte der Button reagieren, da sorgt ProcessMessages dafür.

Oder anderst gefragt:
Was machst Du denn genau in der Schleife?

Sherlock 15. Jul 2008 10:00

Re: Abbrechen einer Schleife mit Button
 
Ist doch ganz einfach. Aus allen Antworten mal die einfachste heraussuchen und schon bekommt man
Delphi-Quellcode:
procedure TForm1.b_startClick(Sender: TObject);
begin
repeat
sleep (200);
Application.ProcesMessages;
If KnopfGedrueckt then
  Exit;
until 1=0;
end;
Und noch fix für den Knopf was gemacht:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender:TObject);
begin
  KnopfGedrueckt := True;
end;
Edit: Das ist bei weitem nicht die schönste, sicherste, eleganteste Lösung des Problems, aber ein Anfang (und vielleicht auch Ende dieses Threads ;)).

Sherlock

RavenIV 15. Jul 2008 10:08

Re: Abbrechen einer Schleife mit Button
 
Achso, jetzt hab ich's glaub ich geschnallt.

Ein Button "Start", bei dem soll die Schleife loslaufen.
Ein Button "Stop", da soll die Schleife gestoppt werden.

In ButtonStartClick:
fAbbrechen := False;
while not fAbbrechen do
begin
Application.ProcessMessages;
MachWas;
Application.ProcessMessages;
MachWasAnderes;
Application.ProcessMessages;
end;


und in ButtonStopClick:
fAbbrechen := True;

In der Zeit, wenn MachWas oder MachWasAnderes laufen, wird der Stop-Button eben nicht reagieren.

raena 15. Jul 2008 10:20

Re: Abbrechen einer Schleife mit Button
 
Ja genau RavenIV und Sherlock, das ist das was ich mir vorstellen.
Geht prinzipiell auch mit Application.ProcesMessages, das Probelm ist jetzt nur noch, dass
wenn "abbrechen" order "stop" gedrückt wurde, die Schleife nicht mehr gestartet werden kann.

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    b_start: TButton;
    b_stop: TButton;
    Memo1: TMemo;
    procedure b_startClick(Sender: TObject);
    procedure ResetEscPressed;
    function EscPressed():Boolean;
    procedure b_stopClick(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  KnopfGedrueckt:boolean;

implementation

{$R *.dfm}

procedure TForm1.b_startClick(Sender: TObject);
var i:integer;

begin
  i:=0;
  resetescpressed;
  repeat
   memo1.Text:=inttostr(i);
   inc(i);
   sleep (10);
   Application.ProcessMessages;
   until EscPressed() or KnopfGedrueckt;
   end;


procedure TForm1.ResetEscPressed;
begin
  GetAsyncKeyState(VK_ESCAPE);
  GetAsyncKeyState(VK_PAUSE);
end;

procedure TForm1.b_stopClick(Sender: TObject);
begin
  KnopfGedrueckt := True;
end;

function TForm1.EscPressed():Boolean;
begin
  Result := ((GetAsyncKeyState(VK_ESCAPE) and $8001) <> 0) or
    ((GetAsyncKeyState(VK_PAUSE) and $8001) <> 0);
end;


end.

RavenIV 15. Jul 2008 10:27

Re: Abbrechen einer Schleife mit Button
 
Zitat:

Zitat von raena
Ja genau RavenIV und Sherlock, das ist das was ich mir vorstellen.
Geht prinzipiell auch mit Application.ProcesMessages, das Probelm ist jetzt nur noch, dass
wenn "abbrechen" order "stop" gedrückt wurde, die Schleife nicht mehr gestartet werden kann.

Ich schreib mir den Wolf und nichts wird daraus gelernt :wall:

Natürlich musst Du die "Stop-Variable" auch irgendwann zurücksetzen.
Am Besten in ButtonStart.

Versuch es doch bitte Wenigstens mal mit meiner Version. :roll:

raena 15. Jul 2008 10:33

Re: Abbrechen einer Schleife mit Button
 
Hallo Raven,

ja du hast Recht. Vielen Dank, so gehts.
Die Sache mit dem Threat werde ich dann beim nächsten mal angehen wenn ich etwas
mehr fit bin. Hab nämlich Kopfschmerzen vom :wall:

Danke :hello: Raena.

Close.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:51 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz