多线程绘图
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.