•  

ГлавнаяIndyЧастые вопросы по Indy → Проблема с кодировкой при работе почтового POP-клиента

Создано: 26.01.2012 21:48:54 · Исправлено: 26.01.2012 21:48:54 · Прочтений: 2498

Вот столкнулся с одной проблемой кодировки при работе почтового POP-клиента. Наша задача - сделать клиент, который бы почту проверил на сервере, и если встретилось там такое письмо, то обработать его.
POP-клиент (Delphi 6. компоненты на вкладке Indy - компоненты TPOP3, TIdMessage) отлично работает. Но как только встречаются письма, то результат ужасный получается, страшные типа
=?koi8-r?B?88XSx8XKIPfJy9TP0s/Xyd4g5M/C0tnOyc4?=
=?win-1251?q?88XSx8XKIPfJy9TP0s/Xyd4g5M/C0tnOyc4?=
Что это такое-мне не нужно объяснять, я сам и так понимаю
=?koi8-r?B?88XSx8XKIPfJy9TP0s/Xyd4g5M/C0tnOyc4
Здесь
Кодировка (charset) KOI8-R
Тип (способ) кодировки (encoding) B - BASE64 и т.д.
Но мне надо, чтобы всё читалось по-русски и никаких
=?charset?encoding?закодированный текст?=
Пытался устанавливать свойство TIdMessage.Charset так
MailMessage.Charset:=KOI8-R (В HELPе почему то два вида кодировки US_ACSII, ..)
MailMessage.ContentTransferEncoding:=B; (В HELPе ноль сведений о видах encoding)
MailMessage.ContentType:=???

MailMessage.Charset:=???
MailMessage.ContentTransferEncoding:=???
MailMessage.ContentType:=???

//Вот кусок программы битый, битый-=============================

    Application.ProcessMessages;

    // Очищаем письмо
    MailMessage.Clear;

    //Читаем заголовок письма - помещаем всё это в список Msg
//  POP.RetrieveHeader(intIndex, MailMessage);
    POP.Retrieve(intIndex, MailMessage);

    //Добавляем информацию в список ListView
    item := MailList.Items.Add;
    item.Caption:=IntToStr(intIndex);
//    item.SubItems.Add(MailMessage.MsgId);
    item.SubItems.Add(Base64Encode(MailMessage.From.Name));//Даже это не
помогает, если включить файл IdCoder3To4.pas в Uses
    item.SubItems.Add(MailMessage.From.Address);
//    item.SubItems.Add(MailMessage.Sender.Text);
    item.SubItems.Add(MailMessage.Subject);
    item.SubItems.Add(DateToStr(MailMessage.Date));
    item.SubItems.Add(IntToStr(POP.RetrieveMsgSize(intIndex)));
    item.SubItems.Add(IntToStr(Pred(MailMessage.MessageParts.Count)));

    //  itm.SubItems.Add(POP.RetrieveUIDL(intIndex));

//======================================================
Прошу помочь, 2 дня искал в Интернете и пытался решить проблему. Стыдно просто перед начальником же. Помогите, плиз. Это же непосильная работа, литературы нету и в хелпе не пишут про русские кодировки
Надеюсь на Ваше понимание. Заранее благодарю за ответ
Да, чтобы ты не мучался, для полноценной отсылки нужно дополнительно указать в IdMessage1.Recipients.EMailAddresses:= [email protected];
Я решил просто: Есть на компоненте idMessage NoEncode, ставишь true, правда предётся поля заголовка idMessage корректировать самостоятельно.. В полях From:/To:/... - подключаешь любые IdEncoder-ы.... типа From:==?windows-1251?B?+IdEncoderMIME1.Encode(Вова)+?= <[email protected]> Если нужно перекодировать в Koi8-r - поищи в инете любые конверторы из windows-1251 в koi8-r... тогды у тебя должно быть типа: From:==?koi8-r?B?+IdEncoderMIME1.Encode(Win1251toKoi8r(Вова))+?= <[email protected]>
ну а заправить так:
IdMessage1.Headers.Values[From:]:=From;
а если письмо в koi8-r
Самое простое решение, которое я смог успешно применить - подправить исходник Indy IdCoderHeader.pas
У меня на харде он лежит вот тут D:\Program Files\Borland\Delphi7\Source\Indy\IdCoderHeader.pas
Находим процедуру InitializeISO.
procedure InitializeISO(var TransferHeader: TTransfer; var HeaderEncoding: char;
  var CharSet: string);

begin
  TransferHeader := bit8;    { header part conversion type }
  HeaderEncoding := B;    { base64 / quoted-printable }    {Do not Localize}

  case GetSystemLocale of
    csGB2312: CharSet := GB2312; {Do not Localize}
    csBig5: CharSet := Big5;    {Do not Localize}
    csIso2022jp:
      begin
        CharSet := ISO-2022-JP;  {Do not Localize}
        TransferHeader := iso2022jp { header needs conversion }
      end;
    csEUCKR: CharSet := EUC-KR;  {Do not Localize}
    else
      CharSet := ISO-8859-1;  {Do not Localize} //Это получается кодировка по умолчанию!!!    HeaderEncoding := Q;    {Do not Localize}
  end;
end;
Меняем ее на необходимую кодировку(WINDOWS-1251).
procedure InitializeISO(var TransferHeader: TTransfer; var HeaderEncoding: char;
  var CharSet: string);

begin
  TransferHeader := bit8;    { header part conversion type }
  HeaderEncoding := B;    { base64 / quoted-printable }    {Do not Localize}

  case GetSystemLocale of
    csGB2312: CharSet := GB2312; {Do not Localize}
    csBig5: CharSet := Big5;    {Do not Localize}
    csIso2022jp:
      begin
        CharSet := ISO-2022-JP;  {Do not Localize}
        TransferHeader := iso2022jp { header needs conversion }
      end;
    csEUCKR: CharSet := EUC-KR;  {Do not Localize}
    else
      CharSet := WINDOWS-1251;  {Do not Localize} //Поменяли кодировку на WINDOWS-1251!!!
    HeaderEncoding := Q;    {Do not Localize}
  end;
end;
Открываем файл dclusr.dpk (у меня D:\Program Files\Borland\Delphi7\Lib\dclusr.dpk). Компилируем (Compile) и инсталлируем (Install). Все теперь компонент IdMessage по умолчанию использует кодировку WINDOWS-1251.
Всё то хорошо, только на строку
...
var M: TIdMessage;
...
у меня выдаётся
[Error] MailFrm.pas(89): Undeclared identifier: TIdMessage
[Fatal Error] VXDMail.dpr(5): Could not compile used unit MailFrm.pas
Кстати в indy 9.011 эту багу не пофиксили. Выражается она в том, что заголовок (subject) сообщения всегда кодируется в ISO-8859 и соответственно некоторые русские буквы сьедает. Решение так и не найдено, мб есть у кого ответ? Ошибки в файлах IDMessage.pas, IDCoderHeader.pas.