How to send Email in Delphi?
Today in most of software program it is required to send mail to others with attached data. As some time we need to update clients about their account details, status or any other information through mail. So Delphi provides so many easiest ways to send mail from our Delphi application. I have collected some of ways which are very useful for Delphi developers. In Delphi we don't required any third party components to send mails. We can send mail to single or group of peoples with CC, BCC and attachments. Even we can send HTML mails from Delphi.
So here are the ways...
1. ShellExecute
Sends Email using default mail client software installed on user's system. But it will not work with attachment for every mail client. And you have to use ShellAPI unit in uses list.
nil,
'mailto:' +
'jiten.g.s001@gmail.com' +
'?Subject=Test Message Subject' +
'&Body=Test Message Body',
nil,
nil,
SW_NORMAL);
2. Sending through MS-OutLook mail client with attachment
We can use Delphi's OLE technique to send mail with attachment. But this approach requires Ms OutLook must to be installed in user's system. And need to use OleCtrls, ComObj units
procedure TForm1.btnSendMailClick(Sender: TObject);
const
olMailItem = 0;
var
Outlook: OLEVariant;
MailItem: Variant;
MailInspector : Variant;
stringlist : TStringList;
begin
try
Outlook:=GetActiveOleObject('Outlook.Application') ;
except
Outlook:=CreateOleObject('Outlook.Application') ;
end;
try
Stringlist := TStringList.Create;
MailItem := Outlook.CreateItem(olMailItem) ;
MailItem.Subject := 'subject here';
MailItem.Recipients.Add('jiten.g.s001@gmail.com');
MailItem.CC:='ABC@GMAIL.COM';
MailItem.Attachments.Add('c:\FILE1.txt');
Stringlist := TStringList.Create;
StringList.Add('body here');
MailItem.Body := StringList.text;
MailItem.Send; //SENDS A MAIL WITH OUT OUTLOOK WINDOW. USE "SAVE" FOR DRAFT
{
// TO SHOW OUTLOOK DIALOG. BUT YOU HAVE SET MAILITEM.SEND AS COMMENT
MailInspector := MailItem.GetInspector;
MailInspector.display(FALSE); //true means modal
MailInspector.Send;
}
finally
Outlook := Unassigned;
StringList.Free;
end;
end;
const
olMailItem = 0;
var
Outlook: OLEVariant;
MailItem: Variant;
MailInspector : Variant;
stringlist : TStringList;
begin
try
Outlook:=GetActiveOleObject('Outlook.Application') ;
except
Outlook:=CreateOleObject('Outlook.Application') ;
end;
try
Stringlist := TStringList.Create;
MailItem := Outlook.CreateItem(olMailItem) ;
MailItem.Subject := 'subject here';
MailItem.Recipients.Add('jiten.g.s001@gmail.com');
MailItem.CC:='ABC@GMAIL.COM';
MailItem.Attachments.Add('c:\FILE1.txt');
Stringlist := TStringList.Create;
StringList.Add('body here');
MailItem.Body := StringList.text;
MailItem.Send; //SENDS A MAIL WITH OUT OUTLOOK WINDOW. USE "SAVE" FOR DRAFT
{
// TO SHOW OUTLOOK DIALOG. BUT YOU HAVE SET MAILITEM.SEND AS COMMENT
MailInspector := MailItem.GetInspector;
MailInspector.display(FALSE); //true means modal
MailInspector.Send;
}
finally
Outlook := Unassigned;
StringList.Free;
end;
end;
3. MAPI (Messaging Application Programming Interface)
Delphi provides Windows API MAPI methods and functions to send mail by using MAPI. But this approach only works if the end user have MAPI complient Email software installed on that system. You also need to add MAPI unit in uses clause.
function SendMAPIEmail(const aTo, aCC, aBCC, aAtts: array of string; const body, subject, SenderName, SenderEmail: string;
ShowError: Boolean = true): Integer;
var
SM: TFNMapiSendMail;
MAPIModule: HModule;
Msg: MapiMessage;
lpSender: MapiRecipDesc;
Recips: array of MapiRecipDesc;
Att: array of MapiFileDesc;
p1, p2, p3, LenTo, LenCC, LenBCC, LenAtts: Integer;
sError: String;
begin
try
FillChar(Msg, SizeOf(Msg), 0);
{ get the length of all arrays passed to this function }
LenTo := length(aTo);
if Trim(aCC[0]) <> '' then
LenCC := length(aCC)
else
LenCC := 0;
if Trim(aBCC[0]) <> '' then
LenBCC := length(aBCC)
else
LenBCC := 0;
if Trim(aAtts[0]) <> '' then
LenAtts := length(aAtts)
else
LenAtts := 0;
{ ... }
Setlength(Recips, LenTo + LenCC + LenBCC);
Setlength(Att, LenAtts);
{ to }
for p1 := 0 to LenTo - 1 do
begin
FillChar(Recips[p1], SizeOf(Recips[p1]), 0);
Recips[p1].ulReserved := 0;
Recips[p1].ulRecipClass := MAPI_TO;
{ Upgrade }
Recips[p1].lpszName := pAnsichar(AnsiString(aTo[p1]));
Recips[p1].lpszAddress := '';
end;
{ cc }
for p2 := 0 to LenCC - 1 do
begin
FillChar(Recips[p1 + p2], SizeOf(Recips[p1 + p2]), 0);
Recips[p1 + p2].ulReserved := 0;
Recips[p1 + p2].ulRecipClass := MAPI_CC;
{ Upgrade }
Recips[p1 + p2].lpszName := pAnsichar(AnsiString(aCC[p2]));
Recips[p1 + p2].lpszAddress := '';
end;
{ bcc }
for p3 := 0 to LenBCC - 1 do
begin
FillChar(Recips[p1 + p2 + p3], SizeOf(Recips[p1 + p2 + p3]), 0);
Recips[p1 + p2 + p3].ulReserved := 0;
Recips[p1 + p2 + p3].ulRecipClass := MAPI_BCC;
{ Upgrade }
Recips[p1 + p2 + p3].lpszName := pAnsichar(AnsiString(aBCC[p3]));
Recips[p1 + p2 + p3].lpszAddress := '';
end;
{ atts }
for p1 := 0 to LenAtts - 1 do
begin
FillChar(Att[p1], SizeOf(Att[p1]), 0);
Att[p1].ulReserved := 0;
Att[p1].flFlags := 0;
Att[p1].nPosition := Cardinal($FFFFFFFF);
{ Upgrade }
Att[p1].lpszPathName := pAnsichar(AnsiString(aAtts[p1]));
Att[p1].lpszFileName := '';
Att[p1].lpFileType := nil;
end;
{ fill the message }
with Msg do
begin
ulReserved := 0;
if subject <> '' then
{ Upgrade }
lpszSubject := pAnsichar(AnsiString(subject));
if body <> '' then
{ Upgrade }
lpszNoteText := pAnsichar(AnsiString(body));
if SenderEmail <> '' then
begin
lpSender.ulRecipClass := MAPI_ORIG;
if SenderName = '' then
lpSender.lpszName := pAnsichar(AnsiString(SenderEmail))
else
lpSender.lpszName := pAnsichar(AnsiString(SenderName));
lpSender.lpszAddress := pAnsichar(AnsiString(SenderEmail));
lpSender.ulEIDSize := 0;
lpSender.lpEntryID := nil;
lpOriginator := @lpSender;
end
else
Msg.lpOriginator := nil;
Msg.lpszMessageType := nil;
Msg.lpszDateReceived := nil;
Msg.lpszConversationID := nil;
Msg.flFlags := 0;
Msg.nRecipCount := LenTo + LenCC + LenBCC;
Msg.lpRecips := @Recips[0];
Msg.nFileCount := LenAtts;
Msg.lpFiles := @Att[0];
end;
MAPIModule := LoadLibrary(PWideChar(MAPIDLL));
if MAPIModule = 0 then
Result := -1
else
try
@SM := GetProcAddress(MAPIModule, 'MAPISendMail');
if @SM <> nil then
begin
Result := SM(0, application.Handle, Msg, { MAPI_DIALOG or } MAPI_LOGON_UI, 0);
end
else
Result := 1;
finally
FreeLibrary(MAPIModule);
end;
if Result <> SUCCESS_SUCCESS then
begin
case Result of
MAPI_E_ACCESS_DENIED:
sError := 'Access denied.';
MAPI_E_AMBIGUOUS_RECIPIENT:
sError := 'Ambiguous recipient.';
MAPI_E_ATTACHMENT_NOT_FOUND:
sError := 'Attachment not found.';
MAPI_E_ATTACHMENT_OPEN_FAILURE:
sError := 'Attachment open failure.';
MAPI_E_ATTACHMENT_WRITE_FAILURE:
sError := 'Attachment write failure.';
MAPI_E_BAD_RECIPTYPE:
sError := 'Bad recipient type.';
MAPI_E_DISK_FULL:
sError := 'Disk full.';
MAPI_E_FAILURE:
sError := 'Failure';
MAPI_E_INSUFFICIENT_MEMORY:
sError := 'Insufficient Memory.';
MAPI_E_INVALID_EDITFIELDS:
sError := 'Invalid Editfields.';
MAPI_E_INVALID_MESSAGE:
sError := 'Invalid message.';
MAPI_E_INVALID_RECIPS:
sError := 'Invalid recipients.';
MAPI_E_INVALID_SESSION:
sError := 'Invalid session.';
MAPI_E_LOGIN_FAILURE:
sError := 'Login failure.';
MAPI_E_MESSAGE_IN_USE:
sError := 'Message in use.';
MAPI_E_NETWORK_FAILURE:
sError := 'Network failure.';
MAPI_E_NO_MESSAGES:
sError := 'No messages.';
MAPI_E_NOT_SUPPORTED:
sError := 'Not supported.';
MAPI_E_TEXT_TOO_LARGE:
sError := 'Text too large.';
MAPI_E_TOO_MANY_FILES:
sError := 'Too many files.';
MAPI_E_TOO_MANY_RECIPIENTS:
sError := 'Too many recipients.';
MAPI_E_TOO_MANY_SESSIONS:
sError := 'Too many sessions.';
MAPI_E_TYPE_NOT_SUPPORTED:
sError := 'Type not supported.';
MAPI_E_UNKNOWN_RECIPIENT:
sError := 'Unknown Recipient';
MAPI_E_USER_ABORT:
sError := 'User Aborted';
end;
if sError <> '' then
begin
MessageDlg('Could not send email. ' + sError, mtInformation, [mbOk], 0);
Exit;
end;
end;
finally
end;
end;
ShowError: Boolean = true): Integer;
var
SM: TFNMapiSendMail;
MAPIModule: HModule;
Msg: MapiMessage;
lpSender: MapiRecipDesc;
Recips: array of MapiRecipDesc;
Att: array of MapiFileDesc;
p1, p2, p3, LenTo, LenCC, LenBCC, LenAtts: Integer;
sError: String;
begin
try
FillChar(Msg, SizeOf(Msg), 0);
{ get the length of all arrays passed to this function }
LenTo := length(aTo);
if Trim(aCC[0]) <> '' then
LenCC := length(aCC)
else
LenCC := 0;
if Trim(aBCC[0]) <> '' then
LenBCC := length(aBCC)
else
LenBCC := 0;
if Trim(aAtts[0]) <> '' then
LenAtts := length(aAtts)
else
LenAtts := 0;
{ ... }
Setlength(Recips, LenTo + LenCC + LenBCC);
Setlength(Att, LenAtts);
{ to }
for p1 := 0 to LenTo - 1 do
begin
FillChar(Recips[p1], SizeOf(Recips[p1]), 0);
Recips[p1].ulReserved := 0;
Recips[p1].ulRecipClass := MAPI_TO;
{ Upgrade }
Recips[p1].lpszName := pAnsichar(AnsiString(aTo[p1]));
Recips[p1].lpszAddress := '';
end;
{ cc }
for p2 := 0 to LenCC - 1 do
begin
FillChar(Recips[p1 + p2], SizeOf(Recips[p1 + p2]), 0);
Recips[p1 + p2].ulReserved := 0;
Recips[p1 + p2].ulRecipClass := MAPI_CC;
{ Upgrade }
Recips[p1 + p2].lpszName := pAnsichar(AnsiString(aCC[p2]));
Recips[p1 + p2].lpszAddress := '';
end;
{ bcc }
for p3 := 0 to LenBCC - 1 do
begin
FillChar(Recips[p1 + p2 + p3], SizeOf(Recips[p1 + p2 + p3]), 0);
Recips[p1 + p2 + p3].ulReserved := 0;
Recips[p1 + p2 + p3].ulRecipClass := MAPI_BCC;
{ Upgrade }
Recips[p1 + p2 + p3].lpszName := pAnsichar(AnsiString(aBCC[p3]));
Recips[p1 + p2 + p3].lpszAddress := '';
end;
{ atts }
for p1 := 0 to LenAtts - 1 do
begin
FillChar(Att[p1], SizeOf(Att[p1]), 0);
Att[p1].ulReserved := 0;
Att[p1].flFlags := 0;
Att[p1].nPosition := Cardinal($FFFFFFFF);
{ Upgrade }
Att[p1].lpszPathName := pAnsichar(AnsiString(aAtts[p1]));
Att[p1].lpszFileName := '';
Att[p1].lpFileType := nil;
end;
{ fill the message }
with Msg do
begin
ulReserved := 0;
if subject <> '' then
{ Upgrade }
lpszSubject := pAnsichar(AnsiString(subject));
if body <> '' then
{ Upgrade }
lpszNoteText := pAnsichar(AnsiString(body));
if SenderEmail <> '' then
begin
lpSender.ulRecipClass := MAPI_ORIG;
if SenderName = '' then
lpSender.lpszName := pAnsichar(AnsiString(SenderEmail))
else
lpSender.lpszName := pAnsichar(AnsiString(SenderName));
lpSender.lpszAddress := pAnsichar(AnsiString(SenderEmail));
lpSender.ulEIDSize := 0;
lpSender.lpEntryID := nil;
lpOriginator := @lpSender;
end
else
Msg.lpOriginator := nil;
Msg.lpszMessageType := nil;
Msg.lpszDateReceived := nil;
Msg.lpszConversationID := nil;
Msg.flFlags := 0;
Msg.nRecipCount := LenTo + LenCC + LenBCC;
Msg.lpRecips := @Recips[0];
Msg.nFileCount := LenAtts;
Msg.lpFiles := @Att[0];
end;
MAPIModule := LoadLibrary(PWideChar(MAPIDLL));
if MAPIModule = 0 then
Result := -1
else
try
@SM := GetProcAddress(MAPIModule, 'MAPISendMail');
if @SM <> nil then
begin
Result := SM(0, application.Handle, Msg, { MAPI_DIALOG or } MAPI_LOGON_UI, 0);
end
else
Result := 1;
finally
FreeLibrary(MAPIModule);
end;
if Result <> SUCCESS_SUCCESS then
begin
case Result of
MAPI_E_ACCESS_DENIED:
sError := 'Access denied.';
MAPI_E_AMBIGUOUS_RECIPIENT:
sError := 'Ambiguous recipient.';
MAPI_E_ATTACHMENT_NOT_FOUND:
sError := 'Attachment not found.';
MAPI_E_ATTACHMENT_OPEN_FAILURE:
sError := 'Attachment open failure.';
MAPI_E_ATTACHMENT_WRITE_FAILURE:
sError := 'Attachment write failure.';
MAPI_E_BAD_RECIPTYPE:
sError := 'Bad recipient type.';
MAPI_E_DISK_FULL:
sError := 'Disk full.';
MAPI_E_FAILURE:
sError := 'Failure';
MAPI_E_INSUFFICIENT_MEMORY:
sError := 'Insufficient Memory.';
MAPI_E_INVALID_EDITFIELDS:
sError := 'Invalid Editfields.';
MAPI_E_INVALID_MESSAGE:
sError := 'Invalid message.';
MAPI_E_INVALID_RECIPS:
sError := 'Invalid recipients.';
MAPI_E_INVALID_SESSION:
sError := 'Invalid session.';
MAPI_E_LOGIN_FAILURE:
sError := 'Login failure.';
MAPI_E_MESSAGE_IN_USE:
sError := 'Message in use.';
MAPI_E_NETWORK_FAILURE:
sError := 'Network failure.';
MAPI_E_NO_MESSAGES:
sError := 'No messages.';
MAPI_E_NOT_SUPPORTED:
sError := 'Not supported.';
MAPI_E_TEXT_TOO_LARGE:
sError := 'Text too large.';
MAPI_E_TOO_MANY_FILES:
sError := 'Too many files.';
MAPI_E_TOO_MANY_RECIPIENTS:
sError := 'Too many recipients.';
MAPI_E_TOO_MANY_SESSIONS:
sError := 'Too many sessions.';
MAPI_E_TYPE_NOT_SUPPORTED:
sError := 'Type not supported.';
MAPI_E_UNKNOWN_RECIPIENT:
sError := 'Unknown Recipient';
MAPI_E_USER_ABORT:
sError := 'User Aborted';
end;
if sError <> '' then
begin
MessageDlg('Could not send email. ' + sError, mtInformation, [mbOk], 0);
Exit;
end;
end;
finally
end;
end;
4. Using INDY components (TIDSMTP, TIdMessage)
Delphi provides indy component TIDSMTP to send emails from our application. We just need to put these components on our form and need to set some properties. You can find this component in Indy Clients tab and Indy Misc tab of component palate.
TIDSMTP - component is used to connect and communicate with a SMTP server
TIDMessage - component is used to store and encode Email message details like body, to, cc, bcc, and attachments.
In this example I have used GMAIL SMTP server to send mails. So please change host name to different when required.
Put following Indy components on your form. Then all the setting are done at runtime on Send button click.
Uses
IdEMailAddress, IdGlobal, IdAttachmentFile;
....
var
IdSMTP1: TIdSMTP;IdMessage1: TIdMessage;
IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL; // to allow SSL authenticate //
....
procedure TFormEmail.btnSendEmailClick(Sender: TObject);
var
Attachmentfile: TIdAttachmentFile;
begin
// IO HANDLER SETTINGS //
With IdSSLIOHandlerSocketOpenSSL1 do
begin
Destination := 'smtp.gmail.com:587';
Host := 'smtp.gmail.com';
MaxLineAction := maException;
Port := 587;
SSLOptions.Method := sslvTLSv1;
SSLOptions.Mode := sslmUnassigned;
SSLOptions.VerifyMode := [];
SSLOptions.VerifyDepth := 0;
end;
//SETTING SMTP COMPONENT DATA //
IdSMTP1.Host := 'smtp.gmail.com';
IdSMTP1.Port := 587;
IdSMTP1.Username := yourGmailaddress@gmail.com; // please change to your gmail address //
IdSMTP1.Password := 'yourGmailPassword';
IdSMTP1.IOHandler := IdSSLIOHandlerSocketOpenSSL1;
IdSMTP1.AuthType := satDefault;
IdSMTP1.UseTLS := utUseExplicitTLS;
// SETTING email MESSAGE DATA //
IdMessage1.Clear;
// add recipient list //
with IdMessage1.Recipients.Add do
begin
Name := 'Recipient 1';
Address := Recipient1@email.com; // please change email address as required //
end;
// add CC list //
with IdMessage1.CCList.Add do
begin
Name := 'CC Recipient 1';
Address := CCRecipient1@email.com; // please change email address as required //
end;
//add BCC list //
with IdMessage1.BCCList.Add do
begin
Name := 'BCC Recipient 1';
Address := BCCRecipient1@email.com; // please change email address as required //
end;
//add Attachment to mail //
Attachmentfile := TIdAttachmentFile.Create(IdMessage1.MessageParts,'C:\File1.txt');
IdMessage1.From.Address := yourGmailaddress@gmail.com; // please change to your gmail address //;
IdMessage1.Subject := 'Test Email Subject';
IdMessage1.Body := 'Test Email Body';
IdMessage1.Priority := mpHigh;
TRY
IdSMTP1.Connect();
IdSMTP1.Send(IdMessage1);
ShowMessage('Email sent');
IdSMTP1.Disconnect();
except on e:Exception do
begin
ShowMessage(e.Message);
IdSMTP1.Disconnect();
end;
END;
AttachmentFile.Free;
end;
Thanks for the article. What version of Delphi do you use? I use Delphi 7, there is no object TIdSSLIOHandlerSocketOpenSSL, only found TIdSSLIOHandlerSocket.
ReplyDeleteI got an error in declaration of class TIdSSLIOHandlerSocketOpenSSL when compiling the code, saying : Undeclared identifier: 'TIdSSLIOHandlerSocketOpenSSL'
thank you worked very well on delphi 10.2 managed to find TIdSSLIOHandlerSocketOpenSSL and it sent the message, on gmail you might have to switch on Less secure app access
DeleteContact MS Office setup with MS Office setup Assistance Experts If you want to know, how to Improve Unsaved MS Office Data? Dial Office.com/setup and update your MS Office setup to use all functions. https://office-setup.us/
ReplyDeletenot worked
ReplyDeleteNice Information...
ReplyDeleteThanks for Sharing...
The AT&T company started to provide the AT&T Email Login Service after it got partnered with the SBCGlobal company and the Yahoo company. Sometimes, the AT&T email login may also be known as the SBCGlobal email login.
Great Article, Thanks but let us know about to send an HTML (HTML body) which is consist by images. Thanks again.
ReplyDeleteThanks for the article.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteGood morning!
ReplyDeleteThank you very much for your article, which helped me a lot to integrate my Delphi application with OutLook, automatically generating emails.
Hugs