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_desejadowhat happens?– Junior Moreira
@Junior Opens Outlook normally on the email composition screen.
– Andrey
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!
– Junior Moreira
@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.– Andrey
This is something of Windows/Office, this code of yours should work perfectly, as last attempt: instead of passing
PAnsiChar('')pass directlynil– Junior Moreira
@It didn’t work. I’ll keep testing here.. if I can get the solution put in place.
– Andrey
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
– Victor Tadashi
Why not use Indy10 components for Email ?
– Victor Tadashi
@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
@Andrey, what types of data you the user can change ?
– Victor Tadashi
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)).
– Andrey
That, but what stops you from creating a screen, where the user does all this?
– Victor Tadashi
It worked @Andrey ?
– Victor Tadashi
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.
– Andrey
and then @Andrey, something new ?
– Victor Tadashi
@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.
– Andrey