最初に解決方法を書いておきます。
下記のコードを追加して、プロジェクトオプションの「実行時パッケージを使って構築」をチェックを外すと、問題が発生しなくなります。
#include <IdHeaderCoder2022JP.hpp>
#pragma link "IdHeaderCoder2022JP"
以下、本文です。
Dekoさんのところの記事「Indy 10 を使ってメール(ISO-2022-JP)を送受信するには? (Delphi 2009 以降)」を参考にしたメールを送信する次のコード。
(C++Builder XEでは、Delphi XEで作成したフォームをプロジェクトに追加して使用した。)
Delphi XEでは正しく動作したが、C++Builder XEではヘッダーの日本語が消えた。
procedure TForm1.IdMessage_InitializeISO(var VHeaderEncoding: Char; var VCharSet: string);
begin
VHeaderEncoding := 'B';
VCharSet := 'ISO-2022-JP';
end;
procedure TForm1.Button1Click(Sender: TObject);
var
SMTP: TIdSMTP;
Msg : TIdMessage;
begin
SMTP := TIdSMTP.Create(nil);
try
SMTP.Host := 'localhost';
SMTP.Port := 25;
SMTP.Connect;
Msg := TIdMessage.Create(SMTP);
try
Msg.OnInitializeISO := IdMessage_InitializeISO;
Msg.ContentType := 'text/plain';
Msg.CharSet := 'ISO-2022-JP';
Msg.ContentTransferEncoding := 'BASE64';
Msg.From.Name := '送信者123';
Msg.From.Address := 'from@localhost';
Msg.Recipients.EMailAddresses := 'to@localhost';
Msg.Subject := '件名123です';
Msg.Body.Text := '本文123です';
SMTP.Send(Msg);
finally
Msg.Free;
end;
SMTP.Disconnect;
finally
SMTP.Free;
end;
end;
Delphi XEの送信結果は次のようなっている。これは正しい。
From: =?ISO-2022-JP?B?GyRCQXc/LjxUGyhCMTIz?= <from@localhost>
Subject: =?ISO-2022-JP?B?GyRCN29MPhsoQjEyMxskQiRHJDk=?=
To: to@localhost
Content-Type: text/plain; charset=ISO-2022-JP
Content-Transfer-Encoding: BASE64
Date: Sun, 16 Jan 2011 16:34:54 +0900
GyRCS1xKOBsoQjEyMxskQiRHJDkbKEINCg==
C++Builder XEの送信結果。差出人や件名の日本語の部分が消えている。
From: 23 <from@localhost>
Subject: 123
To: to@localhost
Content-Type: text/plain; charset=ISO-2022-JP
Content-Transfer-Encoding: BASE64
Date: Sun, 16 Jan 2011 16:35:19 +0900
GyRCS1xKOBsoQjEyMxskQiRHJDkbKEINCg==
C++で同じコードを書いてみる。
void __fastcall TForm2::IdMessage_InitializeISO(wchar_t &VHeaderEncoding, UnicodeString &VCharSet)
{
VHeaderEncoding = L'B';
VCharSet = "ISO-2022-JP";
}
void __fastcall TForm2::Button1Click(TObject *Sender)
{
TIdSMTP* smtp = new TIdSMTP(NULL);
smtp->Host = "localhost";
smtp->Port = 25;
smtp->Connect();
TIdMessage* msg = new TIdMessage(NULL);
msg->OnInitializeISO = IdMessage_InitializeISO;
msg->ContentType = "text/plain";
msg->CharSet = "ISO-2022-JP";
msg->ContentTransferEncoding = "BASE64";
msg->From->Name = "送信者123";
msg->From->Address = "from@localhost";
msg->Recipients->EMailAddresses = "to@localhost";
msg->Subject = "件名123です";
msg->Body->Text = "本文123です";
smtp->Send(msg);
smtp->Disconnect();
delete msg;
delete smtp;
}
実行結果は次の通り。変化なし。
From: 23 <from@localhost>
Subject: 123
To: to@localhost
Content-Type: text/plain; charset=ISO-2022-JP
Content-Transfer-Encoding: BASE64
Date: Sun, 16 Jan 2011 17:03:02 +0900
GyRCS1xKOBsoQjEyMxskQiRHJDkbKEINCg==
ということで、C++Builder XEのときだけ、動作がおかしいようだ。
追記
よくわからないまま、回避策が見つかった。
原因を調査していて、TIdHeaderCoder2022JP.Encodeの動作に疑問を持った。
IdHeaderCoder2022JP.pasを修正しようと思い、ファイルをコピーしてプロジェクトに追加した。
それから、メインフォームの先頭で”IdHeaderCoder2022JP.hpp”をincludeすると、問題が起こらなくなった。
なお、プロジェクトオプションの「実行時パッケージを使って構築」をチェックすると、問題は発生するようだ。
2011年3月10日 追記
IdHeaderCoder2022JP.pasのソースコードを読むと、次のコメントを見つけた。
// RLebeau 4/17/10: this forces C++Builder to link to this unit so
// RegisterHeaderCoder can be called correctly at program startup...
(*$HPPEMIT '#pragma link "IdHeaderCoder2022JP"'*)
そこで試しに次のコードを追加してみた。
#pragma link "IdHeaderCoder2022JP"
プロジェクトオプションの「実行時パッケージを使って構築」をチェックを外すと、問題が発生しなくなった。
私も最新のIndyのDevSnapshotとC++BuilderXEで試してみようと思います。
高橋智宏さま
> 私も最新のIndyのDevSnapshotとC++BuilderXEで試してみようと思います。
ありがとうございます。
使用しているIndyはRadStudio XEに付属のものです。
また回避策から考えると、私の環境だけの問題かもしれません。