您的位置:首页 > 编程语言 > Delphi

经过两周时间解决的多线程绘图代码,圆满解决delphi组件不能在多线程画曲线问题

2011-12-01 10:34 519 查看
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,ExtCtrls, StdCtrls,unit2,math,th1,th2, iComponent, iVCLComponent,
iCustomComponent, iPlotComponent, iXYPlot, TeEngine, Series, TeeProcs,
Chart;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Image1: TImage;
Image2: TImage;
Timer1: TTimer;
Edit4: TEdit;
Edit5: TEdit;
Button6: TButton;
Timer2: TTimer;
Edit6: TEdit;
Edit7: TEdit;
Button7: TButton;
Button8: TButton;
Label1: TLabel;
iXYPlot1: TiXYPlot;
iXYPlot2: TiXYPlot;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure Button6Click(Sender: TObject);
procedure Timer2Timer(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button7Click(Sender: TObject);
procedure Button8Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;
shuju = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
public
end;
var
Form1: TForm1;
thd1:test1;
thd2:test2;
shujucaiji:shuju ;
// th2:Tbal;
shu1,shu2:Real;
bb:Boolean ;

implementation
function Mydraw(p: Pointer): Integer; stdcall;
// var
// maxnj,maxjd:real;
// dvol1,djd:real;
// imag:TPaintBox ;
begin
// imag:=Form1.PaintBox1;

while bb do

//setviewportorgex(imag.Canvas.Handle,imag.Width div 2,imag.Height div 2,nil);
begin
// plotline(form1.Image2,shu1,shu2);
// maxnj:=30;
// maxjd:=6;
// dvol1:=shu1;
// djd:=shu2;
// imag.Canvas.Pen.Style:=pssolid; //边线
// imag.Canvas.pen.Color:=clred;
// imag.Canvas.font.Size:=8;
// //image1.Canvas.moveto(trunc(djd*(image1.Width div 2-40)/maxnj),-trunc(dvol1*(image1.Height div 2-40)/maxjd));
// imag.Canvas.lineto(trunc(dvol1*(imag.Width div 2-40)/maxnj),-trunc(djd*(imag.Height div 2-40)/maxjd));
// imag.Canvas.moveto(trunc(dvol1*(imag.Width div 2-40)/maxnj),-trunc(djd*(imag.Height div 2-40)/maxjd));
//

Form1.Edit3.Text :=FloatToStr(shu1) ;
//Application.MessageBox('', '', MB_OK);

end;
Result := 0;
end;
{$R *.dfm}

{ Tball }
procedure shuju.Execute;
begin
FreeOnTerminate :=true; //设置线程终止许可
repeat
Randomize;
shu1:=( shu1+0.005)*randg(1,0.0001);
shu2:=( shu2+0.009)*randg(1,0.0001);
if (shu1>30) or (shu1<-30.0) then shu1:=0;
if (shu2>6.0) or (shu2<-6.0) then shu2:=0;
until Terminated; // 如果Terminated属性为True,则终止n

end;

procedure TForm1.Button1Click(Sender: TObject);
var
ThreadId1, ThreadId2: THandle ;
id:DWORD;
begin
Draw(image1);
iXYPlot1.ClearAllData;
thd1:=test1.Create();
thd1.Resume ;

end;

procedure TForm1.Button2Click(Sender: TObject);
begin
Daw(image2);
iXYPlot2.ClearAllData;
thd2:=test2.Create();
thd2.Resume ;
end;

{ Tbal }

procedure TForm1.FormCreate(Sender: TObject);
begin

shujucaiji:=shuju.Create(False ); //数据采集线程启动
Dw(image2);
Dw(image1);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Edit1 .Text :=FormatFloat('0.00',shu1);
Edit2 .Text :=FormatFloat('0.00',shu2);

end;

procedure TForm1.Button6Click(Sender: TObject);
var
bit: TBitmap;
begin
bit := TBitmap.Create;
bit.Width := Width;
bit.Height := Height;
BitBlt(bit.Canvas.Handle, 0, 0, Width, Height, GetWindowDC(Handle), 0, 0, SRCCOPY);
bit.SaveToFile('c:\Form1.bmp');
bit.Free;

end;

procedure TForm1.Timer2Timer(Sender: TObject);
begin
plotline(Image1,shu1,shu2);
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
Draw(Image1);
Timer2.Enabled :=True;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
Timer2.Enabled :=False ;
plotfree;
end;

procedure TForm1.Button7Click(Sender: TObject);
begin
if thd1<>nil then
thd1.Terminate ;
thd1:=nil;
end;

procedure TForm1.Button8Click(Sender: TObject);
begin
if thd2<>nil then
thd2.Terminate ;
thd2:=nil;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if thd1<>nil then
thd1.Terminate ;
thd1:=nil;
if thd2<>nil then
thd2.Terminate ;
thd2:=nil;
end;

end.

unit Unit2;

interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,ExtCtrls;
procedure Dw(ige:TImage );
procedure Draw(imag:TImage );
procedure plotline(imag:TImage;dvol1,djd:real);
procedure plotfree;
/////////////////////////////////////////////////////
procedure Daw(imag:TImage );
procedure ploline(imag:TImage;dvol1,djd:real);
procedure plofree;
var
image:TBitmap;
mage:TBitmap;
implementation
uses Unit1;

procedure Draw(imag:TImage); //绘制曲线,扭矩和角度的关系坐标
var
I:Integer;
maxnj,maxjd:real;
begin
image:=TBitmap.Create;
image.Height:=imag.Height ;
image.Width:=imag.Width;
image.PixelFormat:= pf24bit ;
maxnj:=30; //X轴数值
maxjd:=6; //Y轴数值
image.Canvas.Brush.Color :=$32CD9A;
image.Canvas.FillRect(Rect(0, 0, image.Width, image.Height ));
setviewportorgex(image.Canvas.Handle,image.Width div 2,image.Height div 2,nil); //API函数设置原点
with image.Canvas do
begin
//////////////////////////////////////////////////////////////
//波浪网格线
pen.Style:=PsDot;
pen.Color:=clgray;
font.Name:='Arial';
font.Size:=6;
for i:=0 to 19 do
begin
moveto(-image.Width div 2+40+trunc(i*(image.Width-80)/20),image.Height div 2-40);
lineto(-image.Width div 2+40+trunc(i*(image.Width-80)/20),-image.Height div 2+40);
end;

for i:=0 to 19 do
begin
moveto(image.Width div 2-40,-image.Height div 2+40+trunc(i*(image.Height-80)/20));
lineto(-image.Width div 2+40,-image.Height div 2+40+trunc(i*(image.Height-80)/20));
end;
////////////////////////////////////////////////////////////
Pen.Style:=pssolid; //边线
pen.Color:=clblack;
font.Size:=8;
textout(-textwidth('角度关系曲线') div 2,image.Height div 2-30, '角度关系曲线');

Pen.Style:=pssolid; //边线
pen.Color:=clblack;
font.Size:=8;

moveto(0,image.Height div 2-40); //X轴
lineto(0,-image.Height div 2+40);
moveto(-image.Width div 2+40,0); //Y轴
lineto(image.Width div 2-40,0);
//四边围线
moveto(-image.Width div 2+40,image.Height div 2-40);
lineto(image.Width div 2-40,image.Height div 2-40);
lineto(image.Width div 2-40,-image.Height div 2+40);
lineto(-image.Width div 2+40,-image.Height div 2+40);
lineto(-image.Width div 2+40,image.Height div 2-40);

textout(image.Width div 2-90,-5-textheight('扭'), '角度');
textout(5,-image.Height div 2+42, '电');
textout(5,-image.Height div 2+55, '压');
// textout(5,-image1.Height div 2+68, '分');

pen.Style:=pssolid;
pen.Color:=clBlack;
font.Name:='Arial';
font.Size:=6;

textout(2,2,'0');

for i:=0 to 19 do
begin
moveto(-image.Width div 2+40+trunc(i*(image.Width-80)/20),0);
lineto(-image.Width div 2+40+trunc(i*(image.Width-80)/20),-5);

if (i<10) and (i<>0) then
textout(-image.Width div 2+40+trunc(i*(image.Width-80)/20)-textwidth('00') div 2,2,formatfloat('0.0',maxnj*(i-10)*0.1));
if (i>10) and (i<>20) then
textout(-image.Width div 2+40+trunc(i*(image.Width-80)/20)-textwidth('00') div 2,2,formatfloat('0.0',(i-10)*maxnj*0.1));
end;

for i:=0 to 19 do
begin
moveto(0,-image.Height div 2+40+trunc(i*(image.Height-80)/20));
lineto(5,-image.Height div 2+40+trunc(i*(image.Height-80)/20));

if (i<10) and (i<>0) then
textout(-5-textwidth('-1.0'),-image.Height div 2+40+trunc(i*(image.Height-80)/20)-textheight('-1.0') div 2,formatfloat('0.0',maxjd*0.1*(10-i)));
if (i>10) and (i<>20) then
textout(-5-textwidth('-1.0'),-image.Height div 2+40+trunc(i*(image.Height-80)/20)-textheight('-1.0') div 2,formatfloat('0.0',maxjd*0.1*(10-i)));
end;
pen.Color:=clblack;
pen.Color:=clblue;
end;
setviewportorgex(image.Canvas.Handle,image.Width div 2,image.Height div 2,nil);
image.Canvas.moveto(0,0);
imag.Picture.Bitmap:=image;
image.SaveToFile('c:\Form1.bmp');
end;

procedure plotline(imag:TImage;dvol1,djd:real); //绘制曲线,扭矩和角度的关系
var
maxnj,maxjd:real;
begin
setviewportorgex(image.Canvas.Handle,image.Width div 2,image.Height div 2,nil);
maxnj:=30;
maxjd:=6;
image.Canvas.Pen.Style:=pssolid; //边线
image.Canvas.pen.Color:=clred;
image.Canvas.font.Size:=8;
image.Canvas.lineto(trunc(dvol1*(image.Width div 2-40)/maxnj),-trunc(djd*(image.Height div 2-40)/maxjd));
image.Canvas.moveto(trunc(dvol1*(image.Width div 2-40)/maxnj),-trunc(djd*(image.Height div 2-40)/maxjd));
imag.Picture.Bitmap:=image;
end;

procedure plotfree;
begin
image.Free
end;
/////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
procedure Daw(imag:TImage); //绘制曲线,扭矩和角度的关系坐标
var
I:Integer;
maxnj,maxjd:real;
begin
mage:=TBitmap.Create;
mage.Height:=imag.Height ;
mage.Width:=imag.Width;
mage.PixelFormat:= pf24bit ;
maxnj:=30; //X轴数值
maxjd:=6; //Y轴数值
mage.Canvas.Brush.Color := $32CD9A;
mage.Canvas.FillRect(Rect(0, 0, mage.Width, mage.Height ));
setviewportorgex(mage.Canvas.Handle,mage.Width div 2,mage.Height div 2,nil); //API函数设置原点
with mage.Canvas do
begin
//////////////////////////////////////////////////////////////
//波浪网格线
pen.Style:=PsDot;
pen.Color:=clgray;
font.Name:='Arial';
font.Size:=6;
for i:=0 to 19 do
begin
moveto(-mage.Width div 2+40+trunc(i*(mage.Width-80)/20),mage.Height div 2-40);
lineto(-mage.Width div 2+40+trunc(i*(mage.Width-80)/20),-mage.Height div 2+40);
end;

for i:=0 to 19 do
begin
moveto(mage.Width div 2-40,-mage.Height div 2+40+trunc(i*(mage.Height-80)/20));
lineto(-mage.Width div 2+40,-mage.Height div 2+40+trunc(i*(mage.Height-80)/20));
end;
////////////////////////////////////////////////////////////
Pen.Style:=pssolid; //边线
pen.Color:=clblack;
font.Size:=8;
textout(-textwidth('角度关系曲线') div 2,mage.Height div 2-30, '角度关系曲线');

Pen.Style:=pssolid; //边线
pen.Color:=clblack;
font.Size:=8;

moveto(0,mage.Height div 2-40); //X轴
lineto(0,-mage.Height div 2+40);
moveto(-mage.Width div 2+40,0); //Y轴
lineto(mage.Width div 2-40,0);
//四边围线
moveto(-mage.Width div 2+40,mage.Height div 2-40);
lineto(mage.Width div 2-40,mage.Height div 2-40);
lineto(mage.Width div 2-40,-mage.Height div 2+40);
lineto(-mage.Width div 2+40,-mage.Height div 2+40);
lineto(-mage.Width div 2+40,mage.Height div 2-40);

textout(mage.Width div 2-90,-5-textheight('扭'), '角度');
textout(5,-mage.Height div 2+42, '电');
textout(5,-mage.Height div 2+55, '压');
// textout(5,-image1.Height div 2+68, '分');

pen.Style:=pssolid;
pen.Color:=clBlack;
font.Name:='Arial';
font.Size:=6;

textout(2,2,'0');

for i:=0 to 19 do
begin
moveto(-mage.Width div 2+40+trunc(i*(mage.Width-80)/20),0);
lineto(-mage.Width div 2+40+trunc(i*(mage.Width-80)/20),-5);

if (i<10) and (i<>0) then
textout(-mage.Width div 2+40+trunc(i*(mage.Width-80)/20)-textwidth('00') div 2,2,formatfloat('0.0',maxnj*(i-10)*0.1));
if (i>10) and (i<>20) then
textout(-mage.Width div 2+40+trunc(i*(mage.Width-80)/20)-textwidth('00') div 2,2,formatfloat('0.0',(i-10)*maxnj*0.1));
end;

for i:=0 to 19 do
begin
moveto(0,-mage.Height div 2+40+trunc(i*(mage.Height-80)/20));
lineto(5,-mage.Height div 2+40+trunc(i*(mage.Height-80)/20));

if (i<10) and (i<>0) then
textout(-5-textwidth('-1.0'),-mage.Height div 2+40+trunc(i*(mage.Height-80)/20)-textheight('-1.0') div 2,formatfloat('0.0',maxjd*0.1*(10-i)));
if (i>10) and (i<>20) then
textout(-5-textwidth('-1.0'),-mage.Height div 2+40+trunc(i*(mage.Height-80)/20)-textheight('-1.0') div 2,formatfloat('0.0',maxjd*0.1*(10-i)));
end;
pen.Color:=clblack;
pen.Color:=clblue;
end;
setviewportorgex(mage.Canvas.Handle,mage.Width div 2,mage.Height div 2,nil);
mage.Canvas.moveto(0,0);
imag.Picture.Bitmap:=mage;
// mage.SaveToFile('c:\Form1.bmp');
end;

procedure ploline(imag:TImage;dvol1,djd:real); //绘制曲线,扭矩和角度的关系
var
maxnj,maxjd:real;
begin
setviewportorgex(mage.Canvas.Handle,mage.Width div 2,mage.Height div 2,nil);
maxnj:=30;
maxjd:=6;
mage.Canvas.Pen.Style:=pssolid; //边线
mage.Canvas.pen.Color:=clred;
mage.Canvas.font.Size:=8;
mage.Canvas.lineto(trunc(dvol1*(mage.Width div 2-40)/maxnj),-trunc(djd*(mage.Height div 2-40)/maxjd));
mage.Canvas.moveto(trunc(dvol1*(mage.Width div 2-40)/maxnj),-trunc(djd*(mage.Height div 2-40)/maxjd));
imag.Picture.Bitmap:=mage;
end;

procedure plofree;
begin
mage.Free
end;
procedure Dw(ige:TImage); //绘制曲线,扭矩和角度的关系坐标
var
I:Integer;
maxnj,maxjd:real;
begin
maxnj:=30; //X轴数值
maxjd:=6; //Y轴数值
ige.Canvas.Brush.Color :=$32CD9A;
ige.Canvas.FillRect(Rect(0, 0, ige.Width, ige.Height ));
setviewportorgex(ige.Canvas.Handle,ige.Width div 2,ige.Height div 2,nil); //API函数设置原点
with ige.Canvas do
begin
//////////////////////////////////////////////////////////////
//波浪网格线
pen.Style:=PsDot;
pen.Color:=clgray;
font.Name:='Arial';
font.Size:=6;
for i:=0 to 19 do
begin
moveto(-ige.Width div 2+40+trunc(i*(ige.Width-80)/20),ige.Height div 2-40);
lineto(-ige.Width div 2+40+trunc(i*(ige.Width-80)/20),-ige.Height div 2+40);
end;

for i:=0 to 19 do
begin
moveto(ige.Width div 2-40,-ige.Height div 2+40+trunc(i*(ige.Height-80)/20));
lineto(-ige.Width div 2+40,-ige.Height div 2+40+trunc(i*(ige.Height-80)/20));
end;
////////////////////////////////////////////////////////////
Pen.Style:=pssolid; //边线
pen.Color:=clblack;
font.Size:=8;
textout(-textwidth('角度关系曲线') div 2,ige.Height div 2-30, '角度关系曲线');

Pen.Style:=pssolid; //边线
pen.Color:=clblack;
font.Size:=8;

moveto(0,ige.Height div 2-40); //X轴
lineto(0,-ige.Height div 2+40);
moveto(-ige.Width div 2+40,0); //Y轴
lineto(ige.Width div 2-40,0);
//四边围线
moveto(-ige.Width div 2+40,ige.Height div 2-40);
lineto(ige.Width div 2-40,ige.Height div 2-40);
lineto(ige.Width div 2-40,-ige.Height div 2+40);
lineto(-ige.Width div 2+40,-ige.Height div 2+40);
lineto(-ige.Width div 2+40,ige.Height div 2-40);

textout(ige.Width div 2-90,-5-textheight('扭'), '角度');
textout(5,-ige.Height div 2+42, '电');
textout(5,-ige.Height div 2+55, '压');
// textout(5,-image1.Height div 2+68, '分');

pen.Style:=pssolid;
pen.Color:=clBlack;
font.Name:='Arial';
font.Size:=6;

textout(2,2,'0');

for i:=0 to 19 do
begin
moveto(-ige.Width div 2+40+trunc(i*(ige.Width-80)/20),0);
lineto(-ige.Width div 2+40+trunc(i*(ige.Width-80)/20),-5);

if (i<10) and (i<>0) then
textout(-ige.Width div 2+40+trunc(i*(ige.Width-80)/20)-textwidth('00') div 2,2,formatfloat('0.0',maxnj*(i-10)*0.1));
if (i>10) and (i<>20) then
textout(-ige.Width div 2+40+trunc(i*(ige.Width-80)/20)-textwidth('00') div 2,2,formatfloat('0.0',(i-10)*maxnj*0.1));
end;

for i:=0 to 19 do
begin
moveto(0,-ige.Height div 2+40+trunc(i*(ige.Height-80)/20));
lineto(5,-ige.Height div 2+40+trunc(i*(ige.Height-80)/20));

if (i<10) and (i<>0) then
textout(-5-textwidth('-1.0'),-ige.Height div 2+40+trunc(i*(ige.Height-80)/20)-textheight('-1.0') div 2,formatfloat('0.0',maxjd*0.1*(10-i)));
if (i>10) and (i<>20) then
textout(-5-textwidth('-1.0'),-ige.Height div 2+40+trunc(i*(ige.Height-80)/20)-textheight('-1.0') div 2,formatfloat('0.0',maxjd*0.1*(10-i)));
end;
pen.Color:=clblack;
pen.Color:=clblue;
end;
end;

end.

unit th1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,ExtCtrls,unit2;

type
test1 = class(TThread)
private
{ Private declarations }
FImg:TImage;
FVmax,FVmin:Real; //曲线绘图区域的最大值和最小值
protected
procedure Execute; override;
procedure Exe;
public
Constructor Create();
end;

implementation

uses Unit1;

{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,

Synchronize(UpdateCaption);

and UpdateCaption could look like,

procedure test1.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }

{ test1 }

constructor test1.Create;
begin
Inherited Create(true);
end;

procedure test1.Exe;
begin
plotline(form1.Image1,shu1,shu2);
Form1.iXYPlot1.Channel[0].AddXY(shu1,shu2);
// Form1.Chart1.Series[0].AddXY(shu1,shu2);
Form1.Edit4 .Text :=FormatFloat('0.00',shu1);
form1. Edit5 .Text :=FormatFloat('0.00',shu2);
end;

procedure test1.Execute;
begin
FreeOnTerminate:=True ;
While not Terminated do
begin
Synchronize( Exe);
Sleep(1);//解决CPU占用过高问题 Sleep(0)告诉系统切换CPU时间片,就是把当时CPU时间片切换到其它线程去执行,也是会起到延迟效果。sleep不会占用CPU,不过会让CPU去处理其他的内容,有可能切换到其他线程的时候,其他线程占用了cpu

end;
plotfree;

end;

end.

unit th2;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,ExtCtrls,unit2;

type
test2 = class(TThread)
private
{ Private declarations }
FImge:TImage;
protected
procedure Execute; override;
procedure Exee;
public
Constructor Create();
end;

implementation

uses Unit1;

{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,

Synchronize(UpdateCaption);

and UpdateCaption could look like,

procedure test2.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }

{ test2 }

constructor test2.Create;
begin
Inherited Create(true);
end;

procedure test2.Execute;
begin
FreeOnTerminate:=True ;
While not Terminated do
begin
Synchronize(Exee);
Sleep(1); //解决CPU占用过高问题
end;
plofree;
end;

procedure test2.Exee;
begin
ploline(form1.Image2,shu1,shu2);
Form1.iXYPlot2.Channel[0].AddXY(shu1,shu2);
Form1.Edit6 .Text :=FormatFloat('0.00',shu1);
form1. Edit7 .Text :=FormatFloat('0.00',shu2);
end;

end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐