Send email by calling Outlook 2013

Asked

Viewed 408 times

4

To send emails use the function Sendemail:

function SendEMail(Handle: THandle; Mail: TStrings): Cardinal;
type
  TAttachAccessArray = array [0..0] of TMapiFileDesc;
  PAttachAccessArray = ^TAttachAccessArray;
var
  MapiMessage: TMapiMessage;
  Receip, ComCopia: TMapiRecipDesc;
  Attachments: PAttachAccessArray;
  AttachCount: Integer;
  i1: integer;
  FileName: string;
  dwRet: Cardinal;
  MAPI_Session: Cardinal;
  WndList: Pointer;

  aRecep: Array of TMapiRecipDesc;
  iRecipC, iCont: Integer;
  sAuxCCo, sCCo, sTO: String;
begin
  dwRet := MapiLogon(Handle, PAnsiChar(''), PAnsiChar(''), MAPI_LOGON_UI or MAPI_NEW_SESSION, 0, @MAPI_Session);
  if (dwRet <> SUCCESS_SUCCESS) then
  begin
    MessageBox(Handle, PChar('Error while trying to send email'#10+SysErrorMessage(GetLastError)), PChar('Error'), MB_ICONERROR or MB_OK);
  end
  else
  begin
    AttachCount := 0;
    Attachments := nil;
    try
      FillChar(MapiMessage, SizeOf(MapiMessage), #0);
      FillChar(Receip, SizeOf(Receip), #0);
      FillChar(ComCopia, SizeOf(ComCopia), #0);

      iRecipC := 0;
      if Mail.Values['to'] <> '' then
      begin
        sAuxCCo := Mail.Values['to'];
        if (sAuxCCo[Length(sAuxCCo)] <> ';') then
          sAuxCCo := sAuxCCo + ';';
        while (Pos(';',sAuxCCo)) > 0 do
        begin
          sTO := sTO + Copy(sAuxCCo,1,Pos(';',sAuxCCo));
          Delete(sAuxCCo,1,Pos(';',sAuxCCo));
          Inc(iRecipC);
        end;
      end;

      if Mail.Values['CCo'] <> '' then
      begin
        sAuxCCo := Mail.Values['CCo'];
        if (sAuxCCo[Length(sAuxCCo)] <> ';') then
          sAuxCCo := sAuxCCo + ';';
        while (Pos(';',sAuxCCo)) > 0 do
        begin
          sCCo := sCCo + Copy(sAuxCCo,1,Pos(';',sAuxCCo));
          Delete(sAuxCCo,1,Pos(';',sAuxCCo));
          Inc(iRecipC);
        end;
      end;

      SetLength(aRecep, iRecipC);

      iCont := 0;
      if sTO <> '' then
      begin
        while ((sTO) <> '') do
        begin
          sAuxCCo := Copy(sTO,1,Pos(';',sTO)- 1);

          aRecep[iCont].ulReserved   := 0;
          aRecep[iCont].ulRecipClass := MAPI_TO;
          aRecep[iCont].lpszName     := StrNew(PAnsiChar(AnsiString(sAuxCCo)));
          aRecep[iCont].lpszAddress  := StrNew(PAnsiChar(AnsiString('SMTP:' + sAuxCCo)));
          aRecep[iCont].ulEIDSize    := 0;

          Delete(sTO,1,Pos(';',sTO));
          Inc(iCont);
        end;
      end;

      if sCCo <> '' then
      begin
        while ((sCCo) <> '') do
        begin
          sAuxCCo := Copy(sCCo,1,Pos(';',sCCo)- 1);

          aRecep[iCont].ulReserved   := 0;
          aRecep[iCont].ulRecipClass := MAPI_BCC;
          aRecep[iCont].lpszName     := StrNew(PAnsiChar(AnsiString(sAuxCCo)));
          aRecep[iCont].lpszAddress  := StrNew(PAnsiChar(AnsiString('SMTP:' + sAuxCCo)));
          aRecep[iCont].ulEIDSize    := 0;

          Delete(sCCo,1,Pos(';',sCCo));
          Inc(iCont);
        end;
      end;

      AttachCount := 0;

      for i1 := 0 to MaxInt do
      begin
        if Mail.Values['attachment' + IntToStr(i1)] = '' then
          break;
        Inc(AttachCount);
      end;

      if AttachCount > 0 then
      begin
        GetMem(Attachments, SizeOf(TMapiFileDesc) * AttachCount);

        for i1 := 0 to AttachCount - 1 do
        begin
          FileName := Mail.Values['attachment' + IntToStr(i1)];
          Attachments[i1].ulReserved := 0;
          Attachments[i1].flFlags := 0;
          Attachments[i1].nPosition := ULONG($FFFFFFFF);
          Attachments[i1].lpszPathName := StrNew(PAnsiChar(AnsiString(FileName)));
          Attachments[i1].lpszFileName := StrNew(PAnsiChar(AnsiString(ExtractFileName(FileName))));
          Attachments[i1].lpFileType := nil;
        end;
      end;

      with MapiMessage do
      begin
        ulReserved         := 0;
        lpszSubject        := StrNew(PAnsiChar(AnsiString(Mail.Values['subject'])));
        lpszNoteText       := StrNew(PAnsiChar(AnsiString(Mail.Values['body'])));
        lpszMessageType    := Nil;
        lpszDateReceived   := Nil;
        lpszConversationID := Nil;
        flFlags            := 0;
        lpOriginator       := Nil;
        nRecipCount        := iRecipC;
        lpRecips           := @aRecep[0];
        nFileCount         := AttachCount;
        lpFiles            := @Attachments[0];
      end;

      WndList := DisableTaskWindows(0);
      try
        Result := MapiSendMail(MAPI_Session, Handle, MapiMessage, MAPI_DIALOG, 0);
      finally
        EnableTaskWindows( WndList );
      end;
    finally
      for i1 := 0 to AttachCount - 1 do
      begin
        StrDispose(Attachments[i1].lpszPathName);
        StrDispose(Attachments[i1].lpszFileName);
      end;

      if Assigned(MapiMessage.lpszSubject) then
        StrDispose(MapiMessage.lpszSubject);
      if Assigned(MapiMessage.lpszNoteText) then
        StrDispose(MapiMessage.lpszNoteText);
      if Assigned(Receip.lpszAddress) then
        StrDispose(Receip.lpszAddress);
      if Assigned(Receip.lpszName) then
        StrDispose(Receip.lpszName);

      MapiLogOff(MAPI_Session, Handle, 0, 0);
    end;
  end;
end;

Until the Office 2010 it works perfectly, but from the Office 2013 does not work anymore. The error pops right after processing the first line, generating the message:

MessageBox(Handle, PChar('Error while trying to send email'#10+SysErrorMessage(GetLastError)), PChar('Error'), MB_ICONERROR or MB_OK);

Does anyone know how to solve?

  • open the windows run and run: mailto:endereço_e-mail_desejado what happens?

  • @Junior Opens Outlook normally on the email composition screen.

  • Ok, this proves that Outlook is the default email server of your pc, so check if there are other versions of Office installed, if possible Uninstall! And if there are Excel plugins, remove them as well!

  • @Júniormoreira An important detail, I compiled a code I found on another site, and when trying to run it, comes a message from Windows (not in the code) saying that No standard email client. But it is configured as, I have already done it within Outlook itself, through Windows settings and still this message. Taking advantage, I have only this version of Office, but I also have the LibreOffice.

  • This is something of Windows/Office, this code of yours should work perfectly, as last attempt: instead of passing PAnsiChar('')pass directly nil

  • @It didn’t work. I’ll keep testing here.. if I can get the solution put in place.

  • 1

    Probably your Delphi application is 32bit and Outlook installed is 64. https://answers.microsoft.com/en-us/msoffice/forum/msoffice_outlook-mso_win10/outlook-2016-error-either-there-is-no-default-mail/346bd0b3-7140-48db-9dfd-6001537f7067

  • Why not use Indy10 components for Email ?

  • @Victorzanella Vc may be right, really my Office is 64 and the application is 32 bits, I will install version 32 of Office to see if the routine works. And as for using Indy10, the problem is that I want to open an email manager, so the user can edit/check the data.

  • @Andrey, what types of data you the user can change ?

  • I don’t know if I correctly understood your question, but I will answer what the user can change in the email that opens in Outlook, and the answer is all. Subject, recipient, e-mail body and even the attachment(s)).

  • That, but what stops you from creating a screen, where the user does all this?

  • It worked @Andrey ?

  • So @Victortadashi , I checked and the problem is even the fact that my application is 32 bits and Office, 64. But I don’t have Office 32 here to test. As for your idea of setting up a screen to allow editing the email, although functional, it is not a path that we would not like to follow. Maybe next year we’ll look at it as a possibility.

  • and then @Andrey, something new ?

  • @Victortadashi I came back today from vacation, but your above-voted comment indicating that a 32-bit app can’t call a 64-bit app is the key to my problem. The client was nominated to work with a 32-bit version of Office. Thank you.

Show 11 more comments

1 answer

2

Based on the comments. an alternative solution to your problem would be to run a shell or . bat command with "mailto:"

Ex.: ShellExecute(0, 'open', 'mailto:', '', nil, SW_HIDE);

Browser other questions tagged

You are not signed in. Login or sign up in order to post.