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

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发送消息。 仔细想想,这样确实方便。
1769

被折叠的 条评论
为什么被折叠?



