Solved

Sending Mail through Delphi via Default Email Application

Posted on 2010-11-16
5
1,250 Views
Last Modified: 2012-05-10
I am looking at ways to send e-mail via the default mail application through Delphi. I am currently using MAPI to open the e-mail program (SendMail). The problem I am running into is that the window is opening up Modal. I would like to open the form as a normal form and be able to still open and use other windows. I could use ShellAPI to open the e-mail program, but I have read this has problems sending attachments.

Any thoughts on what is the best way to go or how you can use MAPI to open the e-mail Window not modally? Thanks for the insight.
0
Comment
Question by:aceswildab1
5 Comments
 
LVL 11

Expert Comment

by:David Kroll
ID: 34149492
If you just want to open the default mail application, just use ShellExecute.

http://www.latiumsoftware.com/en/delphi/00041.php
0
 
LVL 32

Accepted Solution

by:
ewangoya earned 500 total points
ID: 34151760
Try running it in a thread. This will let your apllication continue to function while the dialog is displayed
Here is a simple example
unit Unit3;



interface



uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, StdCtrls;



type

  TMessageSentEvent = procedure(const AResult: Integer; const AError: string) of Object;



  TMAPIThread = class(TThread)

  private

    FErrorMessage: string;

    FMessageSent: TMessageSentEvent;

    FReceiverName, FReceiverAddress, FSenderName, FSenderAddress, FSubject, FBody: AnsiString;

    FSendResult: Integer;

    procedure DoneSend;

  public

    constructor Create(const AReceiverName, AReceiverAddress, ASenderName,

      ASenderAddress, ASubject, ABody: AnsiString; AMessageSent: TMessageSentEvent);

    procedure Execute; override;

  end;



  TForm3 = class(TForm)

    Button1: TButton;

    procedure Button1Click(Sender: TObject);

  private

    FDialogVisible: Boolean;

    FMAPIThread: TMAPIThread;

    procedure MessageSent(const AResult: Integer; const AError: string);

  public

    { Public declarations }

  end;



var

  Form3: TForm3;



implementation



{$R *.dfm}



uses

  MAPI;



  { TMAPIThread }



constructor TMAPIThread.Create(const AReceiverName, AReceiverAddress,

  ASenderName, ASenderAddress, ASubject, ABody: AnsiString;

  AMessageSent: TMessageSentEvent);

begin

  FMessageSent := AMessageSent;

  FReceiverName := AReceiverName;

  FReceiverAddress :=AReceiverAddress;

  FSenderName := ASenderName;

  FSenderAddress := ASenderAddress;

  FSubject := ASubject;

  FBody := ABody;

  FreeOnTerminate := True;



  inherited Create(False);

end;



procedure TMAPIThread.DoneSend;

begin

  if Assigned(FMessageSent) then

    FMessageSent(FSendResult, FErrorMessage);

end;



procedure TMAPIThread.Execute;

var

  MapiMessage: TMapiMessage;

  MsgSender, MsgTarget: TMapiRecipDesc;

  PReceiverName, PReceiverAddress, PSenderName, PSenderAddress, PSubject, PBody: PAnsiChar;

begin

  FillChar(MapiMessage, SizeOf(MapiMessage), 0);

  FillChar(MsgTarget, SizeOf(MsgTarget), 0);

  FillChar(MsgSender, SizeOf(MsgSender), 0);



  //Receiver

  PReceiverAddress := PAnsiChar('SMTP: ' + FReceiverAddress);

  PReceiverName := PAnsiChar(FReceiverName);

  MsgTarget.lpszAddress := PAnsiChar(FReceiverAddress);

  MsgTarget.lpszName := PAnsiChar(FReceiverName);

  MsgTarget.ulRecipClass := MAPI_TO;

  MapiMessage.nRecipCount := 1;

  MapiMessage.lpRecips := @MsgTarget;



  //Sender

  PSenderAddress := PAnsiChar(FSenderAddress);

  PSenderName := PAnsiChar(FSenderName);

  MsgSender.lpszAddress := PAnsiChar(FSenderAddress);

  MsgSender.lpszName := PAnsiChar(FSenderName);

  MsgSender.ulRecipClass := MAPI_ORIG;

  MapiMessage.lpOriginator := @MsgSender;



  //Subject

  PSubject := PAnsiChar(FSubject);

  MapiMessage.lpszSubject := PSubject;



  //Body

  PBody := PAnsiChar(FBody);

  MapiMessage.lpszNoteText := PBody;



  try

    try

      FSendResult := Mapi.MapiSendMail(0, 0, MapiMessage, MAPI_DIALOG or MAPI_LOGON_UI or MAPI_NEW_SESSION or MAPI_ALLOW_OTHERS, 0);

    except

      on E: Exception do

        FErrorMessage := E.Message;

    end;

  finally

    Synchronize(DoneSend);

  end;

end;



{ TForm3 }



procedure TForm3.Button1Click(Sender: TObject);

begin

  Button1.Enabled := False;

  FDialogVisible := True;

  FMAPIThread := TMAPIThread.Create('Joh Doe', 'johndoe@email.com', 'Jane DOe',

      'janedoe@email.com', 'Hello', 'Hello', MessageSent);

end;



procedure TForm3.MessageSent(const AResult: Integer; const AError: string);

begin

  FMapiThread.Terminate;

  FDialogVisible := False;

  Button1.Enabled := True;

end;



end.

Open in new window

0
 
LVL 19

Expert Comment

by:Thommy
ID: 34152915
If your mail application is OUTLOOK, you can easily control it by OLE automation...
procedure SendMailViaOutlook;

const

  OutlookItemType = 0;  //olMailItem

var

  Outlook: OleVariant;

  TheMailItem: variant;

begin

  try

    try

      //connect running outlook instance

      Outlook := GetActiveOleObject('Outlook.Application');

    except

      //start new outlook instance

      Outlook := CreateOleObject('Outlook.Application');

    end;



    TheMailItem := Outlook.CreateItem(OutlookItemType);

    TheMailItem.Recipients.Add('MailAdress@gmx.com');

    TheMailItem.Subject := 'This is an e-mail sent by Delphi app using OutLook...';

    TheMailItem.Body := 'Body text...';

    TheMailItem.Attachments.Add('c:\test\attachment.txt');



    TheMailItem.Send;

  finally

    VarClear(Outlook);

  end;

end;

Open in new window

0
 
LVL 24

Expert Comment

by:jimyX
ID: 34153513
I doubt that works, I mean to perform MAPISendMail and get back to use the caller application before it is closed. Unless you are using thread, as shown by ewangoya.

I can provide you code that allows to disable modal effects and enable you get back to the main form even if there is another Form showing by modal and it works fine, but when you use that in any application that's calling SendMail the email application will block the I/O of your application until it's done and the email application is closed.
By applying the code that disables the modal restriction you will be able to activate your application and get the focus on it but you will not be able to click a button or even if you have timer there it will be disabled until the e-mail application is closed and the control is returned back to the caller application.

I have tried this on the OutLook and the Lotus Notes and same behavior in both applications.

So in short words that is not possible if it involves e-mail application unless using thread.
0
 

Author Closing Comment

by:aceswildab1
ID: 34187479
The thread has been the best answer I've seen so far. It still opens Outlook/E-mail program modally, but it does open up the calling program to allow it to run. Thanks for the help!
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
groupSumClump challenge 9 103
Delphi 2 51
what is the main difference between git clone and fetch ann pull and push commands 2 74
C# code editing and collaboration 3 100
Explore the encryption capabilities built into Google Apps and how these features can help you meet privacy policy and regulatory compliance, but are not a full solution. Understand and compare the most popular email encryption services for Google A…
We are happy to announce a brand new addition to our line of acclaimed email signature management products – CodeTwo Email Signatures for Office 365.
The purpose of this video is to demonstrate how to set up Lists in Mailchimp. This will be demonstrated using a Windows 8 PC. Mailchimp will be used. Log into your Mailchimp account. : Click on Lists. Click on Create List Button : Choose the desi…
This tutorial gives a high-level tour of the interface of Marketo (a marketing automation tool to help businesses track and engage prospective customers and drive them to purchase). You will see the main areas including Marketing Activities, Design …

863 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

Need Help in Real-Time?

Connect with top rated Experts

27 Experts available now in Live!

Get 1:1 Help Now