Ostatnio musiałem automatycznie wysłać e-maile za pomocą Delphi (żaden SPAM).
Wybrałem komponenty Indy standardowo dystrybuowane wraz z RAD Studio.
Problem w tym, że wiadomości powinny były być zakodowane wg ISO-8859-2.
Myślałem, że proste ustawienie właściwości CharSet wystarczy -
uruchom aplikację, a wszystko zadziała jak należy...
No, zadziałało tak nie do końca... A w zasadzie, w ogóle.
Oto jak wygląda źródło wiadomości, w której w temacie i w treści wypisane są wszystkie polskie znaki diakrytyczne
(znaki zapytania na dole to treść wiadomości):
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: ...
????????????
Oto jedno z rozwiązań: zapomnij o właściwości CharSet, natomiast ustaw ContentType odpowiednio, np.:
LMessage := TIdMessage.Create(NIL);
LMessage.ContentType := 'text/plain; charset=ISO-8859-2';
Jeżeli nie ustawisz ContentType, treść wiadomości może zostać dobrze wyświetlona np. w Outlooku,
ale już w Thunderbirdzie zobaczysz krzaczki.
Inne podejście to ustawienie obu właściwości Encoding i CharSet:
LMessage := TIdMessage.Create(NIL);
LMessage.CharSet := 'ISO-8859-2';
LMessage.Encoding := meMIME;
Gdy kodowanie jest ustawione na MIME,
wtedy tablica kodowa znaków ustawiona w CharSet dodawana jest do nagłówka wiadomości;
nie działa to jednak z kodowaniem mePlainText...
Oba podejścia wyżej działają, tyle, że...
temat nadal nie używa odpowiedniej tablicy znaków:
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: ...
ąćęłńóśźżĄĆĘŁŃÓŚŹŻ
A to już jest nieco bardzie skomplikowane (niestety).
TIdMessage ma jeszcze jedną właściwość proceduralną: OnInitializeISO.
Należy ją ustawić na kod mniej więcej taki jak przedstawiony poniżej.
Metody musi być typu "of object" - tzn. musi być zdefiniowana wewnątrz jakiejś klasy.
Jedną z możliwości jest zdefiniowanie potomka TIdMessage i tam zdefiniowanie procedury.
Inną jest przypisanie metody zdefiniowanej w innej klasie
(jak definiowanie obsługi w procedurze formularza, na którym umieszczony jest komponent TIdMessage - patrz komentarze poniżej).
Sposób przypisania procedury nie jest tutaj tak bardzo istotny - kod procedury jest:
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;
I wtedy:
LMessage := TMyMessage.Create(NIL);
LMessage.ContentType := 'text/plain; charset=ISO-8859-2';
LMessage.OnInitializeISO := LMessage.InitializeISO88592;
O kurczę! Nareszcie i treść wiadomości i temat wykorzystują prawidłową tablicę znaków:
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: ...
ąćęłńóśźżĄĆĘŁŃÓŚŹŻ
HTH
Góra
|