标签:
转载自:万一的博客
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.
多线程编程(4)--从CreateThread说起(倒数第三个参数)
标签:
原文地址:http://www.cnblogs.com/xumenger/p/4487520.html