Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Интернет и сети
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 07.07.2013, 13:40
RobinStone RobinStone вне форума
Прохожий
 
Регистрация: 02.06.2013
Сообщения: 27
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию "КРАКОЗЯБЛИ" в почте

Добрый день уважаемые господа програмисты! И вновь требуется Ваша помощь (как обычно в нашем теперешнем мире). Есть программа которая читает почту. Этакий почтовый клиент. Однако при отображении текста в memo, например, текст выглядит как "Алекс-Юстасу", сплошная шифрограмма. Вопрос : как быть?
зарание спасибо!
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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  
Старый 07.07.2013, 13:42
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Текст в разных кодировках может передаваться (UTF-8, KOI-8, ISO...), нужно просто перекодировать.
И да, кто так код форматирует? Это ж пипетс.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #3  
Старый 07.07.2013, 21:38
RobinStone RobinStone вне форума
Прохожий
 
Регистрация: 02.06.2013
Сообщения: 27
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

в смысле кто так код форматирует?
- Я так форматирую, а что не так?
То,что нужно перекодировать - я думаю понятно было и мне (иначе зачем бы я стал бы об этом спрашивать), Вы бы подсказали или показали как это делать
Ответить с цитированием
  #4  
Старый 07.07.2013, 22:14
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

В пакете инди есть набор перекодировщиков, поиск по файлам сделай по слову KOI.
А про форматирование - этот код жеж на экран не влезает, обычно так форматируется он:
Код:
1
2
3
4
5
6
7
8
9
10
if blalblalbalbalblalbalblablablalalaablbla then
begin
  for bsmdbmslgbslfnlsnbslknr do
  begin
    while true do
    begin
 
    end;
  end;
end;

З.Ы. В вопросе было "как быть?" а "покажите, как перекодировать".
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #5  
Старый 07.07.2013, 22:22
RobinStone RobinStone вне форума
Прохожий
 
Регистрация: 02.06.2013
Сообщения: 27
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Уважаемый M.A.D.M.A.N. !
Действительно не правильно спросил!
Спрашиваю правильно : покажите как перекодировать текст.
Ответить с цитированием
  #6  
Старый 07.07.2013, 22:28
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,723
Репутация: 52347
По умолчанию

Не, ну конечно вам виднее, как оформлять. Просто несколько широковато выходит. Я например конструкцию if then else оформляю немножко покомпактнее, но кому-то тоже так не нравится. Вот скажем ваш код с моим вариантом форматирования:
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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  
Старый 07.07.2013, 22:37
RobinStone RobinStone вне форума
Прохожий
 
Регистрация: 02.06.2013
Сообщения: 27
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

да, действительно, так - значительно приятнее. Но мне бы всё-же хотелось узнать как перекодировать текст который я получаю с почты. ?
Ответить с цитированием
  #8  
Старый 07.07.2013, 22:50
RobinStone RobinStone вне форума
Прохожий
 
Регистрация: 02.06.2013
Сообщения: 27
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

вот я получаю текст письма
Код:
1
2
Form1.TIdPOP.Retrieve(f,Form1.IdMessage2);
str:=  Form1.IdMessage2.Subject;

и вот именно в этом самом str и обнаруживается что то вроди ?koi-8?... или что -то в этом роде. Во первых что это такое (ладно этоя знаю, это другая кодировка), но при помощи какой функции текст можно сделать читабельным?
В моём почтовом клиенте, клиент, после настроек программы (адрес почты, пароль), должен увидеть сколько писем в ящике и какие темы у этих писем, мне нужно что бы надписи отображались корректно.
Ответить с цитированием
  #9  
Старый 08.07.2013, 07:05
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,105
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Цитата:
Сообщение от RobinStone
вот я получаю текст письма
Код:
1
2
Form1.TIdPOP.Retrieve(f,Form1.IdMessage2);
str:=  Form1.IdMessage2.Subject;

Боролся как-то с этим.
Для начала проверь у TIdMessage свойство автоматической декодировки (не помню как называется, мне не сильно помогло, так что забил). Что-то, может и автоматом декодирует.
Потом просто сделал себе функцию (меня интересовал только utf-8, но можно туда добавить кодировок) (Тапками за код не кидать, писалось давно, недавно только чуть-чуть правилось. Если есть желающие прикрутить различные кодировки, код отдается под GPL ):
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
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  
Старый 08.07.2013, 07:55
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Вроде в классе 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;

Короче найдешь, если есть терпение.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию

Последний раз редактировалось M.A.D.M.A.N., 08.07.2013 в 08:06.
Ответить с цитированием
Этот пользователь сказал Спасибо M.A.D.M.A.N. за это полезное сообщение:
RobinStone (08.07.2013)
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 04:23.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025