synapse 40, также проблема наблюдается в 203 trunk'е.
Здравствуйте, отправлять письма и пристёгивать файлы - получается, проблем нет.
Проблема с кодировкой пристёгнутых файлов- она меняется на системную, то есть на CP1251.
В заголовках письма выглядит так:
Content-Disposition: attachment;
FileName="=?ISO-8859-5?Q?=C0=FC=C0=F5=C0=A6=C1=5F=C0=F0_=C1=5F=C0=5F=C0=F4=C1=A3=C1=5F=C0=F5=C0=A6=C1=5F=C0=F0_?=
=?ISO-8859-5?Q?=C0=5F=C0=F5=C0=F4=C1=F3=C0=F8=C0=5F=C0=A5=C1=5F.txt?="
Content-Description: Attached file: Новый текстовый
документ.txt
Отображается в письме так:
РќРѕРІС_Р№ С_Р_РєСЃС_РѕРІС_Р№ Р_РѕРєСѓРјР_РЅС_.txt
Код:
- Код: Выделить всё
MsgMail := TMimeMess.Create; //создаем новое сообщение
MsgMail.Header.CharsetCode:=UTF_8;
MsgMail.MessagePart.CharsetCode:=UTF_8;
MsgMail.MessagePart.DefaultCharset:='UTF-8';
MsgMail.MessagePart.TargetCharset:=UTF_8;
MsgMail.MessagePart.ConvertCharset:=true;
MIMEPartMails := MsgMail.AddPartMultipart('mixed', nil);
MsgMail.AddPartTextEx(BodyBig, MIMEPartMails, UTF_8, true, ME_7BIT);
MsgMail.AddPartBinaryFromFile('D:\Новая папка\Новая папка\Новый текстовый документ.txt', MIMEPartMails);
MsgMail.EncodeMessage;
Насколько я понимаю происходит вот что:
- Код: Выделить всё
function TMimeMess.AddPartBinaryFromFile(const FileName: string; const PartParent: TMimePart): TMimepart;
Begin
...
Result := AddPartBinary(tmp, ExtractFileName(FileName), PartParent);
...
- Код: Выделить всё
function TMimeMess.AddPartBinary(const Stream: TStream; const FileName: string; const PartParent: TMimePart): TMimepart;
begin
...
Result := AddPart(PartParent);
...
- Код: Выделить всё
function TMimeMess.AddPart(const PartParent: TMimePart): TMimePart;
begin
...
Result := PartParent.AddSubPart;
Result.Clear;
end;
- Код: Выделить всё
function TMIMEPart.AddSubPart: TMimePart;
begin
Result := TMimePart.Create;
Result.DefaultCharset := FDefaultCharset;
FSubParts.Add(Result);
...
- Код: Выделить всё
constructor TMIMEPart.Create;
begin
...
FTargetCharset := GetCurCP;
...
end;
- Код: Выделить всё
procedure TMIMEPart.Clear;
begin
...
FTargetCharset := GetCurCP;
...
Как видно значение FTargetCharset теряется в функции TMIMEPart.AddSubPart и заменяется на кодировку системы в которой запущена программа, и мой любимый UTF-8 меняется на CP1251.
И повторно теряется в функции TMimeMess.AddPart, когда происходит Clear, который также меняется значение FTargetCharset на текущую системную.
В результате чего проблема проявляется здесь:
- Код: Выделить всё
procedure TMIMEPart.EncodePartHeader;
...
begin
...
if FDisposition <> '' then
begin
s := '';
if FFileName <> '' then
s := '; FileName=' + QuoteStr(InlineCodeEx(FileName, FTargetCharset), '"');
FHeaders.Insert(0, 'Content-Disposition: ' + LowerCase(FDisposition) + s);
end;
Всё верно в FTargetCharset будет равно CP1251, а не UTF-8.
Собственно проблема решается, например вот так:
- Код: Выделить всё
procedure TMIMEPart.Clear;
begin
...
// FTargetCharset := GetCurCP;
...
- Код: Выделить всё
...
function TMIMEPart.AddSubPart: TMimePart;
begin
Result := TMimePart.Create;
Result.DefaultCharset := FDefaultCharset;
Result.TargetCharset := FTargetCharset;
FSubParts.Add(Result);
...
Или вообще вот так:
- Код: Выделить всё
procedure TMIMEPart.EncodePartHeader;
...
begin
...
if FDisposition <> '' then
begin
s := '';
FTargetCharset := UTF_8;
if FFileName <> '' then
s := '; FileName=' + QuoteStr(InlineCodeEx(FileName, FTargetCharset), '"');
FHeaders.Insert(0, 'Content-Disposition: ' + LowerCase(FDisposition) + s);
end;
Но это какие-то нехорошие способы - скажите что я делаю не так?
