delphi - using windows key press to break out of loop (non keyPress event) -


using delphi 2010

hi, looking way break out of loop using key press (example 'x')

procedure tfrmmain.btnspinclick(sender: tobject);  function iscontrolkeypressed: boolean; begin   result := getkeystate(ord('x')) < 0; end;  var  productlist: tstringlist;  i, integer; begin   screen.cursor:= crhourglass;   spinning:= true;   updateall;   application.processmessages;   //create product list   productlist:= tstringlist.create;   productlist.loadfromfile(edtproductsfile.text);   progressbar1.min:= 1;   progressbar1.max:= productlist.count - 1;   //interate through product list   //skip first line (its field names) , start @ second line   i:=  1 productlist.count - 1   begin     //***************    //other code here    //***************    progressbar1.position:= progressbar1.position + 1;    ***if iscontrolkeypressed break;    application.processmessages;***   end; //for i:=  1 productlist.count - 1   productlist.clear;   productlist.free;   thesaurus.clear;   thesaurus.free;   screen.cursor:= crdefault;   spinning:= false;   updateall;   application.processmessages; end; 

move long-running code separate thread. in it, check whether flag set. when it's set, stop.

then, write onkeypress event handler form. when event handler detects magic key combination has been pressed, set flag. cause thread stop doing work.

it work this:

type   tprocessproductlistthread = class(tthread)   private     ffilename: string;     fprogressbar: tprogressbar;     fmax: integer;     procedure setprogressbarrange;     procedure incrementprogressbar;     procedure processproduct(const aproduct: string);   protected     procedure execute; override;   public     constructor create(const afilename: string; aprogressbar: tprogressbar;       onthreadterminate: tnotifyevent);   end; 

the constructor receives information need work, doesn't start doing of it. that's reserved execute method. set freeonterminate := false because main thread need continue have access thread object after it's begun running.

constructor tprocessproductlistthread.create(const afilename: string;   aprogressbar: tprogressbar; onthreadterminate: tnotifyevent); begin   inherited create(false);   ffilename := afilename;   fprogressbar := aprogressbar;   onterminate := onthreadterminate;   freeonterminate := false; end; 

your code interacts gui in couple of places. needs happen gui thread, we'll extract code separate methods can passed synchronize:

procedure tprocessproductlist.setprogressbarrange); begin   fprogressbar.min := 1;   fprogressbar.position := fprogressbar.min;   fprogressbar.max := fmax; end;  procedure tprocessproducelist.incrementprogressbar; begin   fprogressbar.position := fprogressbar.position + 1; end; 

you'll notice execute method looks similar original code. notice how uses values saved constructor.

procedure tprocessproductlist.execute; var   productlist: tstringlist;   i: integer; begin   productlist := tstringlist.create;   try     productlist.loadfromfile(ffilename);     fmax := productlist.count - 1;     synchronize(setprogressbarrange);      // skip first line (it's field names) , start @ second line     := 1 productlist.count - 1 begin       processproduct(productlist[i]);        synchronize(incrementprogressbar);       if terminated         exit;     end;       productlist.free;   end; end; 

to start thread, create this:

processthread := tprocessproductlist.create(edtproductsfile.text, progressbar1,   onprocessproductlistterminate); 

handle termination event handler below. it's stuff epilogue of original code, clears processthread; way, value can indicate whether thread still running.

procedure tform1.onprocessproductlistterminate(sender: tobject); begin   thesaurus.clear;   thesaurus.free;   updateall;   processthread := nil; end; 

remember said should set flag when key pressed? in code above, flag checks thread's own terminated property. set it, call thread's terminate method.

procedure tform1.formkeypress(sender: tobject; var key: char); begin   if char = 'x' begin     processthread.terminate;     processthread.free;     char := #0;   end; end; 

Comments

Popular posts from this blog

jquery - How can I dynamically add a browser tab? -

node.js - Getting the socket id,user id pair of a logged in user(s) -

keyboard - C++ GetAsyncKeyState alternative -