[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Stop while loop ?

Posted on 2006-05-25
15
Medium Priority
?
316 Views
Last Modified: 2010-04-06
I have 1 button and in button click i have somthing like:

while not file eof
begin
  read file
  call procedure
end

When i click on button this loop starts. Now i want to kill this loop when i click on another button.

How can i do this ? Some boolen var and check is this var set to true in my case is not good.
0
Comment
Question by:65zgtre45rr
  • 4
  • 3
  • 2
  • +4
13 Comments
 
LVL 4

Accepted Solution

by:
BedouinDN earned 1000 total points
ID: 16766650
Best way would probably be to put that code into a thread and check for thread temination within the loop.
The second button could call terminate for the thread and you can create an OnTerminate event to perform cleanup.
0
 
LVL 12

Expert Comment

by:AmigoJack
ID: 16766656
>>How can i do this ? Some boolen var and check is this var set to true in my case is not good.<<
why not? would your loop check it not often enough?

>>to kill this loop<<
following that words exactly, you could put all your "loop"s work into a thread. and when the other button is pressed, you simply destroy that thread. to create a thread, select "file -> new -> thread" and see the delphi help, its quite simple

0
 
LVL 28

Assisted Solution

by:2266180
2266180 earned 1000 total points
ID: 16766849
something like this:

in the form declare:
  finished:boolean; (private)

the modify the loop to:
finished:=false;
while (not file eof) and (not finished)
begin
  read file
  call procedure
  application.processmessages;
end

then on the second button do:
onclickevent:
  finished:=true;

you're done.
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 

Author Comment

by:65zgtre45rr
ID: 16771053
Like i said before this is not god for my case. Never mind !
0
 
LVL 28

Expert Comment

by:2266180
ID: 16771710
1) you didn't say anything like this before.
2) if you refer to your other question with the trhead, then that is another matter. you put a question with terminating a loop and anotehr one with terminating an app. they are 2 distinct things. just that both questions were opened because of the same issue is not exactly our fault, is it now? (this is for that "never mind" thing)

I suggest you ask a question in the community support so that a moderator will either merge the 2 questions, or decrease points to one of them and make it a pointer to the other question.
0
 
LVL 3

Expert Comment

by:NetTechDude
ID: 16772977
If you have a problem clicking the 2nd Button do stop the while loop (or set a variable to make the loop stop
then consider using the call to 'Application.ProcessMessages;' inside the loop.
Then it works with a bool var that you set to true to stop the loop.

Or is there any other reason why you don't want to use a variable for that ?
You can also use Button2.Down if e.g. Button2 is of type TSpeedButton and can be set to go down (GroupIndex <> 0) and option (I don't remember the exact name) 'AllowAllUp=true' or so.
After the loop has finished, you manually set Button2.Down=false.
With this Idea, you have to use Application.ProcessMessages inside the loop, too
--NTD
0
 
LVL 17

Expert Comment

by:TheRealLoki
ID: 16785896
The way I see it, you have 2 options.

a) button1 clicking starts reading the file, and checking the boolean (that you dont want) and requires doing a "processmessages" (thus actually ALLOWING the user to click button2 to stop it)
If you don't do the processmessages, youwont be able to click on button 2 at all until the file has finished....

b) button1 starts a thread that begins reading the file. control is returned to the user, who can then happily click anything they like, including "button2" which tells the thread to terminate.

Both of these options allow the user to get control back, and they could do anything they like.
I am guessing you do not want this.
If you _only_ want the user to have the option of starting the read in, then stopping it, then you can do the folliwing :-

when you click on button1
it does a

with TForm2.Crate(application) do
try
    showmodal;
finally
    free;
end;

now "Form2" (Alt-File-New-Dialog-Standard dialog with the buttons removed) is a dialog window that takes focus (showmodal) when it is shown, it does 1 of method "A" or "B" above, but the user can only "stop" the process, they can't click anything on the main form.
This dialog window could even have a nice progress bar, or animation to amuse the user while they wait...
When the user clicks button2 or the process ends, the Form2 does a "Close" or "ModalREsult := mrOK;"
hth, Loki
0
 
LVL 3

Expert Comment

by:NetTechDude
ID: 16786653
@RealLoki: your a) is what I said 5 lines above
your b) is what BedoiunDN suggested in the very first answer.
There's some thing new to the forms idea although I don't see how the
data reading loop is terminated from the showmodal form. Have you ever tried that out ?
--NTD
0
 
LVL 17

Expert Comment

by:TheRealLoki
ID: 16786725
Not to worry NTD, I wasn't trying to claim your points.
I was trying to stress both yours and ciuly's points above. Thank me :P
and yes, using a modal form would work...
the reading code would be in the modal form.
The only reason I can see for the author not to use 1 of your solutions would be if he doesn't want the user to be able to do anything else except cancel during the read-in procedure.
That's why I added the showmodal as an option. Another option would be to "enabled := false" everything else on the form, but that's not as elegant. Hopefully he can come back with his reason why the other 2 suggestions aren't viable, and we can tackle the real issue.
0
 
LVL 3

Expert Comment

by:NetTechDude
ID: 16786817
But how do you make the reader loop stop ?
You have it inside - say Form2.OnShow - or what ? But the form won't close as long as there is running some of it's code. Thats's what makes me object.
Or have you tried that and found other outcomes ? In that case, state so and post a little real code. I'd love to hear if it worked that easy. Well - threads are easy too, but some think they'd be complicated.
--NTD
0
 
LVL 17

Expert Comment

by:TheRealLoki
ID: 16786882
the "form2" dialog would do exactly as you or ciuly suggest. It's that simple. click a cancel button...
personally, I'd probably use a message loop with A.PM, but the effect is the same.
Want me to post the code? I'd prefer to wait and see what the author wants rather than hijack his question...
0
 
LVL 17

Expert Comment

by:TheRealLoki
ID: 16840009
ok, since the author has not responded, I will post some example code :-)

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

uses unit2;

procedure TForm1.Button1Click(Sender: TObject);
var
    mresult: integer;
begin
    with TForm2.Create(self) do
    try
        mresult := ShowModal;
        if mresult = mrOK then
          memo1.Lines.Assign(Results)
        else if mresult = mrCancel then
          ShowMessage('User closed the window')
        else if mresult = mrAbort then
          ShowMessage('User clicked the cancel button')
    finally
        free;
    end;

end;

end.



****************************** 2nd form




unit Unit2;

interface

uses Windows, Messages, SysUtils, Classes, Graphics, Forms, Controls, StdCtrls,
  Buttons, ExtCtrls, ComCtrls;

const
  WM_PROCESSFILE = WM_user + 1;
  stage_Init = 0;
  stage_NextLine = 1;
type
  TForm2 = class(TForm)
    Animate1: TAnimate;
    bCancel: TButton;
    procedure bCancelClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    CancelButtonPressed: boolean;
    TextF: TextFile;
    fileisopen: boolean;
    Procedure ProcessFile(var Msg:TMessage);Message WM_PROCESSFILE;
  public
    { Public declarations }
    Results: TStringList; // the result data from reading the file. just because I don't know what you want to do with it
  end;

var
  Form2: TForm2;

implementation

{$R *.DFM}

procedure TForm2.FormCreate(Sender: TObject);
begin
    Results := TStringList.Create;
end;

procedure TForm2.FormDestroy(Sender: TObject);
begin
    animate1.Active := false;
    Results.Clear;
    Results.Free;
    if fileisopen then
      closefile(TextF);
end;

procedure TForm2.FormShow(Sender: TObject);
begin
    CancelButtonPressed := False;
    Postmessage(Handle, WM_PROCESSFILE, stage_Init, 0);
end;

procedure TForm2.bCancelClick(Sender: TObject);
begin
    CancelButtonPressed := True;
end;

procedure TForm2.ProcessFile(var Msg: TMessage);
    var
        s: string;
begin
    Application.ProcessMessages;
    case Msg.wParam of
      stage_Init:
        begin
//            assignfile(TextF, 'c:\somefile.txt');
            animate1.Active := true;
            assignfile(TextF, 'c:\temp\_syncDestination.dat');
            reset(TextF);
            fileisopen := true;
            Postmessage(Handle, WM_PROCESSFILE, stage_NextLine, 0);
        end;
      stage_NextLine:
        begin
            if CancelButtonPressed then
            begin
                CloseFile(TextF);
                fileisopen := false;
                ModalResult := mrAbort; // user aborted. note, if user closes the form, you get an mrCancel, so you can distinguish if you want
            end
            else if EOF(TextF) then
            begin
                CloseFile(TextF);
                fileisopen := false;
                ModalResult := mrOK; //succeeded
            end
            else
            begin
                ReadLn(TextF, S);
// because I do not know what you wish to do with the data, I will just store it in a stringlist
                Results.Add(S);
                sleep(500); // just a delay for testing - REMOVE ME!!!
                Postmessage(Handle, WM_PROCESSFILE, stage_NextLine, 0); // message to read next line
            end;
        end;
    end; // case
end;


end.

// just make sure form2 is NOT in ALt-Projects-Options-Auto create forms

0
 
LVL 4

Expert Comment

by:4Rabbits
ID: 16929758
(Button to Stop)
StopFlow:=True;


if StopFlow then break; //(top of your loop)

   (loop code)
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Are you ready to place your question in front of subject-matter experts for more timely responses? With the release of Priority Question, Premium Members, Team Accounts and Qualified Experts can now identify the emergent level of their issue, signal…
Screencast - Getting to Know the Pipeline
Suggested Courses

868 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question