Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Sending non blocking mail with MAPI

Posted on 2002-06-04
9
Medium Priority
?
984 Views
Last Modified: 2010-08-05
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
0
Comment
Question by:Dev6
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
9 Comments
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7054877
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
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7054888
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
 

Author Comment

by:Dev6
ID: 7055804
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7055824
weird ..
can you give me the mail sending code to check it out ?
0
 

Author Comment

by:Dev6
ID: 7055833
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
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7055860
will check it out a bit later
hold on :)
0
 
LVL 1

Expert Comment

by:pnh73
ID: 9010451
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
 
LVL 6

Accepted Solution

by:
Mindphaser earned 0 total points
ID: 9101846
Force accepted

** Mindphaser - Community Support Moderator **
0
 

Expert Comment

by:genii_th
ID: 9239118
how to use?
what ?????  THostParser >>>> with THostParser.Create(Attachments, #0) do begin  
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Suggested Courses

604 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question