我写了下面一个线程类,该线程从数据库中取出数据,最终将取出的数据加载到主线程的一个combobox控件中。加载到combobox控件的Objects列表中是一个组件对象。在主线程中,当选择combobox控件选项时,会将该combobox控件选项包含的组件显示到窗体界面上。存在的问题是:组件显示到窗体上之后,组件内包含多个组件中的部分组件显示不正常。
如果不用多线程,直接在主线程中以相同的方式加载数据后,完全正常。 TLoadComponentThread = class(TThread)
private
ComponentList: TComboBox; InComponentList: TStringList;
ADOQuery: TADOQuery;
protected
procedure Execute; override;
destructor Destroy; override;
procedure GetComponent;
procedure SetToMainList; //将所获取到的对象列表加载至主线程的对象列表中
public
constructor Create(aComponentList: TComboBox; aConnection: TADOConnection);
end;
{ TLoadComponentThread }
constructor TLoadComponentThread.Create(aComponentList: TComboBox; aConnection: TADOConnection);
begin
InComponentList := TStringList.Create;
ADOQuery := TADOQuery.Create(nil);
ADOQuery.Connection := aConnection; ComponentList := aComponentList; FreeOnTerminate := True;
inherited Create(False);
end;destructor TLoadComponentThread.Destroy;
var
i: Integer;
begin
FreeAndNil(InComponentList);
FreeAndNil(ADOQuery);
inherited;
end;procedure TLoadComponentThread.Execute;
begin
inherited; GetComponent;
end;
//在此过程中将数据库中取出的数据加载到InComponentList
procedure TLoadComponentThread.GetComponent;
var
i: Integer;
BlobStream: TADOBlobStream;
aHouse: TComponentHouse;
begin
//获取数据
ADOQuery.SQL.Text := 'SELECT * FROM S_Component';
if ADOQuery.Active then ADOQuery.Close;
ADOQuery.Open; //将数据库中取出的数据加载到InComponentList
for i := 0 to ADOQuery.RecordCount - 1 do
begin
if Terminated then Exit;
//此处的'COMPONENT'字段保存了一个Panel组件,该Panel组件上有若干Panel或Image组件
BlobStream := TADOBlobStream.Create(TBlobField(ADOQuery.FieldByName('COMPONENT')), bmRead);
try
aHouse := BlobStream.ReadComponent(aHouse) as TComponentHouse;
aHouse.BindEven;
InComponentList.AddObject(aHouse.ComponentHouseName, aHouse);
aHouse := nil;
finally
BlobStream.Free;
end; ADOQuery.Next;
end; Synchronize(SetToMainList) ;
end;//将InComponentList中的数据转移到主线程的ComponentList
procedure TLoadComponentThread.SetToMainList;
var
i: Integer;
begin
for i := 0 to InComponentList.Count - 1 do
begin
if Terminated then Exit; ComponentList.Items.AddObject(InComponentList.Strings[i], (InComponentList.Objects[i] as TComponentHouse));
FToMainIndex := i;
end;
end;
如果不用多线程,直接在主线程中以相同的方式加载数据后,完全正常。 TLoadComponentThread = class(TThread)
private
ComponentList: TComboBox; InComponentList: TStringList;
ADOQuery: TADOQuery;
protected
procedure Execute; override;
destructor Destroy; override;
procedure GetComponent;
procedure SetToMainList; //将所获取到的对象列表加载至主线程的对象列表中
public
constructor Create(aComponentList: TComboBox; aConnection: TADOConnection);
end;
{ TLoadComponentThread }
constructor TLoadComponentThread.Create(aComponentList: TComboBox; aConnection: TADOConnection);
begin
InComponentList := TStringList.Create;
ADOQuery := TADOQuery.Create(nil);
ADOQuery.Connection := aConnection; ComponentList := aComponentList; FreeOnTerminate := True;
inherited Create(False);
end;destructor TLoadComponentThread.Destroy;
var
i: Integer;
begin
FreeAndNil(InComponentList);
FreeAndNil(ADOQuery);
inherited;
end;procedure TLoadComponentThread.Execute;
begin
inherited; GetComponent;
end;
//在此过程中将数据库中取出的数据加载到InComponentList
procedure TLoadComponentThread.GetComponent;
var
i: Integer;
BlobStream: TADOBlobStream;
aHouse: TComponentHouse;
begin
//获取数据
ADOQuery.SQL.Text := 'SELECT * FROM S_Component';
if ADOQuery.Active then ADOQuery.Close;
ADOQuery.Open; //将数据库中取出的数据加载到InComponentList
for i := 0 to ADOQuery.RecordCount - 1 do
begin
if Terminated then Exit;
//此处的'COMPONENT'字段保存了一个Panel组件,该Panel组件上有若干Panel或Image组件
BlobStream := TADOBlobStream.Create(TBlobField(ADOQuery.FieldByName('COMPONENT')), bmRead);
try
aHouse := BlobStream.ReadComponent(aHouse) as TComponentHouse;
aHouse.BindEven;
InComponentList.AddObject(aHouse.ComponentHouseName, aHouse);
aHouse := nil;
finally
BlobStream.Free;
end; ADOQuery.Next;
end; Synchronize(SetToMainList) ;
end;//将InComponentList中的数据转移到主线程的ComponentList
procedure TLoadComponentThread.SetToMainList;
var
i: Integer;
begin
for i := 0 to InComponentList.Count - 1 do
begin
if Terminated then Exit; ComponentList.Items.AddObject(InComponentList.Strings[i], (InComponentList.Objects[i] as TComponentHouse));
FToMainIndex := i;
end;
end;
解决方案 »
- [讨论] 金山T盘客户pc端能实现不用验证码登录软件,用delphi能实现吗 附件为金山T盘软件,要求提供delphi实现主要代码,WEB调用的话不行
- delphi现在是不是不能用indy控件开发邮件发送系统了?
- 请教:关于软件的重装打开问题?
- 问一问,帮帮忙
- 麻烦各位大哥推荐几本好的DELPHI(或者VC也行)网络编程(涉及讨论TCP协议)的书籍(如果是可以下载的电子书就更好喽,呵呵)..
- 如何改变文件的默认保存路径
- 有关记录的长度问题
- Install Shield安装问题
- 用wise9.01打包安装后,程序路径放在注册表。问题是:路径总是被截短,如:D:\Program Files\ECSMS变成D:\Progar~1\ECSMS,为何?郁闷!
- 谁能告诉我那里有delphiX的中文资料
- 请问Tchart的Series的数据源为函数时的用法
- 有关字符串内存复制问题
具体可以看delphi自带的demo
而只是个别image控件显示不正常,比如一个Panel组件上有四个子Panel组件,每个子Panel上有五个Image组件,总共4×5=20个image中有一二个显示不正常 ,所以我无法通过设断点来看到是否加载完全。
begin
inherited; Synchronize(GetComponent); // 就同步他
end; 或者:FreeOnTerminate := flase;
同 數據加載後完再關閉這個線程。