![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
|
Добрый день уважаемые господа програмисты! И вновь требуется Ваша помощь (как обычно в нашем теперешнем мире). Есть программа которая читает почту. Этакий почтовый клиент. Однако при отображении текста в memo, например, текст выглядит как "Алекс-Юстасу", сплошная шифрограмма. Вопрос : как быть?
зарание спасибо! Код:
procedure TForm1.SpeedButtonClick(Sender: TObject);
var f: Integer;
name: string;
begin
cler;
if work = True then begin
try
Form1.TIdPOP.Connect();
if Form1.TIdPOP.Connected = True then begin
all:= Form1.TIdPOP.CheckMessages;
Form1.Label1.Caption:= IntToStr(all);
form1.Label3.Font.Color:= clLime;
form1.Label3.Caption:= '> Последний просмотр был в '+timeToStr(Now);
Form1.lst1.Clear;
for f:= 1 to all do begin
Form1.IdMessage2.Clear;
Form1.TIdPOP.Retrieve(f,Form1.IdMessage2);
Form1.IdMessage2.CharSet:='koi8-r';
if Form1.IdMessage2.Subject = '' then begin
name:= 'Нет заголовка.';
dat:= 'not';
tim:= 'not';
end
else begin
dat:= DateToStr(Form1.IdMessage2.Date);
name:= form1.IdMessage2.Subject;
tim:= TimeToStr(Form1.IdMessage2.Date);
end;
Form1.lst1.Items.Add('');
Form1.lst1.Items[f-1]:= IntToStr(f)+ ' > '+ name + ' : '+dat+ ' / '+tim;
end;
if allMemory > all then allMemory:= all;
if (allMemory <> all) and (first = False) and (Form2.CheckBox1.Checked = True) then theMail;
if first = True then begin
first:= False;
allMemory:= all;
end;
end;
except
Form1.Label3.Font.Color:= clRed;
form1.Label3.Caption:= '> Превышен лимит времени TIME OUT !';
end;
Form1.TIdPOP.Disconnect;
end else form1.Label3.Caption:= '> Не установлены данные адреса! Войдите в НАСТРОЙКИ';
end; |
|
#2
|
||||
|
||||
|
Текст в разных кодировках может передаваться (UTF-8, KOI-8, ISO...), нужно просто перекодировать.
И да, кто так код форматирует? Это ж пипетс. |
|
#3
|
|||
|
|||
|
в смысле кто так код форматирует?
- Я так форматирую, а что не так? То,что нужно перекодировать - я думаю понятно было и мне (иначе зачем бы я стал бы об этом спрашивать), Вы бы подсказали или показали как это делать |
|
#4
|
||||
|
||||
|
В пакете инди есть набор перекодировщиков, поиск по файлам сделай по слову KOI.
А про форматирование - этот код жеж на экран не влезает, обычно так форматируется он: Код:
if blalblalbalbalblalbalblablablalalaablbla then
begin
for bsmdbmslgbslfnlsnbslknr do
begin
while true do
begin
end;
end;
end;З.Ы. В вопросе было "как быть?" а "покажите, как перекодировать". |
|
#5
|
|||
|
|||
|
Уважаемый M.A.D.M.A.N. !
Действительно не правильно спросил! Спрашиваю правильно : покажите как перекодировать текст. |
|
#6
|
||||
|
||||
|
Не, ну конечно вам виднее, как оформлять. Просто несколько широковато выходит. Я например конструкцию if then else оформляю немножко покомпактнее, но кому-то тоже так не нравится. Вот скажем ваш код с моим вариантом форматирования:
Код:
procedure TForm1.SpeedButtonClick(Sender: TObject);
var f: Integer;
name: string;
begin
cler;
if work
then begin
try
Form1.TIdPOP.Connect();
if Form1.TIdPOP.Connected
then begin
all:= Form1.TIdPOP.CheckMessages;
Form1.Label1.Caption:= IntToStr(all);
form1.Label3.Font.Color:= clLime;
form1.Label3.Caption:= '> Последний просмотр был в '+timeToStr(Now);
Form1.lst1.Clear;
for f:= 1 to all
do begin
Form1.IdMessage2.Clear;
Form1.TIdPOP.Retrieve(f,Form1.IdMessage2);
Form1.IdMessage2.CharSet:='koi8-r';
if Form1.IdMessage2.Subject = ''
then begin
name:= 'Нет заголовка.';
dat:= 'not';
tim:= 'not';
end
else begin
dat:= DateToStr(Form1.IdMessage2.Date);
name:= form1.IdMessage2.Subject;
tim:= TimeToStr(Form1.IdMessage2.Date);
end;
Form1.lst1.Items.Add('');
Form1.lst1.Items[f-1]:= IntToStr(f)+ ' > '+ name + ' : '+dat+ ' / '+tim;
end;
if allMemory > all
then allMemory:= all;
if (allMemory <> all) and (first = False) and (Form2.CheckBox1.Checked = True)
then theMail;
if first = True
then begin
first:= False;
allMemory:= all;
end;
end;
except
Form1.Label3.Font.Color:= clRed;
form1.Label3.Caption:= '> Превышен лимит времени TIME OUT !';
end;
Form1.TIdPOP.Disconnect;
end
else form1.Label3.Caption:= '> Не установлены данные адреса! Войдите в НАСТРОЙКИ';
end; |
|
#7
|
|||
|
|||
|
да, действительно, так - значительно приятнее. Но мне бы всё-же хотелось узнать как перекодировать текст который я получаю с почты. ?
|
|
#8
|
|||
|
|||
|
вот я получаю текст письма
Код:
Form1.TIdPOP.Retrieve(f,Form1.IdMessage2); str:= Form1.IdMessage2.Subject; и вот именно в этом самом str и обнаруживается что то вроди ?koi-8?... или что -то в этом роде. Во первых что это такое (ладно этоя знаю, это другая кодировка), но при помощи какой функции текст можно сделать читабельным? В моём почтовом клиенте, клиент, после настроек программы (адрес почты, пароль), должен увидеть сколько писем в ящике и какие темы у этих писем, мне нужно что бы надписи отображались корректно. |
|
#9
|
|||
|
|||
|
Цитата:
Боролся как-то с этим. Для начала проверь у TIdMessage свойство автоматической декодировки (не помню как называется, мне не сильно помогло, так что забил). Что-то, может и автоматом декодирует. Потом просто сделал себе функцию (меня интересовал только utf-8, но можно туда добавить кодировок) (Тапками за код не кидать, писалось давно, недавно только чуть-чуть правилось. Если есть желающие прикрутить различные кодировки, код отдается под GPL ):Код:
unit EmlStrUtils;
interface
uses
Windows, SysUtils, Classes, StrUtils;
function DecodeEmailString(S : String) : String;
implementation
uses
IdCoder, IdCoder3to4, IdCoderMIME, IdCoderQuotedPrintable;
function Base64Decode(const EncodedText: string): String;
var
Decoder: TIdDecoderMIME;
begin
Result := EncodedText;
Decoder := TIdDecoderMIME.Create(nil);
try
Result := Decoder.DecodeString(EncodedText);
finally
Decoder.Free;
end;
end;
function QuotedPrintableDecode(const EncodedText: string): String;
var
Decoder: TIdDecoderQuotedPrintable;
begin
Result := EncodedText;
Decoder := TIdDecoderQuotedPrintable.Create(nil);
try
Result := Decoder.DecodeString(EncodedText);
finally
Decoder.Free;
end;
end;
function DecodeTocken(S : String) : String;
var
SecondQuestIdx : Integer;
ThirdQuestIdx : Integer;
Txt : String;
begin
// =?charset?encoding?encoded text?=
// =?utf-8?B?<text>?=
// =?utf-8?Q?=D0=A5=D0=B0=D0=B9=D0=B9_...=21=21=21=29_?=
Result := S;
If Pos('=?',S) = 1 Then
Begin
SecondQuestIdx := PosEx('?',S,3);
ThirdQuestIdx := PosEx('?',S,SecondQuestIdx+1);
Txt := Copy(S,ThirdQuestIdx+1,Length(S)-ThirdQuestIdx-2);
Case S[SecondQuestIdx+1] Of
'B', 'b' :
Begin
Result := Base64Decode(Txt);
If CompareText('utf-8',Copy(S,3,SecondQuestIdx-1-2)) = 0
Then Result := Utf8ToAnsi(Result);
End;
'Q', 'q' :
Begin
Result := QuotedPrintableDecode(Txt);
End;
End;
End;
end;
procedure SplitTockens(S : String; var AList : TStringList);
var
Idx1, Idx2, Idx3 : Integer;
begin
While S <> '' Do
Begin
Idx1 := Pos('=?',S);
If Idx1 = 0
Then
Begin
AList.Add(S);
S := '';
End
Else
If Idx1 > 1
Then
Begin
AList.Add(Copy(S,1,Idx1-1));
S := Copy(S,Idx1,Length(S));
End
Else
Begin
Idx2 := PosEx('?',S,3);
Idx3 := PosEx('?',S,Idx2+1);
AList.Add(Copy(S,1,PosEx('?=',S,Idx3+1)+1));
S := Copy(S,PosEx('?=',S,Idx3+1)+2,Length(S));
End;
End;
end;
function DecodeEmailString(S : String) : String;
var
I : Integer;
AList : TStringList;
begin
// =?charset?encoding?encoded text?=
// =?utf-8?B?<text>?=
// =?utf-8?Q?=D0=A5=D0=B0=D0=B9=D0=B9_...=21=21=21=29_?=
Result := S;
If Pos('=?',S) <> 0 Then
Begin
Result := '';
AList := TStringList.Create;
Try
// Split tockens
SplitTockens(S,AList);
// Decode
For I := 0 To AList.Count-1 Do
AList[i] := DecodeTocken(AList[i]);
// Join result
For I := 0 To AList.Count-1 Do
Result := Result + AList[i];
Finally
AList.Free;
End;
End;
end;
end.ЗЫ. Да, Indy у меня не родная Дельфевая, а более новая, скаченная с сайта индей... |
| Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
RobinStone (08.07.2013)
| ||
|
#10
|
||||
|
||||
|
Вроде в классе TIdMessage есть какие-то ф-ии для перекодирования. Говорю же, поищи по *.pas файлам в инди, там есть, я когда свой велосипед почтовый делал, натыкался на те функции.
"C:\Program Files\Embarcadero\RAD Studio\10.0\source\xml\Xml.Internal.EncodingUtils. pas" "C:\Program Files\Borland\Delphi7\Source\XML\xdom.pas" function KOI8_RToUTF16Char(const P: Char):WideChar; Короче найдешь, если есть терпение. Последний раз редактировалось M.A.D.M.A.N., 08.07.2013 в 08:06. |
| Этот пользователь сказал Спасибо M.A.D.M.A.N. за это полезное сообщение: | ||
RobinStone (08.07.2013)
| ||