Recently I had to send some e-mails automatically using Delphi (no SPAM, mind you).
Obviously, I turned to the Indy components distributed by default with RAD Studio.
The problem was that I needed to encode those e-mails using ISO-8859-2.
I thought that setting the CharSet property would be enough,
just run the application and everything should work nicely...
Well, no, not entirely... Actually, not at all.
This is how the message source looks like - in this message the subject and body include all Polish diacritic characters
(the question marks at the bottom constitute the e-mail's body):
From: ...
Subject:
=?ISO-8859-1?Q?=B1=E6=EA=B3=F1=F3=B6=BC=BF=A1=C6=CA=A3=D1=D3=A6=AC=AF?=
To: ...
Date: ...
Message-Id: ...
????????????
So, here's one solution: forget about the CharSet property, just set ContentType appropriately, for instance:
LMessage := TIdMessage.Create(NIL);
LMessage.ContentType := 'text/plain; charset=ISO-8859-2';
If you don't set ContentType, the message body may appear fine in Outlook,
but will still be garbled when viewing it under Thunderbird.
Another approach is to set two properties: Encoding and CharSet.
LMessage := TIdMessage.Create(NIL);
LMessage.CharSet := 'ISO-8859-2';
LMessage.Encoding := meMIME;
When the encoding is set to MIME, then the character set set in CharSet is added to the header
(but only with that encoding; doesn't work with mePlainText, for instance).
Both approaches above work, except that...
the subject line is not encoded using the specified character set:
From: ...
Subject:
=?ISO-8859-1?Q?=B1=E6=EA=B3=F1=F3=B6=BC=BF=A1=C6=CA=A3=D1=D3=A6=AC=AF?=
To: ...
Content-Type: text/plain; charset=ISO-8859-2
Date: ...
Message-Id: ...
acelnoszzACELNOSZZ
This is, unfortunately, a bit more complicated.
TIdMessage has an additional procedural property: OnInitializeISO.
You need to set this property to something like the code below.
This procedure must be an "of object" kind - that is, it must be defined inside a class.
One way is to subclass TIdMessage and define the procedure there.
Another way is to assign a procedure defined in another class
(such as defining the handler as a method of a form when the TIdMessage component is placed on that form - see the comment below).
The way you assign this handler is not that relevant here - the code inside the handler is:
TMyMessage = class(TIdMessage)
private
procedure InitializeISO88592(
var VTransferHeader: TTransfer; var VHeaderEncoding: char; var VCharSet: string);
end;
procedure TMyMessage.InitializeISO88592(
var VTransferHeader: TTransfer; var VHeaderEncoding: char; var VCharSet: string);
begin
VCharSet := 'ISO-8859-2';
end;
And then:
LMessage := TMyMessage.Create(NIL);
LMessage.ContentType := 'text/plain; charset=ISO-8859-2';
LMessage.OnInitializeISO := LMessage.InitializeISO88592;
Wow, finally the message's subject and body are both encoded using the correct character set:
From: ...
Subject:
=?ISO-8859-2?Q?=B1=E6=EA=B3=F1=F3=B6=BC=BF=A1=C6=CA=A3=D1=D3=A6=AC=AF?=
To: ...
Content-Type: text/plain; charset=ISO-8859-2
Date: ...
Message-Id: ...
acelnoszzACELNOSZZ
HTH
Top
|