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

时间:2015-11-10 21:56:07

标签: delphi omnithreadlibrary

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

我想向Mainform发送关注消息:

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

main.pas(MainForm)

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.

1 个答案:

答案 0 :(得分:0)

以下是MainForm中包含所有功能的示例代码。效果很好。

我想在自己的类中移动BackgrounTask。

main.pas(MainForm):

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.