澳门皇冠賭場:Delphi多线程编程 - 编程技巧文章 - 蓝鸟软件-05

来源:百度文库 编辑:偶看新闻 时间:2024/04/28 08:58:11

多线程编程(5) - 从 CreateThread 说起[续三]

function CreateThread(
 lpThreadAttributes: Pointer;
 dwStackSize: DWORD;
 lpStartAddress: TFNThreadStartRoutine; {入口函数的指针}
 lpParameter: Pointer;
 dwCreationFlags: DWORD;
 var lpThreadId: DWORD
): THandle; stdcall;

  到了入口函数了, 学到这个地方, 我查了一个入口函数的标准定义, 这个函数的标准返回值应该是 DWORD, 不过这函数在 Delphi 的System 单元定义的是: TThreadFunc = function(Parameter: Pointer): Integer;我以后会尽量使用 DWORD 做入口函数的返回值.
  这个返回值有什么用呢?
  等线程退出后, 我们用 GetExitCodeThread 函数获取的退出码就是这个返回值!
  如果线程没有退出, GetExitCodeThread 获取的退出码将是一个常量 STILL_ACTIVE (259); 这样我们就可以通过退出码来判断线程是否已退出.
  还有一个问题: 前面也提到过, 线程函数不能是某个类的方法! 假如我们非要线程去执行类中的一个方法能否实现呢?
  尽管可以用 Addr(类名.方法名) 或 MethodAddress('published 区的方法名') 获取类中方法的地址, 但都不能当做线程的入口函数, 原因可能是因为类中的方法的地址是在实例化为对象时动态分配的.
  后来换了个思路, 其实很简单: 在线程函数中再调用方法不就得了, 估计 TThread 也应该是这样.
  下面的例子就尝试了用线程调用 TForm1 类中的方法, 并测试了退出码的相关问题.
  本例效果图:

代码文件:

unit Unit1;
interface
uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;
type
 TForm1 = class(TForm)
  Button1: TButton;
  Button2: TButton;
  procedure Button1Click(Sender: TObject);
  procedure Button2Click(Sender: TObject);
  private
   procedure FormProc; {准备给线程使用的方法}
 end;
var
 Form1: TForm1;
implementation
{$R *.dfm}
var
 hThread: THandle;
{线程入口函数}
function MyThreadFun(p: Pointer): DWORD; stdcall;
begin
 Form1.FormProc; {调用 TForm1 类的方法}
 Result := 99;  {这个返回值将成为线程的退出代码, 99 是我随意给的数字}
end;
{TForm1 的方法, 本例中是给线程的入口函数调用的}
procedure TForm1.FormProc;
var
 i: Integer;
begin
 for i := 0 to 200000 do
 begin
  with Form1.Canvas do begin
   Lock;
   TextOut(10, 10, IntToStr(i));
   Unlock;
  end;
 end;
end;
{建立并执行线程}
procedure TForm1.Button1Click(Sender: TObject);
var
 ID: DWORD;
begin
 hThread := CreateThread(nil, 0, @MyThreadFun, nil, 0, ID);
end;
{获取线程的退出代码, 并判断线程是否退出}
procedure TForm1.Button2Click(Sender: TObject);
var
 ExitCode: DWORD;
begin
 GetExitCodeThread(hThread, ExitCode);
 if hThread = 0 then
 begin
  Text := '线程还未启动';
  Exit;
 end;
 if ExitCode = STILL_ACTIVE then
  Text := Format('线程退出代码是: %d, 表示线程还未退出', [ExitCode])
 else
  Text := Format('线程已退出, 退出代码是: %d', [ExitCode]);
end;
end.

窗体文件:

object Form1: TForm1
 Left = 0
 Top = 0
 Caption = 'Form1'
 ClientHeight = 84
 ClientWidth = 376
 Color = clBtnFace
 Font.Charset = DEFAULT_CHARSET
 Font.Color = clWindowText
 Font.Height = -11
 Font.Name = 'Tahoma'
 Font.Style = []
 OldCreateOrder = False
 PixelsPerInch = 96
 TextHeight = 13
 object Button1: TButton
  Left = 183
  Top = 32
  Width = 75
  Height = 25
  Caption = 'Button1'
  TabOrder = 0
  OnClick = Button1Click
 end
 object Button2: TButton
  Left = 280
  Top = 32
  Width = 75
  Height = 25
  Caption = 'Button2'
  TabOrder = 1
  OnClick = Button2Click
 end
end