Как открыть ClientDataSet (master / detail) в отдельном потоке (отличном от основного потока)
Использование: Delphi XE2, DBExpress, Firebird
Я не могу безопасно получить доступ к любому элементу управления VCL вне основного потока, который включает формы, панели, правки и т. д., а также потомки Timage и Timage. Мне нужно открыть ClientDataSet (Master / Detail) в отдельном потоке(отличном от основного потока).
Мне нужно создать анимированный заставочный экран при доступе к базе данных
Может ли кто-нибудь показать мне простой пример того, как это сделать?
1 ответ:
Полный пример потокового доступа к базе данных dbExpress (включая обратную связь с основным потоком) смотрите в примерах, сделанных Marco Cantù здесь: dbexpress_firebird_examples .
я предполагаю, что доступ к базе данных в потоке не представляет для вас проблемы.Он включает в себя размещение всех настроек подключения к базе данных в
TDataModuleи создание экземпляра этого datamodule для каждого потокового доступа.Так или иначе, чтобы сделать графический интерфейс информированным о фоновом процессе потока с анимированным Gif, вот пример:
unit TestAnimatedScreen; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Imaging.GIFImg, Vcl.ExtCtrls; type TMyEndNotify = procedure (value: Boolean) of object; type TMyThread = class(TThread) private fEndNotification : TMyEndNotify; procedure NotifyEndOfThread; protected procedure Execute; override; public Constructor Create(endNotification : TMyEndNotify); end; type TMainForm = class(TForm) Image1: TImage; Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } FShowAnimation : Boolean; procedure SetShowAnimation(value : Boolean); public { Public declarations } property ShowAnimation : Boolean read FShowAnimation write SetShowAnimation; end; var MainForm: TMainForm; implementation {$R *.dfm} procedure TMyThread.NotifyEndOfThread; begin if Assigned(fEndNotification) then fEndNotification(False); end; constructor TMyThread.Create(endNotification: TMyEndNotify); begin Inherited Create(false); fEndNotification := endNotification; Self.FreeOnTerminate := True; // Free automatically end; procedure TMyThread.Execute; begin try {Add your database access code here} Sleep(5000); // Simulate lengthy process finally Synchronize(NotifyEndOfThread); end; end; { TMainForm } procedure TMainForm.Button1Click(Sender: TObject); begin ShowAnimation := True; TMyThread.Create(Self.SetShowAnimation); end; procedure TMainForm.SetShowAnimation(value: Boolean); begin FShowAnimation := Value; if FShowAnimation then begin {Add animation code here} Button1.Enabled := false; Button1.Caption := 'Processing, please wait ...'; (Image1.Picture.Graphic as TGIFImage).AnimateLoop := glEnabled; (Image1.Picture.Graphic as TGIFImage).Animate := true; end else begin {Stop animation} (Image1.Picture.Graphic as TGIFImage).Animate := false; Button1.Caption := 'Start lengthy process'; Button1.Enabled := True; end; end; end.
object MainForm: TMainForm Left = 0 Top = 0 Caption = 'MainForm' ClientHeight = 265 ClientWidth = 236 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] OldCreateOrder = False PixelsPerInch = 96 TextHeight = 13 object Image1: TImage Left = 8 Top = 8 Width = 200 Height = 200 AutoSize = True IncrementalDisplay = True end object Button1: TButton Left = 8 Top = 224 Width = 200 Height = 25 Caption = 'Start lengthy process' TabOrder = 0 OnClick = Button1Click end endЕсли у вас более старая версия Delphi, чем Delphi 2007, смотрите Как использовать анимированный Gif в форме delphi для получения дополнительной информации о том, как реализовать анимированный GIF.
Анимированный GIF, который я использовал, можно найтиздесь .

Comments