如何使用 Indy 将消息发送到存储在 TListView 组件中的多个电子邮件地址?

问题描述

我正在尝试从 TListView获取电子邮件列表并将它们分配给 TIdMessage.Recipients.EMailAddresses。我正在尝试获取 ListView 标题并将它们指定为收件人电子邮件地址,但是我不知道该怎么做。

这是我目前损坏的代码

procedure TfrmEmailer.btnSendClick(Sender: TObject);
var
  smtpServer: TIdSMTP;
  msgEmail: TIdMessage;
  ssl: TIdSSLIOHandlerSocketopenSSL;
  i: integer;

begin
  smtpServer := TIdSMTP.Create(nil);
  msgEmail := TIdMessage.Create(nil);
  ssl := TIdSSLIOHandlerSocketopenSSL.Create(nil);

  ssl.SSLOptions.Method := sslvTLSv1_2;
  ssl.SSLOptions.Mode := sslmUnassigned;
  ssl.SSLOptions.VerifyMode := [];
  ssl.SSLOptions.VerifyDepth := 0;

  msgEmail.Sender.Address := edtSenderAddress.Text;
  msgEmail.Sender.Name := edtSenderName.Text;
  msgEmail.ReplyTo.EMailAddresses := edtReplyTo.Text;
  for i := 0 to length(lsvRecipients.ItemIndex) do
  begin
    msgEmail.Recipients.EMailAddresses := lsvRecipients.Items[0].Caption;
  end;

  msgEmail.Subject := edtSubject.Text;
  msgEmail.Body.Text := redBody.Text;

  smtpServer.IOHandler := ssl;
  smtpServer.Host := edtHost.Text;
  smtpServer.Port := StrToInt(edtPort.Text);
  smtpServer.Username := edtUsername.Text;
  smtpServer.Password := edtPassword.Text;
  smtpServer.UseTLS := utUseExplicitTLS;

  smtpServer.Connect;
  smtpServer.Send(msgEmail);
  smtpServer.disconnect;

  smtpServer.Free;
  msgEmail.Free;
  ssl.Free;

  // Output
  beep;
  ShowMessage('Email Sent!');
end;

procedure TfrmEmailBomber.btnAddEmailClick(Sender: TObject);
begin
  emailToAdd := lsvRecipients.Items.Add;
  emailToAdd.Caption := edtAddEmail.Text;
end;

解决方法

TIdMessage.Recipients.EMailAddresses 被设计为包含多个电子邮件地址的单个分隔字符串,但您在循环中一遍又一遍地为其分配单个电子邮件地址,因此它将仅包含您分配的最后一个电子邮件地址.

在这种情况下,请使用 TIdMessage.Recipients.Add() 而不是 TIdMessage.Recipients.EMailAddresses

此外,您没有正确枚举 TListView 项。如果引发异常,您并没有保护您的代码免于泄漏内存。

试试这个:

var
  smtpServer: TIdSMTP;
  msgEmail: TIdMessage;
  ssl: TIdSSLIOHandlerSocketOpenSSL;
  i: integer;
begin
  smtpServer := TIdSMTP.Create(nil);
  try
    msgEmail := TIdMessage.Create(smtpServer);

    msgEmail.Sender.Address := edtSenderAddress.Text;
    msgEmail.Sender.Name := edtSenderName.Text;
    msgEmail.ReplyTo.EMailAddresses := edtReplyTo.Text;

    for i := 0 to lsvRecipients.Count-1 do
    begin
      msgEmail.Recipients.Add.Address := lsvRecipients.Items[i].Caption;
      // or:
      // msgEmail.Recipients.Add.Text := lsvRecipients.Items[i].Caption;
    end;

    msgEmail.Subject := edtSubject.Text;
    msgEmail.Body.Text := redBody.Text;

    ssl := TIdSSLIOHandlerSocketOpenSSL.Create(smtpServer);
    ssl.SSLOptions.Method := sslvTLSv1_2;
    ssl.SSLOptions.Mode := sslmUnassigned;
    ssl.SSLOptions.VerifyMode := [];
    ssl.SSLOptions.VerifyDepth := 0;

    smtpServer.IOHandler := ssl;
    smtpServer.Host := edtHost.Text;
    smtpServer.Port := StrToInt(edtPort.Text);
    smtpServer.Username := edtUsername.Text;
    smtpServer.Password := edtPassword.Text;
    smtpServer.UseTLS := utUseExplicitTLS;

    smtpServer.Connect;
    try
      smtpServer.Send(msgEmail);
    finally
      smtpServer.Disconnect;
    end;
  finally
    smtpServer.Free;
  end;

  // Output
  Beep;
  ShowMessage('Email Sent!');
end;

procedure TfrmEmailBomber.btnAddEmailClick(Sender: TObject);
var
  emailToAdd: TListItem;
begin
  emailToAdd := lsvRecipients.Items.Add;
  emailToAdd.Caption := edtAddEmail.Text;
end;