gpt4 book ai didi

delphi - 如何将消息从后台任务发送到 MainForm (OmniThreadLibrary)

转载 作者:行者123 更新时间:2023-12-01 22:18:56 26 4
gpt4 key购买 nike

如何从后台任务向主窗体发送消息 (TOmniMessage)?

我想向 Mainform 发送以下消息:

Memo1.Lines.Add(Format('BEGIN: %s', [msg.MsgData.CastToStringDef('')]));

ma​​in.pas(主窗体)

unit main;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,
Beep;

type
TfrmDemoParallelAsync = class(TForm)
btnAsync: TButton;
Memo1: TMemo;
procedure btnAsyncClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
public
end;

var
frmDemoParallelAsync: TfrmDemoParallelAsync;
fBeep: TBeep;

implementation

{$R *.dfm}

procedure TfrmDemoParallelAsync.FormCreate(Sender: TObject);
begin
fBeep := TBeep.Create;
fBeep.CanClose := True;
end;

procedure TfrmDemoParallelAsync.FormDestroy(Sender: TObject);
begin
fBeep.Free;
end;

procedure TfrmDemoParallelAsync.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if fBeep.CanClose then
Action := caFree
else
Action := caNone;
end;

procedure TfrmDemoParallelAsync.btnAsyncClick(Sender: TObject);
begin
fBeep.CanClose := false;
//btnAsync.Enabled := false;

fBeep.BackgroundTask;
end;

end.

beep.pas(后台任务)

unit Beep;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils,
OtlComm, OtlTask, OtlTaskControl, OtlParallel;

const
WM_MESSAGE_BEGIN = WM_USER + 1;
WM_MESSAGE_END = WM_USER + 2;

type
TBeep = class
private
procedure BeepEventHandler(const task: IOmniTaskControl; const msg: TOmniMessage);
public
CanClose: Boolean;
procedure BackgroundTask;
end;

implementation

procedure TBeep.BackgroundTask;
begin
CanClose := false;

Parallel.Async(
procedure(const task: IOmniTask)
begin
task.Comm.Send(WM_MESSAGE_BEGIN, 'Background Task ' + GetCurrentThreadID.ToString() + ' started');
// executed in background thread
Sleep(5000);
MessageBeep($FFFFFFFF);
task.Comm.Send(WM_MESSAGE_END, 'Background Task ' + GetCurrentThreadID.ToString() + ' ended');
end,
// executed in main thread
Parallel.TaskConfig.Onmessage(BeepEventHandler));
end;

procedure TBeep.BeepEventHandler(const task: IOmniTaskControl; const msg: TOmniMessage);
begin

//if msg.MsgID = WM_MESSAGE_BEGIN then
// Memo1.Lines.Add(Format('BEGIN: %s', [msg.MsgData.CastToStringDef('')]));

if msg.MsgID = WM_MESSAGE_END then
begin
//Memo1.Lines.Add(Format('END: %s', [msg.MsgData.CastToStringDef('')]));
CanClose := True;
end;
end;

end.

最佳答案

这是一个示例代码,包含 MainForm 中的所有功能。效果很好。

我想将 BackgrounTask 移动到它自己的类中。

ma​​in.pas(主窗体):

unit main;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,
OtlComm, OtlTask, OtlTaskControl, OtlParallel;

const
WM_MESSAGE_BEGIN = WM_USER + 1;
WM_MESSAGE_END = WM_USER + 2;

type
TfrmDemoParallelAsync = class(TForm)
btnAsync: TButton;
Memo1: TMemo;
procedure btnAsyncClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
CanClose: Boolean;
procedure BeepEventHandler(const task: IOmniTaskControl; const msg: TOmniMessage);
public
end;

var
frmDemoParallelAsync: TfrmDemoParallelAsync;

implementation

{$R *.dfm}

procedure TfrmDemoParallelAsync.FormCreate(Sender: TObject);
begin
CanClose := True;
end;

procedure TfrmDemoParallelAsync.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if CanClose then
Action := caFree
else
Action := caNone;
end;

procedure TfrmDemoParallelAsync.btnAsyncClick(Sender: TObject);
begin
CanClose := false;
btnAsync.Enabled := false;

Parallel.Async(
procedure(const task: IOmniTask)
begin
task.Comm.Send(WM_MESSAGE_BEGIN, 'Background Task ' + GetCurrentThreadID.ToString() + ' started');
// executed in background thread
Sleep(5000);
MessageBeep($FFFFFFFF);
task.Comm.Send(WM_MESSAGE_END, 'Background Task ' + GetCurrentThreadID.ToString() + ' ended');
end,
// executed in main thread
Parallel.TaskConfig.Onmessage(BeepEventHandler));
end;

procedure TfrmDemoParallelAsync.BeepEventHandler(const task: IOmniTaskControl; const msg: TOmniMessage);
begin

if msg.MsgID = WM_MESSAGE_BEGIN then
Memo1.Lines.Add(Format('BEGIN: %s', [msg.MsgData.CastToStringDef('')]));

if msg.MsgID = WM_MESSAGE_END then
begin
Memo1.Lines.Add(Format('END: %s', [msg.MsgData.CastToStringDef('')]));
btnAsync.Enabled := True;
CanClose := True;
end;
end;

end.

关于delphi - 如何将消息从后台任务发送到 MainForm (OmniThreadLibrary),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33640398/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com