tags:

views:

115

answers:

3

suppose i write a button1click event handler which when called(ie when button1 clicked) keeps on adding 1 to variable counter:

var 
i : counter;
begin
while 1 = 1 do
inc(i);
end;

now i want to add another button on my form and name it ''stop'' which will abruptly exit button1click(after its called) or stop it from adding 1 to counter, how do i do that?

+2  A: 
  1. Put Application.ProcessMessages inside the while. This allows other controls to process and respond to the events.
  2. Create a global variable "Stop".
  3. In stop-button event handler, set Stop to true.
  4. Inside your while, check for the value of Stop and break if it is true.

But, it is not very good practice to do stuff like this. All things you do in form should be reponses to some events, so if you want to do some periodical things, you should use a Timer or something like that.

František Žiačik
+1 for mentioning a TTimer, which is the right way to do this.
Mason Wheeler
thanks for the answer František Žiačik. i am not really gonna use a while loop this was just for asking actually i am trying to make a download manager with pause/resume support the idea was that whenever i press a pause button my download pauses
Omair Iqbal
For that case you should have a look at threading or asynchronous requests, that's a much better approach for this kind of work.
František Žiačik
which is better threading or asynchronous requests? at this moment i know niether,what would you recommend for a begginer and which one of these two is more suited for the job
Omair Iqbal
Probably the aynchronous stuff for the beginner, does not need to care for synchronization so much. However, I'm not a delphi specialist, just my guess.
František Žiačik
+2  A: 

You can put your while in a separate thread. Simple TThread will be enough, but there are also special threading libraries like AsyncCalls or OmniThreadLibrary.

Torbins
thanks for the answer torbins. which is better tthred,asyncccalls or omnithredlibrary and i dont know much about threads so which one of these thee will be easier for a begginer
Omair Iqbal
I think you can start with TThread. Some good articles are available here: http://www.eonclash.com/Tutorials/Multithreading/MartinHarvey1.1/ToC.html
Torbins
+3  A: 

Hopefully this will provide some ideas as to how to adapt a timer based approach for your needs:

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Timer1: TTimer;  // with Interval = 1 (for example) and Enabled = FALSE
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Timer1Execute(Sender: TObject);
  private
    fCounter: Integer;
  end;



procedure TForm1.Button1Click(Sender: TObject);
begin
  Timer1.Enabled := TRUE;
end;


procedure TForm1.Button2Click(Sender: TObject);
begin
  Timer1.Enabled := FALSE;
end;


procedure TForm1.Timer1Execute(Sender: TObject);
begin
  Inc(fCounter);
end;

If your needs are more sophisticated then a TThread based approach may be more appropriate. But whatever you do, do NOT resort to Application.ProcessMessages it will only cause you grief !

Deltics
thanks for the answer deltics. 1.whats wrong with Application.ProcessMessages? 2. i am not really gonna use a while loop this was just for asking actually i am trying to make a download manager with pause resume support the idea is that whenever i press a pause button my download pauses
Omair Iqbal
When you call Application.ProcessMessage (APM) you effectively create a new message loop in your application. Your call will not return until there are no more messages to be processed, and if one of those messages is a CLICK in some other button or window in your application then control passes directly from your innocent looking APM call to that message event handler. In a nut shell, you create a potential re-entrancy issue in the VCL code in your application (unless you go to lengths to disable your UI to protect against this when calling APM).... continued
Deltics
The vast majority of uses of APM I come across are to allow GUI updating to occur while some process is underway, i.e. to process paint messages. In the VCL this is unnecessary - you can keep the UI updated as required during that processing by explicitly repainting the required controls (usually things like labels, status bar etc) with explicit calls to Update. Other scenarios where APM is invoked can typically be avoided using timers (as in this case) or threads.
Deltics
oh that sounds bad!...i thought APM is a usefull method,thanks for opening my eyes to it .application.processmessages exists in c# too(i think) is it bad idea to use it in c# too or just delphi.
Omair Iqbal