delphiindy

Delphi 2007/Indy10 SMTP client : sends ??????? not Greek characters


I use TidSMTP component with Delphi 2007 to send eMails in Greek language with the following code

with IdMsg do begin
    clear;
    contentType := 'multipart/mixed';
    Charset := 'GREEK_CHARSET';
    with TidText.Create(MessageParts) do begin
        ContentType := 'text/plain';
        Charset := 'GREEK_CHARSET';
        Body.Text := Memo1.Text; // memo1 has text in Greek language
    end;
    if Edit1.Text = '' then From.name := some text in Greek language
    else From.name := Edit1.Text;
    if Edit2.Text = '' then From.Address := 'myEmail@asdf.gr'
    else From.Address := Edit2.Text; // has text in Greek language
    Recipients.EMailAddresses := an eMail address;
    
    if edit10.Text = '' then subject := some text in Greek language
                        else Subject := edit10.Text;// has text in Greek language
    .....
    IdSMTP1.Connect;
    IdSMTP1.Send(IdMsg);
    .....

On the recipient side the name and subject text looks like "???????" but the body text is in Greek as expected. Why is this difference and how can I fix it?


Solution

  • GREEK_CHARSET is not a valid charset name. The standard charset for Greek is ISO-8859-7, and there is also the Windows-1253 codepage on Windows.

    The reason why Greek is not working in the email headers, but is working in the email body, is because you are specifying a Greek charset for the body but not for the headers. You are using a pre-Unicode 1 version of Delphi where string is AnsiString, and you have Greek-encoded AnsiStrings in the body which are being sent with a Greek charset specified in the TIdText.Charset property (the TIdMessage.Charset property doesn't apply for multipart emails). So everything matches up. That is not the case with the email headers.

    To send non-ASCII characters in email headers, they must be encoded using the rules of RFC 2047. You can use the TIdMessage.OnInitializeISO event to specify a HeaderEncoding ('Q' for quoted-printable, 'B' for base64, or '8' for raw) and CharSet for Indy's RFC 2047 encoder to use. On a Greek machine using a pre-Unicode Delphi, TIdMessage will default to using 'Q' and 'ISO-8859-1', respectively 2. But, ISO-8859-1 can't handle Greek characters, hence the ? characters.

    Try this:

    // TIdMessage.OnInitializeISO event handler
    procedure TMyForm.IdMsgInitializeISO(
      var VHeaderEncoding: Char; var VCharSet: string);
    begin
      VHeaderEncoding := 'Q';
      VCharSet := 'ISO-8859-7'; // or 'Windows-1253'
    end;
    
    ...
    
    with IdMsg do begin
      Clear;
      ContentType := 'multipart/mixed';
      with TIdText.Create(MessageParts) do begin
        ContentType := 'text/plain';
        Charset := 'ISO-8859-7'; // or 'Windows-1253'
        Body.Text := Memo1.Text;
      end;
      ...
    end;
    

    That begin said, I really suggest that you use UTF-8 instead of Greek, eg:

    procedure TMyForm.IdMsgInitializeISO(
      var VHeaderEncoding: Char; var VCharSet: string);
    begin
      VHeaderEncoding := 'B';
      VCharSet := 'UTF-8';
    end;
    
    ...
    
    with IdMsg do begin
      Clear;
      ContentType := 'multipart/mixed';
      with TIdText.Create(MessageParts) do begin
        ContentType := 'text/plain';
        Charset := 'UTF-8';
        Body.Text := UTF8Encode(Memo1.Text); // UTF8Encode() not needed in D2009+
      end;
      ...
    end;