




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第10章其他编程
Delphi实用教程第10章其他编程第10章其他编程Delphi实用教程第10章其他编程110.1图形图像处理
10.1.1画布的通用属性和方法
TCanvasObject(画布对象)
常用方法及功能:(1)Arc方法▲语法:
Arc(x1,y1,x2,y2,x3,y3,x4,y4:Integer)
Arc方法在椭圆上画一段弧,椭圆由(x1,y1)、(x2,y2)两点所确定的椭圆所决定。弧的起点是椭圆圆周和椭圆中心与(x3,y3)连线的交点。弧矩形终点是椭圆周和椭圆中心与(x4,y4)连线的交点,以逆时针方向画弧。
例如,以下的程序将在窗口中将在窗口中绘制一个圆弧:
procedureTForm1.FormPaint(Sender:TObject); var R:TRect; begin R:=GetClientRect; Canvas.Arc(R.Left,R.Top,R.Right,R.Bottom,R.Right,R.Top, R.Left,R.Top);end;第10章其他编程10.1图形图像处理
10.1.1画布的通用属性和方法210.1.1画布的通用属性和方法
(2)Chord方法
▲语法:
Chord(x1,y1,x2,y2,x3,y3,x4,y4:Integer)
Chord方法连接椭圆上的两点,椭圆由(x1,y1)、 (x2,y2)两点所确定的矩形决定,(x3,y3)是始点,(x4,y4)是终点。
例如,在Form1窗体上放置一个按钮“连接椭圆上的两点”, 双击该按钮,输入下面的代码:
procedureTform1.Button1Click(Sender:TObject); var R:TRect; begin R:=GetClientRect;{Getcoordinatesofthecurrentwindow.} Canvas.Chord(R.Left,R.Top,R.Right,R.Bottom,R.Right, R.Top,R.Left,R.Top); end;第10章其他编程10.1.1画布的通用属性和方法 (2)Chord方法310.1.1画布的通用属性和方法
Canvas类的Chord方法示例
第10章其他编程10.1.1画布的通用属性和方法 Canvas类的Chord410.1.1画布的通用属性和方法
(3)Brushcopy方法 ▲语法:
Brushcopy(constDest:TRect;Bitmap:Tbitmap;const SourceTRect;Color:Tcolor) Brushcopy方法把位图的一部分复制到画布的某个矩形区域, 并用画笔的当前颜色替换位图的颜色。
●Dest定义画布的一个矩形区域,该矩形用以填充位图, ●Bitmap定义位图;
●Source定义位图中的矩形区域,该区域上的位图将被复制; ●Color定义画笔中,用以替换位图的颜色。
第10章其他编程10.1.1画布的通用属性和方法 (3)Brushcopy方510.1.1画布的通用属性和方法
(4)CopyRect方法 ▲语法:
CopyRect(Dest:TRect;Canvas:TCanvas;SourceTRect) 此方法从另一个画布对象上复制部分图像到该画布。
●Canvas表示复制画布,
●Source是源画布上要复制的图像区域,
●Dest表示目标画布上将接受复制图像的矩形区域。
第10章其他编程10.1.1画布的通用属性和方法 (4)CopyRect方法610.1.1画布的通用属性和方法
(5)Draw方法 ▲语法:
Draw(x,y:Integer;Graphic:Tgraphic) 此方法在画布给定的像素点坐标(x,y)处画由参数 Graphic所给的图像,该图像可以是位图、图标或元位图。 Tcanvas的其他方法列于表中。
第10章其他编程10.1.1画布的通用属性和方法 (5)Draw方法第10章710.1.1画布的通用属性和方法2.TpenObject(画笔对象)
用于在画布上绘制各种线段,该对象常用的属性有:
l
Color:定义笔的颜色; l
Width:定义线段宽度; lStyle:定义线段的各种类型,如表所示;
第10章其他编程10.1.1画布的通用属性和方法2.TpenObject810.1.1画布的通用属性和方法
●Mode:定义线段的颜色,取值如表所示。
第10章其他编程10.1.1画布的通用属性和方法 ●Mode:定910.1.1画布的通用属性和方法3.TbrushObject(画刷对象)
画刷对象用以填充图形,如用画刷颜色或图案对矩形或椭圆进行填充。Tbrush拥有一个画刷句柄(Hbrush)。画刷的颜色定义在Color属性中,画刷还有一个Bitmap属性,该属性只能在运行时得到,画刷可使用位图填充图形以产生特殊效果。
第10章其他编程10.1.1画布的通用属性和方法3.TbrushObje1010.1.1画布的通用属性和方法4.TColor类型
TColor类型用于定义一个对象的颜色。很多部件的颜色属性就是TColor类型,在Graphics单元中TColor定义如下: TColor=-(COLOR_ENDCOLORS+1)…$02FFFFF;第10章其他编程10.1.1画布的通用属性和方法4.TColor类型第11110.1.2图形图像组件Image组件
Image组件是一个容器组件,它在应用程序窗体窗口中提供了一个矩形区域,用于显示和输出位图、图标、图元文件或用户自定义的图形文件。Image组件的常用属性表。
第10章其他编程10.1.2图形图像组件Image组件第10章其他编1210.1.2图形图像组件2.Shape组件
Shape组件用于在窗体中绘制几何图形,如椭圆、矩形和圆角矩形等。该组件的常用属性有:
l
Shape:指明需要绘制的几何图形,它可能的取值和含义 如表所示;l
Brush:指明在几何图形中填充的样式;l
Pen:指定几何图形所使用的线型。
第10章其他编程10.1.2图形图像组件2.Shape组件第10章1310.1.2图形图像组件3.PaintBox组件
该组件是一个简单的画板,它为应用程序提供了可在窗体的特定矩形区域内画图的方法。 PaintBox组件的主要属性有: (1)Anchors属性 该属性包含4个子属性(akLeft、akTop、akRight和akBotton),用来指定在运行过程中,当父组件是可调时,它相对于父组件边沿的位置。 (2)BoundsRect属性 该属性用来指定组件的矩形边界,用其父组件的坐标系来表示。
第10章其他编程10.1.2图形图像组件3.PaintBox组件第11410.1.2图形图像组件
例如,以下代码用于绘制矩形:
procedureTform1.Button1Click(Sender:TObject); var MyRect:TRect; begin MyRect:=ActiveControl.BoundsRect; MyRect.right=MyRect.Left+2*(MyRect.Right-MyRect.Left); MyRect.Botton:=MyRect.Top+(MyRect.Botton-MyRect.Top)div2; ActiveControl.BoundsRect:=MyRect; end; (3)Canvas属性 该属性仅在运行时有效,使用该属性可以在组件表面的特定区域进行绘图。 (4)Color属性 该属性可用于除“颜色”对话框以外的所有组件或对象。
(5)Constaints属性 该属性强制指定组件的大小。
第10章其他编程10.1.2图形图像组件 例如,以下代码用于绘制矩形:第1510.1.3图形(Picture)对象读取图像
读取图像需要使用LoadFromFile方法来调用,同时配合OpenDialog函数来选择相应的图像文件。下面的代码实现对图像文件的读取:procedureTform1.Open1Click(Sender:Tobject);begin ifOpenDialog1.Executethen begin CurrentFile:=OpenDialog1.Filename; Image.Picture.LoadFromFile(CurrentFile); end;end;
第10章其他编程10.1.3图形(Picture)对象读取图像第10章1610.1.3图形(Picture)对象2.保存图像
为将Image组件中的图像保存为文件,可调用Image组件的Picture属性的SaveToFile方法。SaveToFile方法需要一个保存文件的文件名。下面的代码是一般程序常用的“Save”和“SaveAs”菜单的处理程序:
procedureTform1.Save1Click(Sender:Tobject) begin ifCurrentFile<>’’then Image.Picture.SaveToFile(CurrentFile) elseSaveAsClick(Sender); end; procedureTform.Saveas1Click(Sender:TObject); begin ifSaveDialog1.Executethen begin CurrentFile:=SaveDialog1.FileName; Save1Click(Sender); end; end;
第10章其他编程10.1.3图形(Picture)对象2.保存图像第11710.1.3图形(Picture)对象3.替换图像
用户可以在任何进修替换掉Image组件中的图像,只要将一新的图像对象赋给Picture就可以了。下面的代码实现用一个新的位图对象代替原有的Image组件中的Picture中的图像对象的功能: Bitmap:Tbitmap: begin Bitmap:=Tbitmap.Create; Bitmap.Width:=NewWidth; Bitmap.Height:=NewHeight; Image.Picture.Graphic:=Bitmap; CurrentFile:=’’; end;
第10章其他编程10.1.3图形(Picture)对象3.替换图像第11810.1.3图形(Picture)对象 【例】屏幕复制,将当前屏幕的图像抓下来,显示到窗口中;还可以文件的形式保存起来。步骤如下: (1)建立用户界面:建立窗体Form1,添加一个Panel、一个Timer、一个SavePictureDialog、四个Button控件并在Panel控件上添加一个 Image控件。(2)再创建窗体Form2,用于窗口抓图的显示窗口;在该窗体中添加一 个Image控件和Timer控件,其中Image控件用于保存图像。(3)设置控件属性:对添加的控件按下表设置其属性。第10章其他编程10.1.3图形(Picture)对象 【例】屏幕复制,将1910.1.3图形(Picture)对象控件的属性设置
第10章其他编程10.1.3图形(Picture)对象控件的属性设置第12010.1.3图形(Picture)对象(4)激活第一个单元文件,单击Delphi7的File菜单下的UseUnit项,出现窗口,选择Unit2,单击OK。(5)编写程序代码如下:
procedureTForm1.Timer1Timer(Sender:TObject); //完成对屏幕的复制,并粘帖到Image控件中 var Fullscreen:Tbitmap; Fullscreencanvas:tcanvas; dc:HDC; begin timer1.Enabled:=false; fullscreen:=tbitmap.Create;//建立一个BITMAP来存放图像 fullscreen.Width:=screen.Width; dc:=getdc(0); //API函数,获取屏幕 fullscreencanvas:=tcanvas.Create; //建立一个CANVAS对象 fullscreencanvas.Handle:=dc; fullscreen.Canvas.CopyRect(rect(0,0,screen.Width,screen.Height), fullscreencanvas,rect(0,0,screen.Width,screen.Height));第10章其他编程10.1.3图形(Picture)对象(4)激活第一个单元2110.1.3图形(Picture)对象 fullscreencanvas.Free; releasedc(0,dc); image1.Picture.Bitmap:=fullscreen;//将拷贝下的图像赋给IMAGE对象image1.Width:=fullscreen.Width;image1.Height:=fullscreen.Height;fullscreen.Free;form1.WindowState:=wsnormal;form1.Show;messagebeep(1);end;procedureTForm1.Button4Click(Sender:TObject);beginclose;end;第10章其他编程10.1.3图形(Picture)对象 fullscre2210.1.3图形(Picture)对象
procedureTForm1.Button1Click(Sender:TObject);begin form1.WindowState:=wsminimized; form1.Hide; timer1.Enabled:=true;end;procedureTForm1.Button3Click(Sender:TObject);beginifform1.SavePictureDialog1.Executethenbeginform2.Image1.Picture.SaveToFile(savepicturedialog1.FileName);end;end;第10章其他编程10.1.3图形(Picture)对象procedure2310.1.3图形(Picture)对象procedureTForm1.Button2Click(Sender:TObject);begin form1.Hide; form2.Hide; form2.Timer1.Enabled:=true;end;end.var Form2:TForm2; foldx,x1,y1,x2,y2,oldx,oldy,foldy:integer; flag,trace:boolean; implementationusesunit3;{$R*.dfm}第10章其他编程10.1.3图形(Picture)对象procedureT2410.1.3图形(Picture)对象
procedureTForm2.Timer1Timer(Sender:TObject);var fullscreen:TBitmap; fullscreencanvas:TCanvas; dc:HDC;begin form2.timer1.enabled:=false; fullscreen:=tbitmap.create; fullscreen.width:=screen.Width; fullscreen.Height:=screen.Height; dc:=getdc(0); fullscreencanvas:=tcanvas.Create; fullscreencanvas.Handle:=dc; fullscreen.Canvas.CopyRect(rect(0,0,screen.Width,screen.Height), fullscreencanvas,rect(0,0,screen.Width,screen.Height)); fullscreencanvas.Free; releasedc(0,dc);第10章其他编程10.1.3图形(Picture)对象procedure2510.1.3图形(Picture)对象
image1.Picture.Bitmap:=fullscreen; image1.Width:=fullscreen.Width;image1.Height:=fullscreen.Height;fullscreen.Free;form2.WindowState:=wsnormal;form2.Show;messagebeep(1);foldx:=-1;foldy:=-1;image1.Canvas.Pen.Mode:=pmnot; //笔的模式取反image1.Canvas.Pen.Color:=clblack; //笔的颜色image1.Canvas.Brush.Style:=bsclear; //刷子的格式flag:=true;end;第10章其他编程10.1.3图形(Picture)对象 image1.2610.1.3图形(Picture)对象
procedureTForm2.Image1MouseMove (Sender:Tobject;Shift:TShiftState;X,Y:Integer);begin iftrace=truethen //追踪鼠标 begin //擦除旧的图形并画上新的图形 withimage1.Canvasdo begin rectangle(x1,y1,oldx,oldy); rectangle(x1,y1,x,y); oldx:=x; oldy:=y; end; end elseifflag=truethen第10章其他编程10.1.3图形(Picture)对象procedure2710.1.3图形(Picture)对象 begin withimage1.Canvasdo begin moveto(foldx,0); lineto(foldx,screen.Height); moveto(0,foldy); lineto(screen.Width,foldy); moveto(x,0); lineto(x,screen.Height); moveto(0,y); lineto(screen.Width,y); foldx:=x; foldy:=y; end; end;end;第10章其他编程10.1.3图形(Picture)对象 begin第10章2810.1.3图形(Picture)对象procedureTForm2.Image1MouseDown(Sender:Tobject;Button:TMouseButton;Shift:TShiftState;X,Y:Integer);//绘制区域图像var width,height:integer; newbitmap:TBitmap;beginif(trace=false)then begin //首次点击鼠标左键,开始追踪鼠标 flag:=false; withimage1.Canvasdo begin moveto(foldx,0); lineto(foldx,screen.Height); moveto(0,foldy); lineto(screen.Width,foldy);第10章其他编程10.1.3图形(Picture)对象procedure2910.1.3图形(Picture)对象
end; x1:=x; y1:=y; oldx:=x; oldy:=y; trace:=true; image1.Canvas.Pen.Color:=clblack; image1.Canvas.Brush.Style:=bsclear;endelsebegin //第2次点击鼠标,得到矩形,并将它拷贝到FORM1的IMAGE上 x2:=x; y2:=y; trace:=false;
第10章其他编程10.1.3图形(Picture)对象 end;第10章3010.1.3图形(Picture)对象 image1.Canvas.Rectangle(x1,y1,oldx,oldy); width:=abs(x2-x1); height:=abs(y2-y1); orm1.Image1.Width:=width; form1.Image1.Height:=height; newbitmap:=Tbitmap.Create;//生成Bitmap对象 newbitmap.Width:=width; newbitmap.Height:=height; newbitmap.Canvas.CopyRect(rect(0,0,width,height), form2.Image1.Canvas,rect(x1,y1,x2,y2)); form1.Image1.Picture.Bitmap:=newbitmap; //放到FORM的IMAGE上 newbitmap.Free; form2.Hide; form1.Show;end;end;end.第10章其他编程10.1.3图形(Picture)对象 image1.Can3110.1.3图形(Picture)对象(6)运行得到如图的结果。
第10章其他编程10.1.3图形(Picture)对象(6)运行得到如图的3210.2多媒体编程
10.2.1简易媒体播放器实例
制作一个媒体播放器,需要在窗体上设置一个TmediaPlayer(该组件位于组件面板的System选项卡上,图标为)、十个Tbutton、一个TopenDialog(位于组件面板的Dialogs选项卡上,图标为)等组件)、一个Edit、一个ComboBox、一个Timer如图所示。各个组件的名字(Name属性)采用默认值。
第10章其他编程10.2多媒体编程
10.2.1简易媒体播放器实例制3310.2.1简易媒体播放器实例该媒体播放器的工作过程是:单击“打开”按钮,就会打开OpenDialog对话框,让用户从中选择一个文件。单击
“播放”按钮,就会播放用户所选择的文件。下面的代码是用于处理Button8的OnClick事件,它将打开媒体播放器。
procedureTform1.Button8Click(Sender:Tobjict);beginifopendialog1.Executethenbeginmediaplayer1.FileName:=opendialog1.FileName;mediaplayer1.openend;end.
第10章其他编程10.2.1简易媒体播放器实例该媒体播放器的工作过程是:单3410.2.1简易媒体播放器实例为了OpenDialog对话框只列出多媒体文件,需要在属性查看器中设置OpenDialog1的Filter属性,单击打开Filter属性设置旁的按钮,将打开FilterEditor对话框,如图所示,在该对话框中键入所要打开文件的类型,如*.WAV、*.AVI、*.MID等,单击OK。设置好上述内容后,保存该工程,这样一个简单的媒体播放器就制作好了。运行这个程序,打开一个多媒体文件即可。
第10章其他编程10.2.1简易媒体播放器实例为了OpenDialog对话3510.2.2媒体播放器组件
1.MediaPlayer组件
媒体播放器组件
媒体播放器组件属性
第10章其他编程10.2.2媒体播放器组件1.MediaPlayer组3610.2.2媒体播放器组件2.MediaPlayer组件的属性
(1)AutoEnable属性
该属性值是Boolean类型。如果这个属性设为True,媒体播放 器在运行过程中能够自动控制哪些按钮当前可用,哪些按钮 当前不可用(不可用的按钮以灰色显示)。
(2)AutoOpen属性
该属性值是Boolean类型。如果这个属性设为True,媒体播放 器自动打开DeveceType属性指定的多媒体设备(如果 DeviceType属性设为dtAutoSelect,媒体播放器将自动打开 FileName属性中指定的文件)。
(3)AutoRewind属性
该属性值是Boolean类型,用于设置是否具有自动重绕功能。
第10章其他编程10.2.2媒体播放器组件2.MediaPlayer组件3710.2.2媒体播放器组件(4)Capabilities属性 该属性值是只读TMPDevCapsSet类型,返回当前设备可以进行 的操作,它的值及值的含义如表所示。
第10章其他编程10.2.2媒体播放器组件(4)Capabilities属3810.2.2媒体播放器组件(5)ColoredButton属性
该属性值是TbuttonSet集合类型,用于设置哪些按钮彩色显示,哪些按钮用黑白显示,默认时全部按钮均用彩色显示。
第10章其他编程10.2.2媒体播放器组件(5)ColoredButton3910.2.2媒体播放器组件MediaPlayer组件的其他属性列于表中。
第10章其他编程10.2.2媒体播放器组件MediaPlaye4010.2.2媒体播放器组件
上表Mode属性的取值及含义见表
第10章其他编程10.2.2媒体播放器组件 上表Mode属性的取值及含义见4110.2.2媒体播放器组件3.MediaPlayer组件的过程和函数
(1)AutoButtonSet过程
该过程用来指定媒体播放器的按钮是否可用。
(2)Back过程
该过程使媒体播放器退回数个帧。
(3)Click过程
这是一个动态过程,该过程决定当OnClick事件被触发时执 行什么动作。在默认状态下,当OnClick事件触发时,该过 程不招待任何动作,仅仅是调用一个事件处理程序,连接到 媒体播放器的OnClick事件处理程序中。该过程可以根据需 要重新加载事件处理程序。 (4)Close过程 该过程关闭已打开的多媒体播放设备。当应用程序中止时, 自动调用该过程。
第10章其他编程10.2.2媒体播放器组件3.MediaPlayer组件4210.2.2媒体播放器组件(5)Create函数
这是一个动态的构造函数,该函数可在运行时建立一个
MediaPlayer对象,并对其进行初始化,使得媒体播放器既可以在设计时静态建立,也可以在运行时通过调用Create方法动态建立。(6)Destroy函数
这是一个动态的析构函数,该函数用于撤销媒体播放器对象。应用程序不能直接调用该函数,应先调用Free过程检查媒体播放器对象是否空闲,如果空闲就释放其占用的内存空间。该函数执行前,必须确保媒体设备已经关闭。
第10章其他编程10.2.2媒体播放器组件(5)Create函数第10章4310.2.2媒体播放器组件MediaPlayer媒体播放器的其他过程表。
第10章其他编程10.2.2媒体播放器组件MediaPlayer媒体播放器4410.2.2媒体播放器组件MediaPlayer媒体播放器的其他过程表。第10章其他编程10.2.2媒体播放器组件MediaPlayer媒体播放4510.2.2媒体播放器组件4.MediaPlayer组件的事件
(1)OnClick事件
当用户移动光标到媒体播放器控制按钮组的任一按钮上,单 击鼠标左键或者当媒体播放器控制按钮获得焦点时,单击空 格键都将会触发该事件。 (2)OnNotify事件 如果Notify属性设置为True,当一个媒体控制方法( 如Back、Close、Eject、Next、Open、Pause、PauseOnly、 Play.Previous、Resume、StartRecording、Step、Stop等)执 行结束时,触发该事件。OnNotify事件触发后,必须重新 设置Notify属性为True,以便触发下一个OnNotify事件。
第10章其他编程10.2.2媒体播放器组件4.MediaPlayer组件4610.2.2媒体播放器组件(3)OnPostClick事件
当OnClick事件处理程序被调用以后,触发该事件。(4)OnEnter事件
当一个控件接收到键入焦点时,触发该事件。
第10章其他编程10.2.2媒体播放器组件(3)OnPostClick事件4710.3线程
10.3.1线程概念
所谓多线程,是指操作系统同时运行多个执行体的能力。线程概念与并发性是紧密相关的,多线程的出发点就是为了提高系统的并发度。
线程与进程的差别主要体现在两个方面:
线程和进程虽然都是系统的基本执行单元,线程的划分单位比进程小,因此支持多线程的系统比只支持多进程的系统并发度高;进程将内存作为自己独享的资源,每个进程都有自己的内存空间;而线程共享内存空间,并通过共享内存交换信息,因此有利于提高系统效率。
第10章其他编程10.3线程
10.3.1线程概念所谓多线程,是指操4810.3.2TThread类
TThread类
TThread类是直接从Tobject继承下来的,它是抽象类,即不能创建TThread类的实例,而只能创建TThread派生类的实例—即创建线程对象。●创建线程对象的方法是,选择Delphi7主菜单下的 FileNewOther…,在弹出的“NewItems”对话框的“New” 选项卡中选择 ThreadObject图标, 如图所示。
第10章其他编程10.3.2TThread类TThread类第10章4910.3.2TThread类
●当双击ThreadObject图标后,将出现如图所示的对话框,提示输入线程对象的名称,线程对象名称是一个标识符,如TestThread。
●输入线程对象名后,Delphi7会自动创建一个包括该线程对象的单元,该单元给出了线程的框架,其最初的内容如下所示:
第10章其他编程10.3.2TThread类 ●当双击ThreadO5010.3.2TThread类unitUnit1;interfaceusesClasses;
typeTestThread=class(TThread)private{Privatedeclarations}protectedprocedureExecute;override;end;implementation{}{TestThread}procedureTestThread.Execute;begin{Placethreadcodehere}end;end.第10章其他编程10.3.2TThread类unitUnit1;第10章5110.3.2TThread类TThread派生类中唯一必须覆盖的方法是Excute(),即需要定义线程所执行的功能。
当Create()需要参数为False,则当调用Create()后,线程对象的Execute()方法将会自动被调用,即自动地执行Execute()的代码。当Create()需要参数为False,则不自动执行Execute()的代码,而是要通过TThread的Resume()方法来唤醒线程。
第10章其他编程10.3.2TThread类TThread派生类中唯一必须5210.3.2TThread类2.与VCL同步
大多数VCL都要求在任一时刻只允许一个线程访问它,因此在Delphi中使用多线程,还有一个重要的注意事项,即对VCL访问只能在主线程中进行,这表明所有与用户交互的代码只能在主线程中。同时,Delphi为了使线程中的方法也能在主线程中执行,在TThread中设置了一个Synchronize()方法,该方法声明如下:
procedureSynchronize(Method:TThreadMethod);
Synchronize()方法的参数就是用来传递需要在主线程中执行的线程中的方法。
第10章其他编程10.3.2TThread类2.与VCL同步第10章5310.3.3线程的终止
当线程对象的Execute()方法执行完毕后,就认为该线程终止了,此时Delphi会自动调用一个标准例程EndThread(),该例程将再调用API函数ExitThread(),由ExitThread()来清除线程所占用的栈。线程终止时,将触发OnTerminate事件,可以利用在退出Execute()之前将FreeOnTerminate属性置为True的方法来及时清除线程对象。
procedureTestThread.Execute; var i:integer; Begin FreeOnTerminate:=True; //设置FreeOnTerminate为true以便及时清除线程对象 Fori:=1to10000do begin IfTerminatedthenbreak; Value:=Value+1; end; End;
第10章其他编程10.3.3线程的终止当线程对象的Execute()方法5410.3.3线程的终止【例】创建如图所示的窗体,单击“开始”按钮后,将创建一个附属线程,该线程执行一个计算任务,与此同时主线程并发执行,用户可在文本区域输入任意的字符。示例中所使用的窗体和组件的属性列于表中,未列的属性均取默认值。
主窗体(设计时)
第10章其他编程10.3.3线程的终止【例】创建如图所示的窗体,单5510.3.3线程的终止
窗体与组件的属性设置
第10章其他编程10.3.3线程的终止 窗体与组件的属性设置第10章5610.3.3线程的终止●保存主窗体单元为Main.pas,源程序如下:unitMain;interfaceusesWindows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,Dialogs,StdCtrls,ThrdU;typeTMainForm=class(TForm)Label1:TLabel;Button1:TButton;Label2:TLabel;Edit1:TEdit;Memo1:TMemo;procedureButton1Click(Sender:TObject);end;
第10章其他编程10.3.3线程的终止●保存主窗体单元为Main.pas,5710.3.3线程的终止varMainForm:TMainForm;implementation{$R*.dfm}procedureTMainForm.Button1Click(Sender:TObject);beginTTestThread.Create(False);{创建线程,使其立即执行}end;end.第10章其他编程10.3.3线程的终止var第10章其他编程5810.3.3线程的终止●创建线程单元ThrdU.pas,选择主菜单的FileNewUnit,输入线程对象名为TtestThread,再输入以下源程序: unitThrdU; interface uses Classes; type TTestThread=class(TThread){线程TTestThread类定义} private Answer:integer; protected procedureGiveAnswer; procedureExecute;override; end; implementation usesSysUtils,Main; procedureTTestThread.GiveAnswer; begin MainForm.Edit1.Text:=InttoStr(Answer); end;第10章其他编程10.3.3线程的终止●创建线程单元ThrdU.pas,选5910.3.3线程的终止{TTestThread}procedureTTestThread.Execute;{执行一个较长的计算任务}Vari:integer;beginFreeOnTerminate:=True;fori:=1to2000000dobeginifTerminatedthenbreak;Inc(Answer,Round(abs(sin(sqrt(i)))));Synchronize(GiveAnswer);{使GiveAnswer能在主线程中执行}end;end;end.第10章其他编程10.3.3线程的终止{TTestThread}第106010.3.3线程的终止●单击F9运行程序,结果如图所示。
第10章其他编程10.3.3线程的终止●单击F9运行程序,结果如图所示。6110.3.4线程同步编写多线程应用程序时,需要控制好线程间的同步资源访问,以保证线程的安全运行。
所谓线程同步,简单说就是协调线程间的执行时序。Win32API提供了一组同步对象,包括信号量、互斥、临界区和事件等,来解决线程的同步问题。
Delphi分别将事件对象和临界区对象封装为TEvent和TCriticalSection对象,使得事件和临界区更易使用。
第10章其他编程10.3.4线程同步编写多线程应用程序时,需要控制好线程6210.3.4线程同步临界区
◆临界区是指一次只能由一个线程执行的一段代码。在使用临界区之前,要使用InitializeCriticalSection()过程来初始化它,其声明如下: procedureInitializeCriticalSection (varlpCriticalSection:TRTLCriticalSection);stdcall;
●
lpCriticalSection是一个TRTLCriticalSection类型的记录,在该参数中传递未初始化的记录,●InitializeCriticalSection()过程就会填充这个记录。●
TRTLCriticalSection是一个与临界区资源相关的类型,。
第10章其他编程10.3.4线程同步临界区第10章其他编程6310.3.4线程同步 ◆创建临界区,使用EnterCriticalSection()和LeaveCriticalSection()过程来封装代码块。这两个过程的声明如下:
procedureEnterCriticalSection(varlpCriticalSection: TRTLCriticalSection);stdcall; procedureLeaveCriticalSection(varlpCriticalSection: TRTLCriticalSection);stdcall;
◆当不再需要TRTLCriticalSection记录时,要调用DeleteCriticalSection()过程将其删除。
第10章其他编程10.3.4线程同步 ◆创建临界区,使用EnterCrit6410.3.4线程同步 【例】设有一个全局数组,分别用两个线程对其进行两次初始化,需要对这两个线程同步,否则将出现数据不确定的情形。用临界区方式进行两线程的同步,将对数组各元素赋值的代码设为临界区。程序界面如图所示,当单击“初始化”按钮后,将生成两个线程并执行,在列表框中显示数组元素值。(1)创建应用程序界面,新建如图所示的窗体,并放置一个 label、一个button和一个listbox组件,各组件及其属性设置列于表中。
第10章其他编程10.3.4线程同步 【例】设有一个全局数组,分别用两个线6510.3.4线程同步
窗体与组件的属性设置
第10章其他编程10.3.4线程同步 窗体与组件的属性设置第10章其他6610.3.4线程同步(2)在Form1对应的Unit1单元文件中输入程序代码:
unitUnit1; interface uses Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls, Forms, Dialogs,StdCtrls,unit2; Type TForm1=class(TForm) Button1:TButton; ListBox1:TListBox; Label1:TLabel; procedureButton1Click(Sender:TObject); end;
第10章其他编程10.3.4线程同步(2)在Form1对应的Unit16710.3.4线程同步
var Form1:TForm1; CS:TRTLCriticalSection; //声明临界区资源记录变量 implementation {$R*.dfm} procedureTForm1.Button1Click(Sender:TObject); begin InitializeCriticalSection(CS);//初始化临界区 TInitThread.Create(False);//创建TinitThread线程对象并执行 TInitThread.Create(False); end; end.第10章其他编程10.3.4线程同步 var第10章其他编程6810.3.4线程同步
(3)创建线程对象TinitThread,选择主菜单的
FileNewOther…,在NewItems的New选项卡中双击 “ThreadObject”图标,在弹出的对话框中输入线程名 “TinitThread”。 (4)在系统自动新建的Unit2单元中输入程序代码:
unitUnit2; interface uses Windows,SysUtils,Classes; //在此要添加Windows和SysUtils Type {以下是TinitThread类定义} TInitThread=class(TThread) protected procedureShowResult; //显示结果 procedureExecute;override; end;
第10章其他编程10.3.4线程同步 (3)创建线程对象TinitThre6910.3.4线程同步
implementation usesUnit1; constSIZE=10; //数组大小 varnext:integer=0; //全局变量定义 tag:integer=0; A:array[1..SIZE]ofinteger;procedureTInitThread.ShowResult;var i:integer;begin inc(tag); iftag=2then begin //两个线程均执行完毕 fori:=1toSIZEdo //在列表框中显示数组各元素值 Form1.ListBox1.Items.Add(intToStr(A[i])); DeleteCriticalSection(CS); //移去临界区 end;end;第10章其他编程10.3.4线程同步 implementation第10章7010.3.4线程同步procedureTInitThread.Execute;vari:integer;begin EnterCriticalSection(CS); //进入临界区 fori:=1toSIZEdo //为数组各元素赋值 begin A[i]:=next; Inc(next); Sleep(5); end; LeaveCriticalSection(CS); //临界区终止 Synchronize(ShowResult); //使ShowResult能在主线程中执行 end;end.第10章其他编程10.3.4线程同步procedureTInitThre7110.3.4线程同步
(5)单击F9运行程序,结果如图所示。
第10章其他编程10.3.4线程同步 (5)单击F9运行程序,结果如图所示7210.3.4线程同步说明: 在第一个线程调用了EnterCriticalSection()之后,其他的线程就不能进入临界区代码,它们将睡眠;直到第一个线程调用LeaveCriticalSection()后,下一个需要进入临界区的线程才被唤醒。
第10章其他编程10.3.4线程同步说明:第10章其他编程7310.3.4线程同步2.互斥
(1)互斥(mutex)与临界区非常相似,但有两个主要区别: ●互斥可用于不同进程的线程间同步,而临界区不可; ●互斥可被赋予一个字符串名,通过该名字可创建该互斥对象的 附加句柄。 (2)创建互斥对象的函数是CreateMutex(),其原型为
functionCreateMutex(lpMutexAttibutes:PsecurityAttributes; bInitialOwner:BOOL;lpName:Pchar):Thandle;stdcall;
●lpMutexAttibutes参数为一个指向TsecurityAttributes记录的指针,通 常置为0,表示使用默认的安全属性。
●BInitialOwner参数用于指出创建互斥对象的线程是否要成为此互斥对 象的拥有者,该参数为false表示互斥对象没有拥有者。
●LpName参数指出互斥对象的名称
。第10章其他编程10.3.4线程同步2.互斥第10章其他编程7410.3.4线程同步
(3)互斥对象不再使用时,应调用CloseHandle()过程来关闭它。当一个线程不需再拥有互斥对象时,应调用ReleaseMutex()过程。(4)为了防止其他线程进入同步区代码,需使用aitForSingleObject()函数,原型为:
functionWaitForSingleObject(hHandle:Thandle; dwMilliseconds:DWORD):DWAORD;stdcall;
●
DwMilliseconds参数可设为两个值: ①当值为0时,函数将只检查由hHandle参数指定的互斥对象是否处 于发信号状态,检查完毕后函数立即返回 ②当值为INFINITE时,则函数将一直等待,直到信号出现为止
●
hHandle参数指定的互斥对象
●返回值有3种:
①WAIT_ABANDONED,表明指定对象是互斥对象,并且拥有该 互斥对象的线程在未释放该对象之前就已终止 ②WAIT_OBJECT_0,表明指定的对象处于发信号状态 ③WAIT_TIMEOUT,表明等待的时间已过,对象仍是非发信号 状态第10章其他编程10.3.4线程同步 (3)互斥对象不再使用时,应调用Cl7510.3.4线程同步 【例】对于临界区的例题,使用互斥方式进行两线程的同步,该应用程序与临界区的例题的差别仅在于线程同步方式不同,其余均相同。程序两个单元文件的内容分别为:
//文件Unit1.pas unitUnit1; interface uses Windows,Messages,SysUtils,Variants,Classes,Graphics, Controls,Forms, Dialogs,StdCtrls,Unit2; type TForm1=class(TForm) Button1:TButton; Label1:TLabel; ListBox1:TListBox; procedureButton1Click(Sender:TObject); end;第10章其他编程10.3.4线程同步 【例】对于临界区的例题,使用互斥方式7610.3.4线程同步varForm1:TForm1;hMutex:THandle=0; //声明互斥量implementation{$R*.dfm}procedureTForm1.Button1Click(Sender:TObject);beginhMutex:=CreateMutex(nil,False,nil); //创建互斥量TInitThread.Create(False); //创建TinitThread线程对象并执行TInitThread.Create(False);end;end.第10章其他编程10.3.4线程同步var第10章其他编程7710.3.4线程同步//文件Unit2.pasunitUnit2;interfaceuses Windows,SysUtils,Classes;typeTInitThread=class(TThread)protected procedureShowResult; //显示结果 procedureExecute;override;end;第10章其他编程10.3.4线程同步//文件Unit2.pas第10章其7810.3.4线程同步implementationusesUnit1;constSIZE=10; //数组大小varnext:integer=0; //全局变量定义tag:integer=0;A:array[1..SIZE]ofinteger;procedureTInitThread.ShowResult;var i:integer;begin inc(tag); iftag=2then begin{两个线程均执行完毕} fori:=1toSIZEdo //在列表框中显示数组各元素值 Form1.ListBox1.Items.Add(intToStr(A[i])); CloseHandle(hMutex); //关闭互斥对象 end;end;第10章其他编程10.3.4线程同步implementation第10章7910.3.4线程同步procedureTInitThread.Execute;vari:integer;beginifWaitForSingleObject(hMutex,INFINITE)=WAIT_OBJECT_0then{此时,若要拥有hMutex互斥对象的线程将睡眠,用来禁止其他线程进入此同步区域的代码}beginfori:=1toSIZEdo //为数组各元素赋值beginA[i]:=next;Inc(next);Sleep(5);end;end;ReleaseMutex(hMutex); //释放互斥量Synchronize(ShowResult); //使ShowResult能在主线程中执行end;end.第10章其他编程10.3.4线程同步procedureTInitThre8010.4DLL应用和开发DLL
DLL(DynamicLinkLibrary),即动态链接库,它就是程序模块,包括编译过的可执行代码、数据或资源,能够被其他的Windows应用程序共享。大部分DLL文件的扩展名为.dll,也有的可能是.drv(设备驱动程序)、.sys(系统文件)或.fon(字体文件)。Windows系统文件Kernel32.dll、User32.dll、GDI32.dll就是核心Win32系统的动态链接库Kernel.dll负责内存、进程和线程的管理User32.DLL负责创建窗口和处理Win32消息GDI32.DLL负责处理图形。DLL和可执行文件(exe)非常类似,但DLL中包含了可执行代码却不能单独执行,而应由Windows应用程序直接或间接调用。第10章其他编程10.4DLL应用和开发DLLDLL(DynamicL8110.4.1使用DLL的优点节省资源
动态链接不将所调用的函数代码拷贝到应用程序的可执行文件中,而是应用程序运行时,才动态地装载DLL,其代码将被映射到进程的地址空间中,当要执行所调用DLL中的函数时,根据链接产生的重定位信息,转去执行DLL中相应的函数代码。
2.共享代码、资源和数据
把资源组织到DLL中,就可以让许多应用程序使用,而不必在内存中重复装入这些内容。线程是相互独立的所有线程可以共享DLL的数据。
3.实现模块化
可将程序划分为多个DLL模块,既可以提高模块化程度,又可以隐蔽代码实现细节。
第10章其他编程10.4.1使用DLL的优点节省资源第10章其他编程8210.4.1使用DLL的优点4.独立于编程语言
在一种开发环境下设计的DLL程序,可以在其他的环境中使用。5.便于系统升级
如果需对系统升级,只要将所涉及的DLL进行即可,而不必将整个系统重新编译、链接,减少了工作量。
第10章其他编程10
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025-2030巧克力行业市场深度分析及发展策略研究报告
- 2025-2030实木板市场发展分析及行业投资战略研究报告
- 系统化信息化物流师试题及答案
- 2025-2030婴儿清洁牙刷产业发展分析及发展趋势与投资前景预测报告
- 2025-2030奶粉行业市场深度分析及发展前景与投资战略研究报告
- 2025-2030天然皮革行业市场发展分析及投资前景研究报告
- 2025年-贵州省建筑安全员B证考试题库
- 精细化管理信息化物流师试题及答案分析
- 2025-2030国内稀土永磁电机行业市场发展现状及发展前景与投资机会研究报告
- 2025-2030国内数码音响行业市场发展现状及竞争格局与投资前景研究报告
- 施工机具专项施工方案
- 苏教版三年级科学(下)第一单元综合测试卷植物的一生(一)含答案
- API-650-1钢制焊接石油储罐
- (完整版)最新版线束标准
- 少儿美术绘画教学课件 艺库美术 10岁-12岁 《创意素描-洗刷刷》
- 2022年“华罗庚杯”全国初中数学预赛-竞赛试题及答案
- 减速机生产工艺流程图
- 金融科技课件(完整版)
- 网络直播行业税收检查指引
- 初中三年主题班会整体规划
- 喷塑车间员工培训课件
评论
0/150
提交评论