Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>In order to make GUI to respond to button clicks you should return control to the message loop of the window. While loop <strong>while (rs.State and (adStateConnecting+adStateExecuting+adStateFetching) &lt;> 0)</strong> does not return control back to the message loop thus blocking GUI.</p> <hr> <p>Below is an excerpt from a working Delphi code that uses asyncronous ADO queries. This code does not allow for non-modal fetching of data, but ensures that the main form is repainted during data fetch and also allows cancelling the query.</p> <p>Asynchronous execution and fetching is achieved by setting:<br> <code>FOpeningDataSet.ExecuteOptions := [eoAsyncExecute, eoAsyncFetchNonBlocking];</code> execution of query is cancelled by calling<br> <code>DataSet.Recordset.Cancel;</code><br> in <code>FetchProgress</code> event.</p> <p>Any TADODataSet shall be opened via the method:</p> <pre><code>OpenDataSetInBackground(DataSourceData.DataSet as TADODataSet); </code></pre> <p>Supporting code in the main form:</p> <pre><code>procedure TOperatorForm.OpenDataSetInBackground(DataSet: TADODataSet); begin if DataSet.Active then Exit; FOpeningDataSet := DataSet; if not FAsyncDataFetch then begin FOpeningDataSet.Open; Exit; end; FFetchCancel := False; FExecuteOptions := FOpeningDataSet.ExecuteOptions; FFetchProgress := FOpeningDataSet.OnFetchProgress; FFetchComplete := FOpeningDataSet.OnFetchComplete; FRecordsetCreate := FOpeningDataSet.OnRecordsetCreate; FAfterScroll := FOpeningDataSet.AfterScroll; FOpeningDataSet.ExecuteOptions := [eoAsyncExecute, eoAsyncFetchNonBlocking]; FOpeningDataSet.OnFetchProgress := DataSetFetchProgress; FOpeningDataSet.OnFetchComplete := DataSetFetchComplete; FOpeningDataSet.OnRecordsetCreate := DataSetRecordsetCreate; FOpeningDataSet.AfterScroll := DataSetAfterScroll; FOpeningDataSet.CursorLocation := clUseClient; FOpeningDataSet.DisableControls; try DataSetProgressForm.Left := Left + (Width - DataSetProgressForm.Width) div 2; DataSetProgressForm.Top := Top + (Height - DataSetProgressForm.Height) div 2; DataSetProgressForm.cxButton1.OnClick := DataSetProgressClick; DataSetProgressForm.cxButton1.Visible := FShowProgressCancelButton; FOpeningDataSet.Open; DataSetProgressForm.ShowModal; finally FOpeningDataSet.EnableControls; FOpeningDataSet.ExecuteOptions := FExecuteOptions; FOpeningDataSet.OnFetchProgress := FFetchProgress; FOpeningDataSet.OnFetchComplete := FFetchComplete; FOpeningDataSet.OnRecordsetCreate := FRecordsetCreate; FOpeningDataSet.AfterScroll := FAfterScroll; end; end; procedure TOperatorForm.DataSetProgressClick(Sender: TObject); begin FFetchCancel := True; end; procedure TOperatorForm.DataSetFetchProgress(DataSet: TCustomADODataSet; Progress, MaxProgress: Integer; var EventStatus: TEventStatus); begin if FFetchCancel then DataSet.Recordset.Cancel; end; procedure TOperatorForm.DataSetFetchComplete(DataSet: TCustomADODataSet; const Error: Error; var EventStatus: TEventStatus); begin PostMessage(DataSetProgressForm.Handle, WM_CLOSE, 0, 0); MessageBeep(MB_ICONEXCLAMATION); end; procedure TOperatorForm.DataSetFetchComplete(DataSet: TCustomADODataSet; const Error: Error; var EventStatus: TEventStatus); begin PostMessage(DataSetProgressForm.Handle, WM_CLOSE, 0, 0); MessageBeep(MB_ICONEXCLAMATION); end; procedure TOperatorForm.DataSetRecordsetCreate(DataSet: TCustomADODataSet; const Recordset: _Recordset); begin if Assigned(FRecordsetCreate) then FRecordsetCreate(DataSet, Recordset); end; procedure TOperatorForm.DataSetAfterScroll(DataSet: TDataSet); begin // From TBetterADODataSet 4.04 // Ole Willy Tuv's fix 03-10-00 for missing first record with TADODataSet(DataSet) do begin if (eoAsyncFetchNonBlocking in ExecuteOptions) and (Bof or Eof) and (CursorLocation = clUseClient) and (stFetching in RecordSetState) then begin if Recordset.RecordCount &gt; 0 then if Bof then Recordset.MoveFirst else if Eof then Recordset.MoveLast; CursorPosChanged; Resync([]); end; end; if Assigned(FAfterScroll) then FAfterScroll(DataSet); end; </code></pre> <p>Progress form:</p> <pre><code>unit uDataSetProgressForm; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, ExtCtrls, StdCtrls; type TDataSetProgressForm = class(TForm) AnimateProgress: TAnimate; Label1: TLabel; Bevel1: TBevel; Bevel2: TBevel; Button1: TButton; Shape1: TShape; procedure FormCreate(Sender: TObject); procedure FormShow(Sender: TObject); procedure FormHide(Sender: TObject); private { Private declarations } public { Public declarations } end; var DataSetProgressForm: TDataSetProgressForm; implementation {$R *.dfm} {$R servertimeout.res} // contains IDR_SERVAVI animation resource procedure TDataSetProgressForm.FormCreate(Sender: TObject); begin AnimateProgress.ResName := 'IDR_SERVAVI'; end; procedure TDataSetProgressForm.FormShow(Sender: TObject); begin AnimateProgress.Active := True; end; procedure TDataSetProgressForm.FormHide(Sender: TObject); begin AnimateProgress.Active := False; end; end. </code></pre> <p>and dfm</p> <pre><code>object DataSetProgressForm: TDataSetProgressForm Left = 590 Top = 497 BorderStyle = bsNone ClientHeight = 104 ClientWidth = 205 Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'MS Sans Serif' Font.Style = [] FormStyle = fsStayOnTop OldCreateOrder = False Position = poDefaultSizeOnly OnCreate = FormCreate OnHide = FormHide OnShow = FormShow DesignSize = ( 205 104) PixelsPerInch = 96 TextHeight = 13 object Bevel1: TBevel Left = 0 Top = 0 Width = 205 Height = 104 Align = alClient Style = bsRaised end object Bevel2: TBevel Left = 12 Top = 12 Width = 181 Height = 80 Anchors = [akLeft, akTop, akRight, akBottom] end object Shape1: TShape Left = 1 Top = 1 Width = 203 Height = 102 Anchors = [akLeft, akTop, akRight, akBottom] Brush.Style = bsClear Pen.Color = clWindowFrame end object AnimateProgress: TAnimate Left = 25 Top = 23 Width = 32 Height = 32 end object Label1: TLabel Left = 70 Top = 31 Width = 106 Height = 17 Hint = 'Selecting data...' Caption = 'Selecting data...' TabOrder = 1 end object Button1: TButton Left = 63 Top = 64 Width = 80 Height = 23 Caption = 'Cancel' Default = True TabOrder = 2 end end </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload