Delphi please wait message with cancel button while bde query is executing

Hi,
I m having a form which executes some queries (using BDE). How can I build a message dialog to inform the user that query is executing (for example: please wait while transaction is processing, press cancel button to cancel operation).
If the user presses cancel BDE must cancel the query (if is possible).
Thank you
Yiannis81Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Geert GOracle dbaCommented:
this is only possible if you use a thread to run the query

in the thread
step 1 : create a new session to the same database (different session name)
step 2 : start the query in the thread
step 3 : when cancel is hit, kill the thread

i'll try and get you a sample
0
Geert GOracle dbaCommented:
something like this
type
  TForm1 = class(TForm)
    btnStart: TButton;
    btnCancel: TButton;
    Database1: TDatabase;
    procedure btnStartClick(Sender: TObject);
    procedure btnCancelClick(Sender: TObject);
  private
    fQueryThread: TThread;
    procedure QueryDone(Sender: TObject);
  public

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

var
  threadQueryNumber: integer;

type
  TThreadQuery = class(TThread)
  protected
    procedure Execute; override;
  public
    constructor Create(Done: TNotifyEvent); reintroduce;
  end;

{ TThreadQuery }

constructor TThreadQuery.Create(Done: TNotifyEvent);
begin
  inherited Create(False);
  OnTerminate := Done;
end;

procedure TThreadQuery.Execute;
var db: TDatabase;
begin
  Inc(threadQueryNumber);
  db := TDatabase.Create(nil);
  try
    with db do
    begin
      LoginPrompt := False;
      DatabaseName := 'Test';
      DriverName := 'Oracle';
      Params.Clear;
      Params.Add('USER NAME=DBADM');
      Params.Add('ODBC DSN=oracle');
      Params.Add('PASSWORD=xxx');
      Params.Add('DATABASE NAME=DBADM');
    end;
    db.Open;
    db.Execute('Your Query');
  finally
    db.Free;
  end;
end;

procedure TForm1.btnCancelClick(Sender: TObject);
begin
  if fQueryThread <> nil then
    TerminateThread(fQueryThread.Handle, 0);
end;

procedure TForm1.btnStartClick(Sender: TObject);
begin
  if fQueryThread = nil then
    fQueryThread := TThreadQuery.Create(QueryDone);
end;

procedure TForm1.QueryDone(Sender: TObject);
begin
  fQueryThread := nil;
end;

initialization
  threadQueryNumber := 0;

end.

Open in new window

0
senadCommented:
To cancel a queery you must kill the thread.
That is not a nice thing to do.
A better way would be to have a progress bar
showing progress.
0
Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

Geert GOracle dbaCommented:
senad ...
progress of what ?

to build something with a progress bar which actually reflects how far the query is,
is a lot more complicated

also depending on the database, you may be able to tune your query
 
0
Yiannis81Author Commented:
Ok. I understood,
so lets see the second choice: a message pop up to notify the user that application is processing.
Something like "Proccessing... please wait" while query is executing
Is there another way to do it without a message box?
0
Geert GOracle dbaCommented:
not sure if i understand

some background info to help:
there is a loop in the background (the main thread) processing all the user keyboard and mouse activities
it also takes care of drawing everything on screen
if you start a query (not in a thread), the main thread has to wait for the query to finish
so you don't get any user input, mouse input, screen drawing

for example: you start the query in the main thread (like normal) and you open notepad and put it on top of your application
then close notepad
your application will not get redrawn until the query finishes --> because the main thread is waiting to do anything until the query finishes

you can do anything before the query starts and after
but while it is running in the main thread, nothing else can happen.
0
Yiannis81Author Commented:
Say that we want to execute a query that calculates sales cost. This query runs for a couple of minutes.
1) The user presses a button to execure the query.
2) Application pop up a message (like a message box) which says "please wait while processing..."
3) Query is execures (query1.exec)
4) Execution completes (after a some minutes)
5) Pop up message closes.
0
senadCommented:
You must sometimes use bluffing (like in poker).Do some magic....
Drop a progress bar and let it spin (like its doing something).
So just after the query opens stop the progress bar.
This way user will be occupied looking at your flashy progress bar
and ... voila !he will have a good impression.
And thats what matters...
0
Geert GOracle dbaCommented:
senad,
i agree with you on this that the users need something to look at

but ... this only works if you start the query inside a thread
otherwise you progressbar will not show anything flashy at all
the main thread can only do 1 thing: run the query

if you want a messagebox:
(keep in mind that moving some other app to the foreground will mess up the display until the query is finished)




implementation

uses DBTables;

{$R *.dfm}

procedure TForm1.RunQuery;
//var q: TQuery;
begin
  //q.ExecSQL('SELECT GO_GO_GO FROM CALCULATION');
  Sleep(5000);
end;

procedure TForm1.StartQuery(Sender: TObject);
var F: TForm;
begin
  F := TForm(Sender);
  F.BringToFront;
  F.Update;
  RunQuery;
  PostMessage(F.Handle, WM_CLOSE, 0, 0);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  F: TForm;
  P: TPanel;
begin
  F := TForm.Create(Application);
  try
    F.BorderIcons := [];
    F.BorderStyle := bsNone;
    F.Position := poScreenCenter;
    P := TPanel.Create(F);
    P.Parent := F;
    P.Align := alClient;
    P.BevelInner := bvRaised;
    P.BevelOuter := bvLowered;
    P.BevelWidth := 3;
    P.Caption := 'Processing data ... Please wait ...';
    F.OnActivate := StartQuery;
    F.ShowModal;
  finally
    F.Free;
  end;
end;

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.