Solved

Smoothest way to send Email via Delphi

Posted on 2010-09-14
4
658 Views
Last Modified: 2013-11-23
Hi,

I need to send email from my application (with small attachment) with either of two options.
1) Via default Email Handler (Even if it is not running) (alternatively can I know default handler is not running)
or
2) Directly
How can I do this without windows popping up ugly messages.

I use Delphi 2007


Regards
Allan


0
Comment
Question by:Allan_Fernandes
  • 2
4 Comments
 
LVL 25

Accepted Solution

by:
epasquier earned 125 total points
ID: 33671697
The easiest way to integrate mail in Delphi app is with Indy components.

Here is a datamodule to get/send emails
Mails.zip
0
 
LVL 1

Expert Comment

by:udhna
ID: 33671988
If you want to send with outlook, use outlook Redemption for the same
0
 
LVL 25

Expert Comment

by:epasquier
ID: 33672036
Another way is to call the default email handler to create a new mail, filling some fields and allowing the user to view/edit the email before he sends it.
That can be done in one single line (ShellExecute) if you only want one destination and a subject, but this complete function will handle additional parameters and URL encoding problems (especially the body)

Note that some parameters like subject & content do not work well on all email clients (Eudora). No problem so far with Microsoft emails applications (Outlook)

CreateMail( edtSubject.Text, mmoSendTo.Lines, mmoBody.Lines);
function CreateMail( sSubject : string; rgTo:TStrings; rgContent:TStrings=nil; rgCc:TStrings=nil; rgBcc:TStrings=nil ) : Boolean;

	function Encode(s: String): String;
	var i: Integer;
	Const
	 cset :set of Char=  [' ', '#', '<', '>', '"', '%', '?', '+'];
	begin
         Result:='';
	 for i := 1 to length(s) do
	  begin
	   if s[i] in cset 
	    Then Result:=Result+'%'+IntToHex(ord(s[i]),2)
	    Else Result:=Result+s[i];
	  end;
	end;
	
	function LinesToStr( rgs : TStrings; const sDelim : string ) : string;
	var i : Integer;
	begin
	 Result := '';
	 if Assigned(rgs) Then for i := 0 to rgs.Count - 1 do
	  begin
	   Result := Result + Encode(rgs[ i]);
	   if ( i < rgs.Count - 1 ) then Result := Result + sDelim;
	  end;
	end;

var
  sTo, sCc, sBcc, sContent, sURL : string;

begin
  Result := False;
  if not Assigned( rgTo ) then Exit;
  sTo := LinesToStr( rgTo, '; ' );
  sBcc := LinesToStr( rgBcc, '; ' );
  sCc := LinesToStr( rgCc, '; ' );
  sContent := LinesToStr( rgContent, '%0D%0A' );
  sURL := 'mailto:' + sTo;
  sSubject := Encode(sSubject);
  if ( sCc <> '' ) then sURL := sURL + '?cc=' + sCc;
  if ( sBcc <> '' ) then sURL := sURL + '&bcc=' + sBcc;
  if ( sSubject <> '' ) then sURL := sURL + '&subject=' + sSubject;
  if ( sContent <> '' ) then sURL := sURL + '&body=' + sContent;
  Result := ShellExecute( 0, 'Open', PChar( sURL ), nil, nil, SW_SHOWNORMAL ) > 32;
end; 

Open in new window

0
 
LVL 32

Assisted Solution

by:ewangoya
ewangoya earned 125 total points
ID: 33679095
Here is a simple unit using indy 10 components

unit MailUnit;

interface

uses
   SysUtils, Classes, IdBaseComponent,
   IdMessage, IdComponent, IdTCPConnection, IdTCPClient, IdMessageClient,
   IdSMTP, IdExplicitTLSClientServerBase, IdSMTPBase, IdAttachmentFile,
   IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack, IdSSL, IdSSLOpenSSL;

type
  TMailSend = class(TComponent)
  private
    FAttachments: TStringList;
    FAuthType: TIdSMTPAuthenticationType;
    FMailBCC: string;
    FMailCC: string;
    FMessages: TStringList;
    FMailTo: string;
    FServerUser: string;
    FServerPassword: string;
    FServerName: string;
    FServerPort: Integer;
    FSubject: String;
    FUserEmail: string;
    FUseSSL: Boolean;
    procedure AddAttachments(AIdMessage: TIdMessage);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure SendMail(); overload;
    procedure SendMail(const AServer, AUserName, APassword, AMailTo, ASubject,
      AMessage, AAttachment: string); overload;
    property Attachments: TStringList read FAttachments;
    property AuthType: TIdSMTPAuthenticationType read FAuthType write FAuthType;
    property MailBCC: string read FMailBCC write FMailBCC;
    property MailCC: string read FMailCC write FMailCC;
    property Messages: TStringList read FMessages;
    property MailTo: string read FMailTo write FMailTo;
    property ServerUser: string read FServerUser write FServerUser;
    property ServerPassword: string read FServerPassword write FServerPassword;
    property ServerName: string read FServerName write FServerName;
    property ServerPort: Integer read FServerPort write FServerPort;
    property Subject: string read FSubject write FSubject;
    property UserEmail: string read FUserEmail write FUserEmail;
    property UseSSL: Boolean read FUseSSL write FUseSSL;
  end;

  TMailHelper = class(TComponent)
  public
    class procedure SendMail(const AServer, AUserName, APassword, AMailTo, ASubject,
      AMessage, AAttachment: string);
  end;

implementation

{ TMailSend }

constructor TMailSend.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FAttachments := TStringList.Create;
  FMessages := TStringList.Create;
  FServerPort := 25; //default
end;

destructor TMailSend.Destroy;
begin
  FreeAndNil(FAttachments);
  FreeAndNil(FMessages);
  inherited Destroy;
end;

procedure TMailSend.SendMail(const AServer, AUserName, APassword, AMailTo,
  ASubject, AMessage, AAttachment: string);
begin
  FAttachments.Add(AAttachment);
  FMessages.Add(AMessage);
  FMailTo := AMailTo;
  FServerUser := AUserName;
  FServerPassword := APassword;
  FServerName := AServer;
  FSubject := ASubject;

  SendMail();
end;

procedure TMailSend.SendMail();
var
  IdMsgSend: TIdMessage;
  SMTP: TIdSMTP;
  SSLHandler: TIdSSLIOHandlerSocketOpenSSL;
begin
  IdMsgSend := TIdMessage.Create(nil);
  SSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
  try
    with IdMsgSend do
    begin
      ContentType := 'text/plain';
      Body.Assign(FMessages);
      From.Text := FUserEmail;
      ReplyTo.EMailAddresses := FUserEmail;
      Recipients.EMailAddresses := FMailTo;
      Subject := FSubject;
      CCList.EMailAddresses := FMailCC;
      BccList.EMailAddresses := FMailBCC;
    end;

    SMTP := TIdSMTP.Create(nil);
    try
      SMTP.AuthType := FAuthType;
      SMTP.Username := FServerUser;
      SMTP.Password := FServerPassword;
      SMTP.Host := FServerName;
      SMTP.Port := FServerPort;
      AddAttachments(IdMsgSend);

      if FUseSSL then
      begin
        SMTP.IOHandler := SSLHandler;
        SSLHandler.SSLOptions.Method := sslvTLSV1;
        SMTP.AuthType := satDefault;
        SMTP.UseTLS := utUseImplicitTLS;
      end;

      SMTP.Connect;
      try
        SMTP.Send(IdMsgSend);
      finally
        SMTP.Disconnect;
      end;
    finally
      FreeAndNil(SMTP);
    end;
  finally
    FreeAndNil(IdMsgSend);
  end;
end;

procedure TMailSend.AddAttachments(AIdMessage: TIdMessage);
var
  I: Integer;
begin
  for I := 0 to FAttachments.Count - 1 do
    if FileExists(FAttachments[I]) then
      TIdAttachmentFile.Create(AIdMessage.MessageParts, FAttachments[I]);
end;

{ TMailHelper }

class procedure TMailHelper.SendMail(const AServer, AUserName, APassword,
  AMailTo, ASubject, AMessage, AAttachment: string);
var
  MailSend: TMailSend;
begin
  MailSend := TMailSend.Create(nil);
  try
    MailSend.SendMail(AServer, AUserName, APassword, AMailTo, ASubject, AMessage, AAttachment);
  finally
    FreeAndNil(MailSend);
  end;
end;

end.

You can use it as
TMailHelper.SendMail('smtp.server.com', 'user@server.com', 'pwd',
  'sendto@server.com', 'Test Hello', 'This is a test', 'c:\File1.txt')
0

Featured Post

Microsoft Certification Exam 74-409

Veeam® is happy to provide the Microsoft community with a study guide prepared by MVP and MCT, Orin Thomas. This guide will take you through each of the exam objectives, helping you to prepare for and pass the examination.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Create Database on Android via Delphi dbExpress 3 92
Downloading email attachments 2 74
When i run adoquery my application freezes 26 166
DBGrid or StringGrid ? 6 90
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…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…

810 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