转载自:万一的博客
function CreateThread( lpThreadAttributes: Pointer; dwStackSize: DWORD; lpStartAddress: TFNThreadStartRoutine; lpParameter: Pointer; {入口函数的参数} dwCreationFlags: DWORD; var lpThreadId; DWORD; ): THandle; stdcall;
线程入口函数的参数是一个无类型指针(Pointer),用它可以指定任何数据(这就是指针强大的地方之一);本例是把鼠标点击窗体的坐标传递给线程的入口函数,每次点击窗体都会创建一个线程,运行效果图如下
代码如下
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TForm1=class(TForm) procedure FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); end; var Form1: TForm1; implementation {$R *.dfm} var pt: TPoint; //这个坐标点将会以指针的方式传递给线程,它应该是全局的 function MyThreadFun(p: Pointer): Integer; stdcall; var i: Integer; pt2: TPoint; //因为指针参数给的点随时都在变,需要线程的局部变量存起来 begin pt2:= PPoint(p)^; //转换 for i:=0 to 1000000 do begin with Form1.Canvas do begin Lock; TextOut(pt2.X, pt2.Y, IntToStr(i)); UnLock; end; end; Result:= 0; end; procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var ID: DWORD; begin pt:= Point(X, Y); CreateThread(nil, 0, @MyThreadFun, @pt, 0, ID); //下面的写法更好理解,其实不必,因为 PPoint会自动转换为 Pointer的 //CreateThread(nil, 0, @MyThreadFun, Pointer(@pt), 0, ID); end; end.
窗体文件
object Form1: TForm1 Left = 0 Top = 0 Caption = ‘Form1‘ ClientHeight = 128 ClientWidth = 229 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = ‘Tahoma‘ Font.Style = [] OldCreateOrder = False OnMouseUp = FormMouseUp PixelsPerInch = 96 TextHeight = 13 end
这个例子还有不严谨的地方:当一个线程Lock窗体 Canvas时,其他线程在等待;线程在等待时,其中的技术也还在增加。这就是说:现在并没有去处理线程的同步;同步是多线程中最重要的课题,快到了
另外一个小技巧:线程函数的参数是个 32位(4个字节)的指针,仅就本例来说,可以让它的“高16位”和 “低16位” 分别携带X 和Y ,这样就不需要那个全局的pt 变量了。
其实在 Windows 的消息中就是这样传递坐标的,在Windows的消息中一般高字节是 Y、低字节是X ;咱们这么来吧,这样还可以使用给消息准备的一些方便的函数
重写本例代码(当然运行效果和窗体文件都是一样的):
unit Unit1; interface Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TForm1=class(TForm) procedure FormMouseUp(Sender: Tobject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); end; var Form1: TForm1; implementation {$R *.dfm} function MyThreadFun(p: Pointer): Integer; stdcall; var i: Integer; //Integer是32bit,4个字节 x, y: Word; //word是16bit,2个字节 begin x:= LoWord(Integer(p)); //将p转换为Integer,并获取其低字节 y:= HiWord(Integer(p)); //类似上面 {如果不使用LoWord、HiWord函数,则可以向下面这样:} //x:= Integer(p); //y:= Integer(p) shr 16; for i:= 0 to 1000000 do begin With Form1.Canvas do begin Lock; TextOut(x, y, IntToStr(i)); UnLock; end; end; Result:= 0; end; procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var ID: DWORD; num: Integer; begin num:= MakeLong(X, Y); {如果不使用MakeLong、MakeWParam、MakeLParam、MakeResult等函数,可以像下面这样:} //num:= Y shl 16 +X; CreateThread(nil, 0, @MuThreadFun, Ptr(num), 0, ID); {上面的 Ptr 是专门讲一个数字转换为指针的函数,当然也可以这样} //CreateThread(nil, 0, @MyThreadFun, Pointer(num), 0, ID); end; end.
时间: 2024-10-03 06:56:01