Indy10でメールを送信すると長い件名(Subject)が文字化けする問題と回避方法

Indy10でメールを送信すると、長い件名(Subject)が文字化けします。

サンプルコード

procedure TForm1.Button1Click(Sender: TObject);
var
  SMTP: TIdSMTP;
  Msg: TIdMessage;
begin
  SMTP := TIdSMTP.Create(nil);
  SMTP.Host := 'localhost';
  SMTP.Port := 25;

  Msg := TIdMessage.Create(SMTP);
  Msg.ContentType := 'text/plain';
  Msg.CharSet := 'ISO-2022-JP';
  Msg.ContentTransferEncoding := 'BASE64';
  Msg.From.Name := 'from@example.com';
  Msg.From.Address := 'from@example.com';
  Msg.Recipients.EMailAddresses := 'to@example.com';
  Msg.Subject := 'あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよわをん';
  Msg.Body.Text := '本文';
  Msg.OnInitializeISO := IdMessage_InitializeISO;

  SMTP.Connect;
  SMTP.Send(Msg);
  SMTP.Disconnect;

  Msg.Free;
  SMTP.Free;

  Close;
end;

procedure TForm1.IdMessage_InitializeISO(var VHeaderEncoding: Char;
  var VCharSet: string);
begin
  VHeaderEncoding := 'B';
  VCharSet := 'ISO-2022-JP';
end;

Outlook 2013では文字化けしません。

Outlook 2013

Becky! ver2では文字化けします。

Becky! ver2

これはデコード処理の違いによるものだと考えれます。
Indy10のメール送信処理においてBase64エンコードで文字化けが発生する問題について | 山本隆の開発日誌

問題のコードはIdCoderHeader.pasにありました。

EncodeWord関数の中に改行を追加する処理があります。

procedure EncodeWord(AP: Integer);
const
  MaxEncLen = 75;
  …
begin
  …
  if (EncLen + Length(Enc1)) > MaxEncLen then begin
    T := T + EndEncode + EOL + ' ' + BeginEncode;
    EncLen := Length(BeginEncode) + 2;
  end;

エンコードした文字列がMaxEncLenを超えるときに改行を追加しています。

とりあえず、この部分をコメントアウトすることで文字化けを回避することができまし
た。

コメント

  1. On how to send an email by the application itself delphi Firemonkey android / ios. Or send a direct email and not open the gmail app.

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください