TechTricks
Technical answers from the trenches 
 
 
 
 

     
   
Sending Email (and Files)
 
   
 Posted: 31 January 2002
 
   
 
 Applies to: Delphi 4 and later
 
   
 
Audience: Intermediate
 
       
   

Question: How do I send email from a Delphi application?

Answer: There are a few different ways to do this, but one of the most widely-supported is to use Delphi's built-in support for the Windows Simple Mail API (MAPI). The following code sample shows one way you can using this in your own applications:

function sendMail( const TargetName, TargetAddr,
                         SenderName, SenderAddr,
                         MsgSubject, MsgContent,
                         Attachment : String;
                         PreviewMsg : Boolean = TRUE ) : Integer;
var
  msg       : TMapiMessage;    // Pointer to the message itself
  mrdSender,                   // Who's sending it?
  mrdTarget : TMapiRecipDesc;  // Who's going to get it?
  mfdAttach : TMapiFileDesc;   // The attached file.
  liFlags   : Longint;         // Flags for MAPI.
  strError  : String;          // Holds MAPI error results;
begin
 result := 0;
 liFlags := 0;
 fillChar( msg, sizeOf( msg ), 0 );
 with msg do
 begin

   if TargetAddr = '' then
      raise tMailFileException.createFmt( ERROR,
         [ 'Target email address not specified' ] )
   else begin
      if TargetName = '' then
         mrdTarget.lpszName := pChar( TargetAddr )
      else
         mrdTarget.lpszName := pChar( TargetName );
      mrdTarget.ulRecipClass := MAPI_TO;
      mrdTarget.lpszAddress := pChar( TargetAddr );
      mrdTarget.ulReserved := 0;
      mrdTarget.ulEIDSize := 0;
      mrdTarget.lpEntryID := NIL;
      nRecipCount := 1;
      lpRecips := @mrdTarget;

   end;

   if SenderAddr = '' then
      raise tMailFileException.createFmt( ERROR,
         [ 'Sender email address not specified' ] )
   else begin
      if SenderName = '' then
         mrdSender.lpszName := pChar( SenderAddr )
      else
         mrdSender.lpszName := pChar( SenderName );
      mrdSender.ulRecipClass := MAPI_ORIG;
      mrdSender.lpszAddress := pChar( 'SMTP:' + SenderAddr );
      mrdSender.ulReserved := 0;
      mrdSender.ulEIDSize := 0;
      mrdSender.lpEntryID := NIL;
      lpOriginator := @mrdSender;
   end;

   if MsgSubject = '' then
      lpszSubject := ''
   else
      lpszSubject := pChar( MsgSubject );

   if ( MsgContent = '' ) AND ( Attachment = '' ) then
      raise tMailFileException.createFmt( ERROR,
         [ 'Tried to send an empty message (no content or attachment)' ] )
   else begin
      if MsgContent = '' then
         lpszNoteText := 'Please see the attached file.'
      else
         lpszNoteText := pChar( MsgContent );

      if Attachment = '' then begin
         nFileCount := 0;
         lpFiles := NIL;
      end else begin
         fillChar( mfdAttach, sizeOf( mfdAttach ), 0 );
         mfdAttach.nPosition := cardinal( $FFFFFFFF );
         mfdAttach.lpszPathName := pChar( Attachment );
         nFileCount := 1;
         lpFiles := @mfdAttach;
      end;
   end; // with

   if previewMsg then liFlags := MAPI_DIALOG;

   result := mapiSendMail( 0, application.Handle, msg, liFlags, 0 );

   if result <> 0 then
      raise tMailFileException.createFmt( ERROR,
         [ 'MAPI triggered an error ('
           + getMAPIError( result ) + ')' ] );
  end;

end;

The above example provides a wrapper function that calls Delphi's MAPI unit. It's designed to be placed in a library unit and called using something like this:

uses mapimail;
// ...other stuff
procedure TForm1.btnSendMailClick(Sender: TObject);
begin

   sendMail( edtTargetName.Text, edtTargetAddr.Text,
             edtSenderName.Text, edtSenderAddr.Text,
             edtMsgSubject.Text, mmoMsgContent.Text,
             edtAttachment.Text, chkPreviewMsg.Checked );

end;

For additional information, please consult the Microsoft Win32 Messaging (MAPI) Reference Help file installed with Delphi. If you're using the Professional or Enterprise editions of Delphi, you can also review the source of Delphi's MAPI unit in source/rtl/Win/mapi.pas.

Please note the following:

  1. An example using this code is available.

  2. The above example refers to a custom function called getMAPIError(). This is implemented in the example.

  3. The code in this article is designed for Delphi 4.0 and later; it should be fairly easy to rework it for older versions.

  4. This technique only works if the the end-user has MAPI-compliant email software, such as Microsoft Outlook, or Netscape Communicator.

  5. Raize Components includes a nice component for this. (Look for the TRzSendMessage component.)

 

       

Top

Feedback About Paradox Delphi Assorted Web Stuff
 
 
Copyright © 2000-2004, techtricks.com; All Rights Reserved.
Acknowledgements, Disclaimers, Terms and Conditions.
Article last updated on 31 May 2003

 

Other Sites: Paradox, Delphi, Perl, Web Stuff, and More


 

[- End -]