Delphi 线程

界面预览, 实现以上四个功能

1. 新建单元uVar.pas

unit uVar;

interface

uses
  Messages;

const
  UM_ShowMsg = WM_USER + 101;           //页面显示  比如线程向界面发送消息

var
  GMainHandle: THandle;                 //窗体句柄  

implementation

end.

2. 新建单元uPublic.pas

unit uPublic;

interface

uses
  Windows;

procedure ProcessMessage;

implementation

procedure ProcessMessage;
var
  Msg: TMsg;
begin
  if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
  begin
    TranslateMessage(Msg);
    DispatchMessage(Msg);
  end;
end;

end.

3. 新建单元uThread.pas

unit uThread;

interface

uses
  Windows, Classes, SysUtils, ActiveX;

type
  TestThread= class(TThread)
  private
    FPAUSE: boolean;      //暂停标记
    FHandle: THandle;
    FParams: TStringList;
  protected
    procedure Execute; override;
  public
    procedure Pause;
    procedure Goon;
    function IsPaused: Boolean;   //

    constructor Create(AHandle: THandle; bPause: Boolean= False);
    destructor Destroy; override;
  end;

implementation

uses uPublic, uVar;

{ TestThread }

constructor TestThread.Create(AHandle: THandle; bPause: Boolean);
begin
  FPAUSE:= bPause;
  inherited Create(False);
  FHandle := AHandle;
  FParams:= TStringList.Create;
end;

destructor TestThread.Destroy;
begin
  if Assigned(FParams) then
    FreeAndNil(FParams);
  inherited;
end;

procedure TestThread.Execute;
var
  I: Integer;
  sMsg: string;
begin
  inherited;
  CoInitialize(nil);   //如果线程处理内容和数据库有连接 则需要这句
  while (not Terminated) do
  begin
    ProcessMessage;
    if FPAUSE or (not Assigned(FParams)) then
    begin
      Sleep(200);
      Continue;
    end;
    //接下来做任务处理
    //1. 如果是做for循环 则每次循环建议判断FPause一次  以防中途暂停
    for I := 1 to 100 do
    begin
      if FPAUSE then
        Break;
      Sleep(100);
      sMsg:= Format('[%s] 这是第[%d]次循环...', [FormatDateTime('yyyy-MM-dd hh:mm:ss.zzz', Now), I]);
      SendMessage(FHandle, UM_ShowMsg, 8, LongInt(sMsg));
    end;
  end;
  CoUninitialize;    //如果线程处理内容和数据库有连接 则需要这句
end;

procedure TestThread.Goon;
begin
  FPAUSE:= False;
end;

function TestThread.IsPaused: Boolean;
begin
  Result:= FPAUSE;
end;

procedure TestThread.Pause;
begin
  FPAUSE:= True;
end;

end.

4. 主窗体uFrmMain.pas代码如下

unit uFrmMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, uThread, uVar;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
  private
    { Private declarations }
    mThread: TestThread;
  public
    { Public declarations }
    procedure ShowMsgEvent(var Msg: Tmessage); message UM_ShowMsg;  //处理显示消息
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  try
    mThread:= TestThread.Create(GMainHandle, False);
  except
    on e: Exception do
      Raise Exception.Create('线程创建错误:'+E.Message);
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  try
    if not mThread.IsPaused then
      mThread.Pause;
  except
    on e: Exception do
      Raise Exception.Create('线程暂停错误:'+E.Message);
  end;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  try
    if mThread.IsPaused then
      mThread.Goon;
  except
    on e: Exception do
      Raise Exception.Create('线程继续错误:'+E.Message);
  end;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  try
    if Assigned(mThread) then
    begin
      mThread.Terminate;
      mThread.WaitFor;
      FreeAndNil(mThread);
    end;
  except
    on e: Exception do
      Raise Exception.Create('线程释放错误:'+E.Message);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  GMainHandle:= Handle;
end;

procedure TForm1.ShowMsgEvent(var Msg: Tmessage);
begin
  Memo1.Lines.Add(string(Msg.LParam));
end;

end.

5. 工程文件如下:

program DelphiThread;

uses
  Forms,
  uFrmMain in 'uFrmMain.pas' {Form1},
  uThread in 'uThread.pas',
  uPublic in 'uPublic.pas',
  uVar in 'uVar.pas';

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

运行效果:

结束!

2020-09-11 补充

线程里的FHandle是创建时候传递进去的,可以为其加一条属性, 可以随时改变FHandle值,比如:

property _Handle: THandle read FHandle write FHandle;

这样的话,线程里就可以向对应的FHandle所属窗口SendMessage了。

使用场景: 比如程序对接了一个身份证阅读器,全局启动了一个阅读线程去读取,在程序的多个窗口中都需要阅读身份证,那么就可以通过动态设置线程的_Handle属性,读取成功则向对应的_Handle发送消息。 仔细想想,这样确实方便。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值