2015-11-10 21 views
2

如何發送郵件(TOmniMessage)從後臺任務到主窗體?如何發送郵件從後臺任務到MainForm(OmniThreadLibrary)

我想發送的後續消息的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. 

回答

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.