开发者

Easiest way to compose Outlook 2010 mail from Delphi?

开发者 https://www.devze.com 2023-02-07 23:00 出处:网络
Some of our applications which work fine with different ways of email integration, using mailto:, simulated \"Send To...\", and SMTP in Windows 2000 and 2003 environments, now move to a new Windows 20

Some of our applications which work fine with different ways of email integration, using mailto:, simulated "Send To...", and SMTP in Windows 2000 and 2003 environments, now move to a new Windows 2008 system with Exchange 2010 and Outlook 2010 clients.

We have one use case where the application creates a new mail, sets recipient(s) and subject, adds one or more attachments and then opens it in the default mail client so it can be edited by the user before sending.

Do you know a solution which works in the new environment? Should we use a third party library? Or is there some OLE automation code available which is known to work, using Outlook.Applicati开发者_开发技巧on?


We use JclSimpleBringUpSendMailDialog from the jclMapi unit in the Jedi JCL library.

I once had an app where we built in a user option to specify whether they wanted to use SMTP or MAPI and then all sorts of mail server settings but the Jedi library call makes life so much easier. If end users have gone to the trouble of setting up all their settings in a MAPI client then why would they want to set them all up again in my/our software.

The trouble with the mailto:// stuff is that it's often not quite configurable enough or the mail client doesn't handle the parameters in the same/standard way - then users think your software's rubbish rather than believe they have a dodgy mail client.

So we just use the MAPI interface. Easy.


I use this unit - it credits Brian Long ages ago...

unit UArtMAPI;


interface



procedure ArtMAPISendMail(
            const Subject, MessageText, MailFromName, MailFromAddress,
                  MailToName, MailToAddress: String;
            const AttachmentFileNames: array of String);


implementation



uses
  SysUtils,
  Windows,
  UArtLibrary,
  Dialogs,
  Forms,
  MAPI;

procedure ArtMAPISendMail(
            const Subject, MessageText, MailFromName, MailFromAddress,
                  MailToName, MailToAddress: String;
            const AttachmentFileNames: array of String);
//Originally by Brian Long: The Delphi Magazine issue 60 - Delphi And Email
var
  MAPIError: DWord;
  MapiMessage: TMapiMessage;
  Originator, Recipient: TMapiRecipDesc;
  Files, FilesTmp: PMapiFileDesc;
  FilesCount: Integer;
begin
   FillChar(MapiMessage, Sizeof(TMapiMessage), 0);

   MapiMessage.lpszSubject := PAnsiChar(AnsiString(Subject));
   MapiMessage.lpszNoteText := PAnsiChar(AnsiString(MessageText));

   FillChar(Originator, Sizeof(TMapiRecipDesc), 0);

   Originator.lpszName := PAnsiChar(AnsiString(MailFromName));
   Originator.lpszAddress := PAnsiChar(AnsiString(MailFromAddress));
//   MapiMessage.lpOriginator := @Originator;
   MapiMessage.lpOriginator := nil;


   MapiMessage.nRecipCount := 1;
   FillChar(Recipient, Sizeof(TMapiRecipDesc), 0);
   Recipient.ulRecipClass := MAPI_TO;
   Recipient.lpszName := PAnsiChar(AnsiString(MailToName));
   Recipient.lpszAddress := PAnsiChar(AnsiString(MailToAddress));
   MapiMessage.lpRecips := @Recipient;

   MapiMessage.nFileCount := High(AttachmentFileNames) - Low(AttachmentFileNames) + 1;
   Files := AllocMem(SizeOf(TMapiFileDesc) * MapiMessage.nFileCount);
   MapiMessage.lpFiles := Files;
   FilesTmp := Files;
   for FilesCount := Low(AttachmentFileNames) to High(AttachmentFileNames) do
   begin
     FilesTmp.nPosition := $FFFFFFFF;
     FilesTmp.lpszPathName := PAnsiChar(AnsiString(AttachmentFileNames[FilesCount]));
     Inc(FilesTmp)
   end;

   try
     MAPIError := MapiSendMail(
       0,
       Application.MainForm.Handle,
       MapiMessage,
       MAPI_LOGON_UI {or MAPI_NEW_SESSION},
       0);
   finally
     FreeMem(Files)
   end;

   case MAPIError of
     MAPI_E_AMBIGUOUS_RECIPIENT:
      Showmessage('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:
      Showmessage('The specified attachment was not found; no message was sent.');
     MAPI_E_ATTACHMENT_OPEN_FAILURE:
      Showmessage('The specified attachment could not be opened; no message was sent.');
     MAPI_E_BAD_RECIPTYPE:
      Showmessage('The type of a recipient was not MAPI_TO, MAPI_CC, or MAPI_BCC. No message was sent.');
     MAPI_E_FAILURE:
      Showmessage('One or more unspecified errors occurred; no message was sent.');
     MAPI_E_INSUFFICIENT_MEMORY:
      Showmessage('There was insufficient memory to proceed. No message was sent.');
     MAPI_E_LOGIN_FAILURE:
      Showmessage('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:
      Showmessage('The text in the message was too large to sent; the message was not sent.');
     MAPI_E_TOO_MANY_FILES:
      Showmessage('There were too many file attachments; no message was sent.');
     MAPI_E_TOO_MANY_RECIPIENTS:
      Showmessage('There were too many recipients; no message was sent.');
     MAPI_E_UNKNOWN_RECIPIENT:
       Showmessage('A recipient did not appear in the address list; no message was sent.');
     MAPI_E_USER_ABORT:
       Showmessage('The user canceled the process; no message was sent.');
     SUCCESS_SUCCESS:
       Showmessage('MAPISendMail successfully sent the message.');
   else
     Showmessage('MAPISendMail failed with an unknown error code.');
   end;
end;




end.


Maybe this can be useful for you. But I can't test it, because I'm thunderbird user.


I dug up this example. It's from 2002, so uses an older outlook version, but the idea should still be the same. It was used in an application to send newly registered users their userid and password (don't start me on that, it was just a way to restrict access to a site, nothing sensitive there). The messages are saved in the Outbox, not opened, but if you dig through the OleServer and Outlook8 (number will be higher by now), you should find ways to open the mail for user attention instead of saving it straight to the outbox.

The entire Outlook object model can be found on msdn: http://msdn.microsoft.com/en-us/library/aa221870%28v=office.11%29.aspx

Another good source for information about Office Automation are Deborah Pate's pages: http://www.djpate.freeserve.co.uk/Automation.htm

function TStapWerkt_data.GenerateMailsOutlook(SendDBF: boolean): boolean;
var
  Outlook: TOutlookApplication;
  olNameSpace: NameSpace;
  MailIt: TMailItem;
  AttachedFile: OleVariant;
  i: integer;
  emailaddress: string;
begin
  Result := true;
  Outlook := TOutlookApplication.Create( nil );
  try
    Outlook.ConnectKind := ckNewInstance;
    try
      Outlook.Connect;
      try
        olNameSpace := Outlook.GetNamespace('MAPI');
        olNameSpace.Logon('', '', False, False);
        try

          if SendDBF then begin
            MailIt := TMailItem.Create( nil );
            MailIt.ConnectTo( Outlook.CreateItem( olMailItem ) as MailItem );
            try
              MailIt.Recipients.Add( 'info@bjmsoftware.com' );
              MailIt.Subject := 'StapWerk.dbf';
              MailIt.Body := 'Stap'#13#10;
              AttachedFile := IncludeTrailingBackslash( ExtractFilePath(
                  Stap_db.Stap_Database.DatabaseName ) ) + 'stapwerk.dbf';
              MailIt.Attachments.Add( AttachedFile, EmptyParam, EmptyParam, EmptyParam );
              MailIt.Save;
            finally
              MailIt.Free;
            end;
          end;

          for i := 0 to FNewUsers.Count - 1 do begin
            MailIt := TMailItem.Create( nil );
            MailIt.ConnectTo( Outlook.CreateItem( olMailItem ) as MailItem );
            try
              emailaddress := TStapper( FNewUsers.Items[i] ).Email;
              if emailaddress = '' then begin
                emailaddress := C_MailUnknownAddress;
              end;
              MailIt.Recipients.Add( emailaddress );
              MailIt.Subject := C_MailSubject;
              MailIt.Body := Format( C_MailBody,
                  [TStapper( FNewUsers.Items[i] ).UserId,
                  TStapper( FNewUsers.Items[i] ).Password] );
              MailIt.Save;
            finally
              MailIt.Free;
            end;
          end;

        finally
          olNameSpace.Logoff;
        end;
      finally
        Outlook.Disconnect;
        // We kunnen ondanks ckNewInstance quit niet gebruiken
        // Outlook lijkt de connectkind te negeren en hoe dan ook te koppelen
        // naar een bestaande instantie. En die gooi je dan dus ook dicht met quit.
//        Outlook.quit;
      end;
    finally
      Outlook.free;
    end;
  except
    on E: Exception do begin
      Result := false;
    end;
  end;
end;


Maybe this is the easiest way to open an email window

System("mailto:someone@example.com?Subject=Hello%20again&body=your%20textBody%20here")
0

精彩评论

暂无评论...
验证码 换一张
取 消