Reputation: 31
How can I stop a repeating loop in the middle of execution with pressing some button? The program only writes one letter into an edit box and then waits some given time, writes another letter and so on in a specified order, the pauses are made using sysutils.sleep
.
Example:
procedure TForm1.Button4Click(Sender: TObject);
var
j: integer;
begin
edit1.Text:='a';
edit1.Text:='a';
sysutils.Sleep(l*20);
edit1.Text:='b';
edit1.text:='3';
sysutils.sleep(l*20);
j:= 1 ;
repeat
edit1.Text:='1';
sysutils.sleep(l*2);
edit1.Text:='0';
edit1.text:='2';
sysutils.sleep(l*2);
edit1.Text:='3';
edit1.text:='4';
sysutils.sleep(l*2);
edit1.Text:='5';
sysutils.sleep(l*2);
j:= j + 1;
until j = 5;
end;
What I need: I press one button and it writes those letters, then whenever I press some other button, it stops the procedure and jumps to the other button procedures.
I know this is possible since a lot of apps can do a loop until you press something and stop a loop when you press a button, but I have no idea how to do this. Currently, the app freezes until it finishes the loop.
Upvotes: 3
Views: 4821
Reputation: 2005
Use threads as in below application. Even thought the procedure is set up to run infinitely, the GUI remains unfrozen and you can stop the procedure.
http://www.delphibasics.info/home/delphibasicssnippets/threadswithparametersexample
Upvotes: -1
Reputation: 43659
Every Windows application is message driven. The click on the button is actually a mouse click somewhere on the screen that Windows registers and translates into a message which is send to the application. The application has to process that message in order to determine its meaning before it eventually can call a procedure that will handle that mouse interaction. Your TForm1.Button4Click
routine is such a procedure. (This procedure (or method) is called an event handler. The application converts the Windows message into an event: an application is based on an event driven architecture.)
When an application 1) is executing code, it cannot process messages. The code in TForm1.Button4Click
, including all its loops, is executed in a single pass. And as long as it executes, it gives no change for the application to process another Windows message.
From Sleep
's documentation:
Suspends the execution of the current thread until the time-out interval elapses.
As you already found out yourself, Sleep
makes an application 1) unresponsive and freezes. This is simply its characteristics.
By stopping execution of code: the currently running routine has to end. Only then can an application handle and respond to user interaction.
By using something that still supports application's message and event handling, e.g. a Timer. A Timer is a component which, once Enabled
, executes its OnTimer
event handler at every passed Interval
.
Enable the Timer. At every interval, you can execute a piece of all code that is to be executed over longer time. In your case, that piece of code is setting an Edit's Text property. When multiple intervals are passed, and all code is executed, you disable the Timer.
Since the you have different waiting times and different values to be set, you must base the decision whether to update the Edit with what value on the time lapsed, or better: how many intervals have passed. Hold that count in a variable, and you're set.
1) The application's main thread.
Upvotes: 3
Reputation: 21033
As David said in his comment, you need to understand event driven programming. Very shortly said, when your program has started, it is simply waiting for events to occur. Events are e.g. button clicks, user typing something in an edit box, data is received from a comm port etc. Your job as a programmer is to write event handlers, that is, code that is triggered by these events (and hopefully does something useful).
You already have an event handler in your code, Button4Click. By your description you will also have another OnClick handler, maybe it is Button5Click. To achieve your task, you will also need a TTimer control, which has an OnTimer event. Event handlers should do as little as possible.
So, in your 'reaction game' you need three events:
In addition you need a storage for the characters to be displayed. Since you are showing single characters they can be stored in a string. If you would show strings in the edit box, you could use a TStringList as storage. To know which character to show at the next timer event you can use an integer variable as counter.
The Button4Click event handler would
The Timer1Timer event handler would
The Button5Click event handler would
Hopefully this gets you going. I did not to write any example code for you, so you can think about it yourself. But if you hit the wall, ask specific questions about your problem.
Upvotes: 5