修改IdMessageClient.pas
//在ProcessTextPart方法中修改
AMsg.Body.Text := LStringStream.DataString;
//为
if IndyUpperCase(AMsg.CharSet) ='UTF-8' then
AMsg.Body.Text:=UTF8Decode(LStringStream.DataString)
else
AMsg.Body.Text :=LStringStream.DataString;
//修改
LTxt.Body.Text:=LStringStream.DataString ;
//为
LTxt.Body.Text:=UTF8Decode(LStringStream.DataString) ;
if LTxt.Body.Text='' then
LTxt.Body.Text:=LStringStream.DataString ;
<pre name="code" class="delphi">//修改IdCoderHeader.pas
//修改DecodeHeader方法如下
function DecodeHeader(Header: string):string;
const
WhiteSpace = LF+CR+CHAR32+TAB;
var
i, l: Integer;
HeaderEncoding,
HeaderCharSet,
s: string;
aDecoder:TIdDecoderMIMELineByLine;
LEncodingStartPos,encodingendpos:Integer;
LPreviousEncodingStartPos: integer;
substring: string;
EncodingFound: Boolean;
OnlyWhitespace: boolean;
EncodingBeforeEnd: integer;
TCharSet:string;
begin
// Get the Charset part.
EncodingBeforeEnd := -1;
TCharSet:='';
LEncodingStartPos := PosIdx('=?ISO', Sys.UpperCase(Header), 1); {do not localize}
if LEncodingStartPos = 0 then begin
LEncodingStartPos := PosIdx('=?WINDOWS', Sys.UpperCase(Header), 1); {do not localize}
end;
if LEncodingStartPos = 0 then begin
LEncodingStartPos := PosIdx('=?KOI8', Sys.UpperCase(Header), 1); {do not localize}
end;
if LEncodingStartPos = 0 then begin
LEncodingStartPos := PosIdx('=?UTF-8', Sys.UpperCase(Header), 1); {do not localize}
TCharSet:='utf';
end;
if LEncodingStartPos = 0 then begin
LEncodingStartPos := PosIdx('=?GBK', Sys.UpperCase(Header), 1); {do not localize}
TCharSet:='';
end;
if LEncodingStartPos = 0 then begin
LEncodingStartPos := PosIdx('=?GB2312', Sys.UpperCase(Header), 1); {do not localize}
TCharSet:='';
end;
if LEncodingStartPos = 0 then begin
LEncodingStartPos := PosIdx('=?GB18030', Sys.UpperCase(Header), 1); {do not localize}
TCharSet:='';
end;
while LEncodingStartPos > 0 do begin
// Assume we will find the encoding
EncodingFound := True;
//we need 3 more question marks first and after that a '?=' {Do not Localize}
//to find the end of the substring, we can't just search for '?=', {Do not Localize}
//example: '=?ISO-8859-1?Q?=E4?=' {Do not Localize}
encodingendpos := PosIdx('?', Sys.UpperCase(Header),LEncodingStartPos+5); {Do not Localize}
if encodingendpos = 0 then begin
EncodingFound := False;
end else begin
// valid encoded words can not contain spaces
// if the user types something *almost* like an encoded word,
// and its sent as-is, we need to find this!!
for i := LEncodingStartPos to encodingendpos-1 do begin
if CharIsInSet(Header, i, Whitespace) then begin
EncodingFound := false;
break;
end;
end;
end;
if EncodingFound then
begin
encodingendpos:=PosIdx('?', Sys.UpperCase(Header),encodingendpos+1); {Do not Localize}
if encodingendpos=0 then
begin
EncodingFound := false;
end else begin
for i := LEncodingStartPos to encodingendpos-1 do begin
if CharIsInSet(Header, i, Whitespace) then begin
EncodingFound := false;
break;
end;
end;
end;
end;
if EncodingFound then
begin
encodingendpos:=PosIdx('?=', Sys.UpperCase(Header),encodingendpos+1); {Do not Localize}
if encodingendpos > 0 then
begin
for i := LEncodingStartPos to encodingendpos-1 do begin
if CharIsInSet(Header, i, Whitespace) then begin
EncodingFound := false;
break;
end;
end;
if EncodingFound then begin
substring:=Copy(Header,LEncodingStartPos,encodingendpos-LEncodingStartPos+2);
//now decode the substring
for i := 1 to 3 do
begin
l := Pos('?', substring); {Do not Localize}
substring := Copy(substring, l+1, Length(substring) - l + 1 );
if i = 1 then
begin
HeaderCharSet := Copy(substring, 1, Pos('?', substring)-1) {Do not Localize}
end else if i = 2 then
begin
HeaderEncoding := copy(substring,1,1);
end;
end;
//now Substring needs to end with '?=' otherwise give up! {Do not Localize}
if Copy(substring,Length(substring)-1,2)<>'?=' then {Do not Localize}
begin
EncodingFound := false;
end;
end;
if (EncodingBeforeEnd>=0) and EncodingFound and (LEncodingStartPos > 0) then begin
OnlyWhitespace := true;
for i:=EncodingBeforeEnd to LEncodingStartPos-1 do begin
if not (CharIsInSet(Header, i, WhiteSpace)) then begin
OnlyWhitespace := false;
break;
end;
end;
if OnlyWhitespace then begin
Delete(Header, EncodingBeforeEnd, LEncodingStartPos-EncodingBeforeEnd);
encodingendpos := encodingendpos - (LEncodingStartPos-encodingbeforeend);
LEncodingStartPos := EncodingBeforeEnd;
end;
end;
// Get the HeaderEncoding
if TextIsSame(HeaderEncoding, 'Q') {Do not Localize}
and EncodingFound then begin
i := 1;
s := ''; {Do not Localize}
repeat // substring can be accessed by index here, because we know that it ends with '?=' {Do not Localize}
if substring[i] = '_' then {Do not Localize}
begin
s := s + ' '; {Do not Localize}
end else if (substring[i] = '=') and (Length(substring)>=i+2+2) then //make sure we can access i+2 and '?=' is still beyond {Do not Localize}
begin
s := s + chr(Sys.StrToInt('$' + substring[i+1] + substring[i+2])); {Do not Localize}
inc(i,2);
end else
begin
s := s + substring[i];
end;
inc(i);
until (substring[i]='?') and (substring[i+1]='='); {Do not Localize}
s:=UTF8Decode(s);
end else if EncodingFound then
begin
S := Copy(Substring,1,Length(Substring)-2);
aDecoder := TIdDecoderMIMELineByLine.Create(nil);
try
aDecoder.Clear;
S := aDecoder.DecodeString(S);
if TCharSet<>'' then s:=UTF8Decode(s);
finally
Sys.FreeAndNil(aDecoder);
end;
end;
if EncodingFound then
begin
if TextIsSame(HeaderCharSet, 'ISO-2022-JP') then {Do not Localize}
begin
substring := Decode2022JP(s);
end else
begin
substring := s;
end;
//replace old substring in header with decoded one:
header := Copy(header, 1, LEncodingStartPos - 1)
+ substring + Copy(header, encodingendpos + 2, Length(Header));
encodingendpos := length(substring);
substring := ''; {Do not Localize}
end;
end;
end;
encodingendpos := LEncodingStartPos + encodingendpos;
{CC: Bug fix - changed LEncodingStartPos to LPreviousEncodingStartPos because
LEncodingStartPos gets overwritten by return value from PosIdx.}
LPreviousEncodingStartPos := LEncodingStartPos;
LEncodingStartPos := PosIdx('=?ISO', Sys.UpperCase(Header), LPreviousEncodingStartPos + 1); {do not localize}
if LEncodingStartPos = 0 then begin
LEncodingStartPos := PosIdx('=?WINDOWS', Sys.UpperCase(Header), LPreviousEncodingStartPos + 1); {do not localize}
end;
if LEncodingStartPos = 0 then begin
LEncodingStartPos := PosIdx('=?KOI8', Sys.UpperCase(Header), LPreviousEncodingStartPos + 1); {do not localize}
end;
if LEncodingStartPos = 0 then begin
LEncodingStartPos := PosIdx('=?UTF-8', Sys.UpperCase(Header), 1); {do not localize}
end;
if LEncodingStartPos = 0 then begin
LEncodingStartPos := PosIdx('=?GBK', Sys.UpperCase(Header), 1); {do not localize}
end;
if LEncodingStartPos = 0 then begin
LEncodingStartPos := PosIdx('=?GB2312', Sys.UpperCase(Header), 1); {do not localize}
end;
if LEncodingStartPos = 0 then begin
LEncodingStartPos := PosIdx('=?GB18030', Sys.UpperCase(Header), 1); {do not localize}
end;
// delete whitespace between adjacent encoded words, but only
// if we had an encoding before
if EncodingFound then begin
EncodingBeforeEnd := encodingendpos;
end else begin
EncodingBeforeEnd := -1;
end;
end;
//There might be #0's in header when this it b64 encoded, e.g with:
//decodeheader('"Fernando Corti=?ISO-8859-1?B?8Q==?=a" <fernando@nowhere.com>');
while Pos(#0, header) > 0 do begin
Delete(header, Pos(#0, header), 1);
end;
Result := Header;
end;