Jaskinie Podróże Nurki Grafika Mizar Teksty Kulinaria Lemkov Namiary Mapa RSS English
Spelunka Trybików Teksty Charsets TIdMessage a CharSet YAC Software
  Wróć

Spis

Charsets

Wykresy

DBExpress

Delphi

HTML

Intraweb

MSTest

PHP

Programowanie

R

Rhino Mocks

Software

Testowanie

Testowanie UI

VB.NET

VCL

WPF

TIdMessage a CharSet
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

Komentarze
#1
Dalis napisał(a) dnia 2009-12-16 09:41:45
Thank you very much. This code help me with my problem.
#2
1 napisał(a) dnia 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 napisał(a) dnia 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;


Góra

Dodaj komentarz (pola z gwiazdką są obowiązkowe)
Imię / ksywa *
Mail (pozostanie ukryty) *
Twoja strona
Komentarz (bez tagów) *
Wpisz tekst wyświetlony poniżej *
 

Góra

Tagi

Charsets

Delphi


Podobne strony

Interfejsy w Delphi... znowu

Weryfikacja "wiszących" procedur obsługi zdarzeń w formach Delphi

Przeciąganie plików na okno aplikacji

Intraweb a MaxConnections

Argumenty za używaniem FreeAndNIL

Intraweb jako moduł DSO Apache'a

Intraweb a "Device not supported"

Zautomatyzowane testowanie GUI

Zaokrąglanie i dokładność na FPU 8087

mail() w PHP

Intraweb a SessionTimeout

Używanie TChart w programach Intraweb

Unknown driver: MySQL

Gwarancje oprogramowania

Automatyczne testowanie formularzy okien

TChart - brakujące etykiety w osiach

Tracona pamięć i eksplozje połączeń w DBExpress

Kontrola dyrektyw kompilacji warunkowej oraz ustawień przełączników kompilacji

Wykrywanie traconej pamięci a DUnit

last_insert_id() a DBExpress

Rejestracja rozszerzeń

DBExpress a dostęp wielowątkowy

Formy jak ramki

Sprawdzanie błędnych odwołań a nowy menedżer pamięci

Dostęp do składowych chronionych

Obiekty, interfejsy i obsługa pamięci w Delphi - ki czort?