为了加速在Delphi XE2中绘制位图,我决定采用以下方式
a)创建一个例如。 10 x线程并在线程类中仅绘制一个位图图层 b)一旦所有线程完成,使用bitblt函数逐层合并位图
我做了以下经验代码
unit Unit_BitmapThread;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Data.DB, Data.Win.ADODB, ActiveX;
type PaintBitmapThread = class(TThread)
private
FBitmap : TBitmap;
FConnection : TAdoConnection;
fserver, fdatabasename, ftablename, fsqlstr : String;
protected
procedure Execute; override;
public
constructor Create ( bmp_width, bmp_height : Integer; server, databasename, tablename, sqlstr : String; ThreadId : Integer );
destructor destroy ; override;
end;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private-Deklarationen }
FAdoConnection : TAdoConnection;
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var i : Integer;
aPaintBitmapThread : PaintBitmapThread;
begin
for i := 1 to 10 do
begin
aPaintBitmapThread :=PaintBitmapThread.Create(100,100,'server','database','table','select *',1);
end;
end;
{ PaintBitmapThread }
constructor PaintBitmapThread.Create(bmp_width, bmp_height: Integer;
server, databasename, tablename, sqlstr: String; ThreadId: Integer);
begin
FBitmap :=TBitmap.create;
FConnection :=TAdoConnection.Create(nil);
end;
destructor PaintBitmapThread.destroy;
begin
FBitmap.Free;
FConnection.Free;
inherited;
end;
procedure PaintBitmapThread.Execute;
var
ThreadQuery : TADOQuery;
k : integer;
begin
inherited;
CoInitialize(nil) ; //CoInitialize was not called
ThreadQuery := TADOQuery.Create(nil) ;
try
// ADO DB THREAD MUST USE OWN CONNECTION
ThreadQuery.Connection := FConnection;
// ThreadQuery.ConnectionString := '????';
// ThreadQuery.CursorLocation := clUseServer;
// ThreadQuery.LockType := ltReadOnly;
// ThreadQuery.CursorType := ctOpenForwardOnly;
ThreadQuery.SQL.Text := FSQLStr;
// ThreadQuery.Open;
while NOT ThreadQuery.Eof and NOT Terminated do
begin
//Canvas Does NOT Allow Drawing if not called through Synchronize
//Synchronize(RefreshCount) ;
ThreadQuery.Next;
end;
finally
ThreadQuery.Free;
end;
CoUninitialize()
end;
end.
问:a)一旦完成所有10个涂装线程,如何检测 b)如何访问线程[i]并将位图获取到主程序(VCL)进行合并?
最佳解决方案是
if Thread[1] and Thread[2] finished -> newBMP := Bitblt( bmp1, bm2);
if also Thread[3]finished -> newBMP := Bitblt( newBMP, bm3);
unit all threads-Bitmaps are merged
答案 0 :(得分:4)
a)一旦完成所有10个绘制线程,如何检测b)如何访问线程[i]并将位图获取到主程序(VCL)进行合并?
为每个线程添加OnTerminate
事件处理程序。这将在主线程上执行。合并此事件处理程序中的位图。因为它在主线程上执行,所以同步得以处理。
如果事件处理程序是线程类的方法,那么它可以访问线程的私有位图对象。
或者,如果您不想使用事件处理程序,请覆盖DoTerminate
并从那里同步合并方法。