使用工具:Delphi XE2、DBExpress、Firebird
我无法安全地在主线程之外访问任何VCL控件,包括表单、面板、编辑框等以及Timage和Timage的派生类。我需要在单独的线程(不同于主线程)中打开ClientDataSet(主/细节)。
我需要在访问数据库时创建动画闪屏。
有人能给我展示一个简单的例子吗?
使用工具:Delphi XE2、DBExpress、Firebird
我无法安全地在主线程之外访问任何VCL控件,包括表单、面板、编辑框等以及Timage和Timage的派生类。我需要在单独的线程(不同于主线程)中打开ClientDataSet(主/细节)。
我需要在访问数据库时创建动画闪屏。
有人能给我展示一个简单的例子吗?
TDataModule
中,并为每个线程访问创建此数据模块的实例。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
TClientDataSet
应该是线程本地的。同时,请记得从线程中打开一个新的数据库会话。如果您想将线程 clientdataset
中的数据传输到主线程中的某个对象,请在 Synchronize()
方法中执行此操作。 - LU RD