{@abstract(FIBPlus background query)
 @author(Nikolai Voynov)
 @created(10.07.2002)
 @lastmod(01.07.2004)}
unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, Buttons, StdCtrls, Grids, DBGrids, DB, FIBDatabase,
  pFIBDatabase, FIBDataSet, pFIBDataSet;

type
  TForm2 = class(TForm)
    Panel1: TPanel;
    Panel2: TPanel;
    Panel3: TPanel;
    BitBtn1: TBitBtn;
    DBGrid1: TDBGrid;
    ds: TDataSource;
    dba: TpFIBDatabase;
    dt: TpFIBDataSet;
    tra: TpFIBTransaction;
    memSQL: TMemo;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormShow(Sender: TObject);
  private
  public
  end;

  //
  procedure ShowBackgroundQuery(FormCaption: string; Qry: String;
    DBPath, UserName, Password: string);

implementation

{$R *.dfm}

const
  cTopStart  = 100;
  cTopDelta  = 25;
  cLeftStart = 100;
  cLeftDelta = 25;

var
  FTop, FLeft, MaxTop, MaxLeft: Word;

type
  TFIBQueryThread = class(TThread)
  private
    FQuery: TpFIBDataSet;
    FDataS: TDataSource;
    FQueryException: Exception;
    procedure HookUpUI;
    procedure QueryError;
  protected
    procedure Execute; override;
  public
    constructor Create(Q: TpFIBDataSet; D: TDataSource); virtual;
  end;

procedure TForm2.FormShow(Sender: TObject);
begin
  if FLeft + cLeftDelta > MaxLeft
    then Left := cLeftStart else Left := FLeft + cLeftDelta;
  if FTop + cTopDelta > MaxTop
    then Top := cTopStart else Top := FTop + cTopDelta;
  FLeft := Left; FTop := Top;
end;

////////////////////////////////////////////////////////////////////////////////
procedure ShowBackgroundQuery(FormCaption: string; Qry: String; DBPath,
  UserName, Password: string);
begin
  with TForm2.Create(Application) do begin
    Caption := FormCaption;
    with dba do begin
      DBName := DBPath;
      DBParams.Add(Format('user_name=%s',[UserName]));
      DBParams.Add(Format('password=%s',[Password]));
      Connected := True;
    end;
    with dt do begin
      Database := dba;
      dt.Transaction := tra;
      dt.UpdateTransaction := tra;
      SelectSQL.Clear;
      SelectSQL.Text := Qry;
    end;
    memSQL.Lines.Text := Qry;
    Show;
    TFIBQueryThread.Create(dt, ds);
  end;
end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;

{ TFIBQueryThread }
////////////////////////////////////////////////////////////////////////////////
constructor TFIBQueryThread.Create(Q: TpFIBDataSet; D: TDataSource);
begin
  inherited Create(True);
  FQuery:= Q; FDataS := D;
  FreeOnTerminate := True;
  Resume;
end;

procedure TFIBQueryThread.Execute;
begin
  try
    FQuery.Open;
    Synchronize(HookUpUI);
  except
    FQueryException := ExceptObject as Exception;
    Synchronize(QueryError);
  end;
end;

procedure TFIBQueryThread.HookUpUI;
begin
  FDataS.DataSet := FQuery;
end;

procedure TFIBQueryThread.QueryError;
begin
  Application.ShowException(FQueryException);
end;

initialization
  FLeft := 100; FTop  := 100;
  MaxTop  := Screen.Height - 50;
  MaxLeft := Screen.Width  - 50;

end.
