Sending non blocking mail with MAPI

How can i send a non blocking mail with MAPI ?

I know the MapiSendMail but this function blocks until the user has sent the mail or aborted the send process.

I would like to do the same like MapiSendMail (Subject, Body, Address, Attachments) but the function should return immediatly)

thanxs
Andreas
Dev6Asked:
Who is Participating?
 
MindphaserCommented:
Force accepted

** Mindphaser - Community Support Moderator **
0
 
Lee_NoverCommented:
you could run it in a separate thread

a small nontested example:

unit Unit1;

interface

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

type
  TSendMailThread = class(TThread)
  private
    FSubject,
    FBody,
    FAddress,
    FAttachments: string;

    procedure Execute; override;
  public
    constructor Create(const Subject, Body, Address, Attachments: string);
  end;

  TForm1 = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TSendMailThread }

procedure SendMail(const Subject, Body, Address, Attachments: string);
begin
     TSendMailThread.Create(Subject, Body, Address, Attachments: string);
end;

constructor TSendMailThread.Create(const Subject, Body, Address, Attachments: string);
begin
     FSubject:=Subject;
     FBody:=Body;
     FAddress:=Address;
     FAttachments:=Attachments;
     FreeOnTerminate:=true;
     inherited Create(false);
end;

procedure TSendMailThread.Execute;
begin
     // replace this with your code to send the mail
     //MyMapiSenMail(FSubject, FBody, FAddress, FAttachments);
end;

end.
0
 
Lee_NoverCommented:
eh couldn't help it to test it :)

this is correct:

type
  TSendMailThread = class(TThread)
  private
    FSubject,
    FBody,
    FAddress,
    FAttachments: string;
  protected
    procedure Execute; override;
  public
    constructor Create(const Subject, Body, Address, Attachments: string);
  end;




and :



procedure SendMail(const Subject, Body, Address, Attachments: string);
begin
     TSendMailThread.Create(Subject, Body, Address, Attachments);
end;


:)
0
Cloud Class® Course: Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

 
Dev6Author Commented:
Doesn't work !
The calling applicaiton stills wait for the MAPI finishing !

This is very strange ....

I tried (for testing if the part with the thread works) to put a showmessage after the call to my SendMail
When i click the button, i get the showmessage and the Outlook form, now i can click on my form and do all what i want. If i remove the ShowMessage, the apllication waits for the MAPI !

0
 
Lee_NoverCommented:
weird ..
can you give me the mail sending code to check it out ?
0
 
Dev6Author Commented:
This is the code, with your modified Execute ...

procedure TSendMailThread.Execute;
begin
    SendMail(FAddress, FSubject, FBody, FAttachments, TRUE);
end;


function SendEMailToMAPI(Handle : THandle; Mail : TStrings) : Cardinal;
type
    TAttachAccessArray = array[0..0] OF TMapiFileDesc;
    PAttachAccessArray = ^TAttachAccessArray;
var MapiMessage : TMapiMessage;
    Receip      : TMapiRecipDesc;
    Attachments : PAttachAccessArray;
    AttachCount : integer;
    iCount      : integer;
    FileName    : string;
begin
    FillChar(MapiMessage, SizeOf(MapiMessage), #0);
    Attachments   := nil;
    FillChar(Receip, SizeOf(Receip), #0);
    if Mail.Values['to'] <> '' then begin
        Receip.ulReserved   := 0;
        Receip.ulRecipClass := MAPI_TO;
        Receip.lpszName     := StrNew(PChar(Mail.Values['to']));
        Receip.lpszAddress  := StrNew(PChar('SMTP:' + Mail.Values['to']));
        Receip.ulEIDSize    := 0;
        MapiMessage.nRecipCount := 1;
        MapiMessage.lpRecips    := @Receip;
    end;

    AttachCount := 0;
    for iCount := 0 to MaxInt do begin
        if Mail.Values['Attachment' + IntToStr(iCount)] = '' then break;
        AttachCount := AttachCount + 1;
    end;

    if AttachCount > 0 then begin
        GetMem(Attachments,SizeOf(TMapiFileDesc) * AttachCount);
        for iCount := 0 to (AttachCount - 1) do begin
            FileName                            := Mail.Values['Attachment' + IntToStr(iCount)];
            Attachments[iCount].ulReserved      := 0;
            Attachments[iCount].flFlags         := 0;
            Attachments[iCount].nPosition       := ULONG($FFFFFFFF);
            Attachments[iCount].lpszPathName    := StrNew(PChar(FileName));
            Attachments[iCount].lpszFileName    := StrNew(PChar(ExtractFileName(FileName)));
            Attachments[iCount].lpFileType      := nil;
        end;
        MapiMessage.nFileCount  := AttachCount;
        MapiMessage.lpFiles     := @Attachments^;
    end;

    if Mail.Values['subject'] <> '' then
        MapiMessage.lpszSubject := StrNew(PChar(Mail.Values['subject']));
    if Mail.Values['body'] <> '' then
        MapiMessage.lpszNoteText := StrNew(PChar(Mail.Values['body']));

    Result := MapiSendMail(0, Handle, MapiMessage, MAPI_DIALOG*Ord(Handle <> 0) OR MAPI_LOGON_UI OR MAPI_NEW_SESSION, 0);

    for iCount := 0 to (AttachCount - 1) do begin
        strDispose(Attachments[iCount].lpszPathName);
        strDispose(Attachments[iCount].lpszFileName);
    end;

    if assigned(MapiMessage.lpszSubject)    then strDispose(MapiMessage.lpszSubject);
    if assigned(MapiMessage.lpszNoteText)   then strDispose(MapiMessage.lpszNoteText);
    if assigned(Receip.lpszAddress)         then strDispose(Receip.lpszAddress);
    if assigned(Receip.lpszName)            then strDispose(Receip.lpszName);
end;



function SendMAPIMail(Addr, Subject, Body : string; Attachments : string) : Boolean;
var Mail        : TStringList;
    i           : integer;
    Res         : integer;
begin
    Mail        := TStringList.Create;
    Mail.Values['To']           := Addr;
    Mail.Values['Subject']      := Subject;
    if length(Body) > 0 then
        Mail.Values['Body']         := Body;
    i                           := 0;
    with THostParser.Create(Attachments, #0) do begin
        while IsValid do begin
            Mail.Values['Attachment'+IntToStr(i)]   := GetValue;
            inc(i);
        end;
        Free;
    end;
    Res := SendEMailToMAPI(Application.Handle, Mail);
    case Res of
        MAPI_E_AMBIGUOUS_RECIPIENT      : LastError := 'A recipient matched more than one of the recipient descriptor structures and MAPI_DIALOG was not set. No message was sent.';
        MAPI_E_ATTACHMENT_NOT_FOUND     : LastError := 'The specified attachment was not found. No message was sent.';
        MAPI_E_ATTACHMENT_OPEN_FAILURE  : LastError := 'The specified attachment could not be open; no message was sent.';
        MAPI_E_BAD_RECIPTYPE            : LastError := 'The type of a recipient was not MAPI_TO, MAPI_CC, or MAPI_BCC. No message was sent.';
        MAPI_E_FAILURE                  : LastError := 'One or more unspecified errors occurred; no message was sent.';
        MAPI_E_INSUFFICIENT_MEMORY      : LastError := 'There was insufficient memory to proceed. No message was sent.';
        MAPI_E_LOGIN_FAILURE            : LastError := 'There was no default logon, and the user failed to log on successfully when the logon dialog box was displayed. No message was sent.';
        MAPI_E_TEXT_TOO_LARGE           : LastError := 'The text in the message was too large to sent; the message was not sent.';
        MAPI_E_TOO_MANY_FILES           : LastError := 'There were too many file attachments; no message was sent.';
        MAPI_E_TOO_MANY_RECIPIENTS      : LastError := 'There were too many recipients; no message was sent.';
        MAPI_E_UNKNOWN_RECIPIENT        : LastError := 'A recipient did not appear in the address list; no message was sent.';
        MAPI_E_USER_ABORT               : LastError := 'The user canceled one of the dialog boxes; no message was sent.';
        SUCCESS_SUCCESS                 : LastError := 'Alles OK';
    end;
    Result  := Res = SUCCESS_SUCCESS;
    Mail.Free;
end;

function SendMail(Addr, Subject, Body : string; Attachments : string; DoWait : Boolean = FALSE) : Boolean;
begin
    if DoWait then  Result  := SendMAPIMail(Addr, Subject, Body, Attachments)
    else begin
        try
            TSendMailThread.Create(Addr, Subject, Body, Attachments);
            Result  := TRUE;
        except
            Result  := FALSE;
        end;
    end;
end;
0
 
Lee_NoverCommented:
will check it out a bit later
hold on :)
0
 
pnh73Commented:
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

PAQ with No Refund

Please leave any comments here within the next seven days.
 
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
 
Paul (pnh73)
EE Cleanup Volunteer
0
 
genii_thCommented:
how to use?
what ?????  THostParser >>>> with THostParser.Create(Attachments, #0) do begin  
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.