Caves Travel Diving Graphics Mizar Texts Cuisine Lemkov Contact Map RSS Polski
Trybiks' Dive Texts Charsets TIdMessage's CharSet YAC Software
  Back

List

Charsets

Charts

DBExpress

Delphi

HTML

Intraweb

MSTest

PHP

Programming

R

Rhino Mocks

Software

Testing

UI Testing

VB.NET

VCL

WPF

TIdMessage's CharSet
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

Comments
#1
Dalis wrote on 2009-12-16 09:41:45
Thank you very much. This code help me with my problem.
#2
1 wrote on 2010-03-15 08:47:57
Component IdMessage -> Events -> OnInitializeISO

procedure TMainFrm.IdMessageInitializeISO(var VHeaderEncoding: Char;
var VCharSet: String);
begin
VCharSet := \'ISO-8859-2\';
end;
#3
davk wrote on 2011-12-18 22:15:18
On my ver. worked just with full 3 variables, in event "OnInitializeISO"

procedure Tform1.IdMessage1InitializeISO(var VTransferHeader: TTransfer;
var VHeaderEncoding: Char; var VCharSet: String);
begin
VTransferHeader:=bit8;
VHeaderEncoding:='Q';
VCharSet:='ISO-8859-2';
end;


Top

Add a comment (fields with an asterisk are required)
Name / nick *
Mail (will remain hidden) *
Your website
Comment (no tags) *
Enter the text displayed below *
 

Top

Tags

Charsets

Delphi


Related pages

Delphi interfaces... again

Checking "Dangling" Event Handlers in Delphi Forms

Drag-n-drop files onto the application window

Intraweb and MaxConnections

A Case for FreeAndNIL

Intraweb as an Apache DSO module

"Device not supported" in Intraweb

Automated GUI Testing

Rounding and precision on the 8087 FPU

PHP's mail()

SessionTimeout in Intraweb

Using TChart with Intraweb

Unknown driver: MySQL

Software Guarantees

Automated Testing of Window Forms

TChart - Missing Labels in Axes

Memory Leaks and Connection Explosions in DBExpress

Controlling Conditional Defines and Compilation Switches

Detecting Memory Leaks with DUnit

last_insert_id() and DBExpress

Registering Extensions

DBExpress and Thread Safety

Forms as Frames

Checking Dangling Pointers vs. the New Memory Manager

Accessing Protected Members

Objects, interfaces, and memory management in Delphi