如题我用delphi练习写了一个简答的邮件接收程序,但是邮件主题和接收到的邮件内容,有部分可以正常显示,有部分却是乱码。我已经在网上找了一个解码函数base64函数。但是还是有部分不能正常读出邮件主题和邮件内容。好像发邮件可会有这个问题,所以发邮件的代码暂时没写
我把代码贴出:
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus, ImgList, IdMessage, IdBaseComponent, IdComponent,
IdTCPConnection, IdTCPClient, IdMessageClient, IdSMTP, ExtCtrls, sPanel,
StdCtrls, sMemo, ComCtrls, sListView, sStatusBar, sSkinManager, ToolWin,
sToolBar, IdPOP3, sDialogs, IdAntiFreezeBase, IdAntiFreeze, IdCoder,
IdCoder3to4, IdCoderMIME;type
TFormMain = class(TForm)
sPanel1: TsPanel;
IdSMTP1: TIdSMTP;
IdMessage1: TIdMessage;
MainMenu1: TMainMenu;
ImageList1: TImageList;
N1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem;
N4: TMenuItem;
N5: TMenuItem;
sToolBar1: TsToolBar;
sSkinManager1: TsSkinManager;
ToolButton1: TToolButton;
sStatusBar1: TsStatusBar;
lvMail: TsListView;
memoMail: TsMemo;
lvAttach: TsListView;
IdPOP31: TIdPOP3;
ToolButton3: TToolButton;
sSaveDialog1: TsSaveDialog;
sOpenDialog1: TsOpenDialog;
IdAntiFreeze1: TIdAntiFreeze;
N6: TMenuItem;
IdDecoderMIME1: TIdDecoderMIME;
IdEncoderMIME1: TIdEncoderMIME;
procedure N2Click(Sender: TObject);
procedure lvAttachDblClick(Sender: TObject);
procedure lvMailDblClick(Sender: TObject);
procedure N6Click(Sender: TObject);
function DecodeBase64(s: string): String;
private
{ Private declarations }
public
{ Public declarations }
end;var
FormMain: TFormMain;implementation
uses unit2;
{$R *.dfm}
//----Base64编码转换----//
function TFormMain.DecodeBase64(s: string): String;
var
s1,s2,s3: integer;
t,v: string;
Encoding: char;
hex,step: integer;
a1: array[1..4] of byte;
b1: array[1..3] of byte;
j: integer;
byte_ptr,real_bytes: integer;
begin
s1:=Pos('=?',s);
s2:= 1 ;
hex:= 0 ;
if s1>0 then
begin
for s2:=Length(s)-1 downto 1 do
begin
if Copy(s,s2,2)='?=' then Break;
end;
end;
if (s1=0) or (s2=1) then
begin
Result:=s;
Exit;
end;
t:=Copy(s,s1+2,s2-2-s1);
s3:=Pos('?',t);
Delete(t,1,s3);
if(t='')then
begin
Result:= s;
Exit ;
end ;
Encoding:=t[1];
Delete(t,1,2);
v:='';
step:=0;
case Encoding of
'Q':
while t<>'' do
begin
case step of
0:
begin
case t[1] of
'_': v:=v+' ';
'=': step:=1;
else v:=v+t[1];
end;
end;
1:
begin
if t[1]<='9' then hex:=(Ord(t[1])-Ord('0'))*16
else hex:=(Ord(t[1])-55)*16;
step:=2;
end;
2:
begin
if t[1]<='9' then hex:=hex+(Ord(t[1])-Ord('0'))
else hex:=hex+Ord(t[1])-55;
v:=v+Chr(hex);
step:=0;
end;
end;
Delete(t,1,1);
end;
'B':
begin
byte_ptr:=0;
for j:=1 to Length(t) do
begin
Inc(byte_ptr);
case t[j] of
'A'..'Z': a1[byte_ptr]:=Ord(t[j])-65;
'a'..'z': a1[byte_ptr]:=Ord(t[j])-71;
'0'..'9': a1[byte_ptr]:=Ord(t[j])+4;
'+': a1[byte_ptr]:=62;
'/': a1[byte_ptr]:=63;
'=': a1[byte_ptr]:=64;
end;
if byte_ptr=4 then
begin
byte_ptr:=0;
real_bytes:=3;
if a1[1]=64 then real_bytes:=0;
if a1[3]=64 then
begin
a1[3]:=0;
a1[4]:=0;
real_bytes:=1;
end;
if a1[4]=64 then
begin
a1[4]:=0;
real_bytes:=2;
end;
b1[1]:=a1[1]*4+(a1[2] div 16);
b1[2]:=(a1[2] mod 16)*16+(a1[3]div 4);
b1[3]:=(a1[3] mod 4)*64 +a1[4];
if(real_bytes>0)then
v:= v + chr(b1[1]) ;
if(real_bytes>1)then
v:= v + chr(b1[2]) ;
if(real_bytes>2)then
v:= v + chr(b1[3]) ;
end;
end;
end;
end;
Result := v;
end;procedure TFormMain.N2Click(Sender: TObject);
var
Index:Integer;
MailSum:dword;
MailItem:TlistItem;
begin lvmail.Items.Clear;
if IdPOP31.Connected then
begin
IdPOP31.Connect;
end
else
begin
IdPOP31.Host:=FormConfig.edtPOP3.Text;
IdPOP31.Port:=strtoint(formconfig.edtPOP3port.text);
IdPOP31.Username:=FormConfig.edtUser.Text;
IdPOP31.Password:=FormConfig.edtPW.text;
IdPOP31.Connect;
Mailsum:=Idpop31.CheckMessages;//获得邮件数
if MailSum > 0 then
sStatusBar1.SimpleText:='共有'+inttostr(MailSum)+'封邮件'
else
showmessage('没有邮件');
for index := 1 to MailSum do
begin
IdMessage1.Clear;
IdPOP31.RetrieveHeader(index,IdMessage1);//获取邮件头部信息
MailItem:=lvmail.items.add;
MailItem.Caption:=inttostr(index);
MailItem.SubItems.Add((DecodeBase64(IdMessage1.Subject)));//邮件主题
MailItem.SubItems.Add(IdMessage1.From.Address);//文件
MailItem.SubItems.Add(FormatDateTime('yyyy-mm-dd hh:mm:ss',IdMessage1.Date));//时间
MailItem.SubItems.Add(IntToStr(IdPOP31.RetrieveMsgSize(index) div 1024)+'K');//大小
IdMessage1.Clear;
IdPOP31.Retrieve(Index,IdMessage1);//获取邮件
IdMessage1.MessageParts.CountParts;//获得邮件的分部分计算
if IdMessage1.MessageParts.AttachmentCount >0 then
MailItem.ImageIndex:= 5 //有附件
else
MailItem.ImageIndex:=4;
end;
end;
end;
procedure TFormMain.lvAttachDblClick(Sender: TObject);
var
Index:Integer;
begin
Index:=StrToInt(lvAttach.ItemFocused.Caption);//这里隐藏额序列号
if sSaveDialog1.Execute then
begin
TIdAttachment(IdMessage1.MessageParts.Items[index]).SaveToFile((sSaveDialog1.FileName));
end;
end;procedure TFormMain.lvMailDblClick(Sender: TObject);
var
Index:integer;
AttachItem:TListItem;
begin
MemoMail.Lines.Clear;
LVAttach.Items.Clear;
IdMessage1.Clear;
IdMessage1.ContentType:='Multipart/*';//邮件类型
sStatusBar1.SimpleText:='开始接收';
IdPOP31.Retrieve(LVmail.ItemIndex+1,IdMessage1);
sStatusBar1.SimpleText:='接收完毕';
memomail.Lines:=IdMessage1.Body;//邮件正文
for Index:=0 to Pred(IdMessage1.MessageParts.Count) do
begin
if IdMessage1.MessageParts.Items[Index] is TIdAttachment then
begin
AttachItem:=lvAttach.Items.Add;
AttachItem.Caption:=IntTostr(index);
AttachItem.SubItems.Add(TIdAttachMent(IdMessage1.MessageParts.Items[Index]).FileName);
end
else if IdMessage1.MessageParts.Items[index] is TIdText then
begin
MemoMail.Lines.Clear;
MemoMail.Lines.AddStrings(TIdText(IdMessage1.MessageParts.Items[Index]).Body);
end;
end;
end;procedure TFormMain.N6Click(Sender: TObject);
begin
FormConfig.showmodal;//显示设置邮件服务器窗体
end;
end.现在主要有3个问题:
1,邮件乱码
2,为什么在接收邮件时程序出现假死
3,发邮件乱码的解决办法
希望大大们帮助解答
我把代码贴出:
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus, ImgList, IdMessage, IdBaseComponent, IdComponent,
IdTCPConnection, IdTCPClient, IdMessageClient, IdSMTP, ExtCtrls, sPanel,
StdCtrls, sMemo, ComCtrls, sListView, sStatusBar, sSkinManager, ToolWin,
sToolBar, IdPOP3, sDialogs, IdAntiFreezeBase, IdAntiFreeze, IdCoder,
IdCoder3to4, IdCoderMIME;type
TFormMain = class(TForm)
sPanel1: TsPanel;
IdSMTP1: TIdSMTP;
IdMessage1: TIdMessage;
MainMenu1: TMainMenu;
ImageList1: TImageList;
N1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem;
N4: TMenuItem;
N5: TMenuItem;
sToolBar1: TsToolBar;
sSkinManager1: TsSkinManager;
ToolButton1: TToolButton;
sStatusBar1: TsStatusBar;
lvMail: TsListView;
memoMail: TsMemo;
lvAttach: TsListView;
IdPOP31: TIdPOP3;
ToolButton3: TToolButton;
sSaveDialog1: TsSaveDialog;
sOpenDialog1: TsOpenDialog;
IdAntiFreeze1: TIdAntiFreeze;
N6: TMenuItem;
IdDecoderMIME1: TIdDecoderMIME;
IdEncoderMIME1: TIdEncoderMIME;
procedure N2Click(Sender: TObject);
procedure lvAttachDblClick(Sender: TObject);
procedure lvMailDblClick(Sender: TObject);
procedure N6Click(Sender: TObject);
function DecodeBase64(s: string): String;
private
{ Private declarations }
public
{ Public declarations }
end;var
FormMain: TFormMain;implementation
uses unit2;
{$R *.dfm}
//----Base64编码转换----//
function TFormMain.DecodeBase64(s: string): String;
var
s1,s2,s3: integer;
t,v: string;
Encoding: char;
hex,step: integer;
a1: array[1..4] of byte;
b1: array[1..3] of byte;
j: integer;
byte_ptr,real_bytes: integer;
begin
s1:=Pos('=?',s);
s2:= 1 ;
hex:= 0 ;
if s1>0 then
begin
for s2:=Length(s)-1 downto 1 do
begin
if Copy(s,s2,2)='?=' then Break;
end;
end;
if (s1=0) or (s2=1) then
begin
Result:=s;
Exit;
end;
t:=Copy(s,s1+2,s2-2-s1);
s3:=Pos('?',t);
Delete(t,1,s3);
if(t='')then
begin
Result:= s;
Exit ;
end ;
Encoding:=t[1];
Delete(t,1,2);
v:='';
step:=0;
case Encoding of
'Q':
while t<>'' do
begin
case step of
0:
begin
case t[1] of
'_': v:=v+' ';
'=': step:=1;
else v:=v+t[1];
end;
end;
1:
begin
if t[1]<='9' then hex:=(Ord(t[1])-Ord('0'))*16
else hex:=(Ord(t[1])-55)*16;
step:=2;
end;
2:
begin
if t[1]<='9' then hex:=hex+(Ord(t[1])-Ord('0'))
else hex:=hex+Ord(t[1])-55;
v:=v+Chr(hex);
step:=0;
end;
end;
Delete(t,1,1);
end;
'B':
begin
byte_ptr:=0;
for j:=1 to Length(t) do
begin
Inc(byte_ptr);
case t[j] of
'A'..'Z': a1[byte_ptr]:=Ord(t[j])-65;
'a'..'z': a1[byte_ptr]:=Ord(t[j])-71;
'0'..'9': a1[byte_ptr]:=Ord(t[j])+4;
'+': a1[byte_ptr]:=62;
'/': a1[byte_ptr]:=63;
'=': a1[byte_ptr]:=64;
end;
if byte_ptr=4 then
begin
byte_ptr:=0;
real_bytes:=3;
if a1[1]=64 then real_bytes:=0;
if a1[3]=64 then
begin
a1[3]:=0;
a1[4]:=0;
real_bytes:=1;
end;
if a1[4]=64 then
begin
a1[4]:=0;
real_bytes:=2;
end;
b1[1]:=a1[1]*4+(a1[2] div 16);
b1[2]:=(a1[2] mod 16)*16+(a1[3]div 4);
b1[3]:=(a1[3] mod 4)*64 +a1[4];
if(real_bytes>0)then
v:= v + chr(b1[1]) ;
if(real_bytes>1)then
v:= v + chr(b1[2]) ;
if(real_bytes>2)then
v:= v + chr(b1[3]) ;
end;
end;
end;
end;
Result := v;
end;procedure TFormMain.N2Click(Sender: TObject);
var
Index:Integer;
MailSum:dword;
MailItem:TlistItem;
begin lvmail.Items.Clear;
if IdPOP31.Connected then
begin
IdPOP31.Connect;
end
else
begin
IdPOP31.Host:=FormConfig.edtPOP3.Text;
IdPOP31.Port:=strtoint(formconfig.edtPOP3port.text);
IdPOP31.Username:=FormConfig.edtUser.Text;
IdPOP31.Password:=FormConfig.edtPW.text;
IdPOP31.Connect;
Mailsum:=Idpop31.CheckMessages;//获得邮件数
if MailSum > 0 then
sStatusBar1.SimpleText:='共有'+inttostr(MailSum)+'封邮件'
else
showmessage('没有邮件');
for index := 1 to MailSum do
begin
IdMessage1.Clear;
IdPOP31.RetrieveHeader(index,IdMessage1);//获取邮件头部信息
MailItem:=lvmail.items.add;
MailItem.Caption:=inttostr(index);
MailItem.SubItems.Add((DecodeBase64(IdMessage1.Subject)));//邮件主题
MailItem.SubItems.Add(IdMessage1.From.Address);//文件
MailItem.SubItems.Add(FormatDateTime('yyyy-mm-dd hh:mm:ss',IdMessage1.Date));//时间
MailItem.SubItems.Add(IntToStr(IdPOP31.RetrieveMsgSize(index) div 1024)+'K');//大小
IdMessage1.Clear;
IdPOP31.Retrieve(Index,IdMessage1);//获取邮件
IdMessage1.MessageParts.CountParts;//获得邮件的分部分计算
if IdMessage1.MessageParts.AttachmentCount >0 then
MailItem.ImageIndex:= 5 //有附件
else
MailItem.ImageIndex:=4;
end;
end;
end;
procedure TFormMain.lvAttachDblClick(Sender: TObject);
var
Index:Integer;
begin
Index:=StrToInt(lvAttach.ItemFocused.Caption);//这里隐藏额序列号
if sSaveDialog1.Execute then
begin
TIdAttachment(IdMessage1.MessageParts.Items[index]).SaveToFile((sSaveDialog1.FileName));
end;
end;procedure TFormMain.lvMailDblClick(Sender: TObject);
var
Index:integer;
AttachItem:TListItem;
begin
MemoMail.Lines.Clear;
LVAttach.Items.Clear;
IdMessage1.Clear;
IdMessage1.ContentType:='Multipart/*';//邮件类型
sStatusBar1.SimpleText:='开始接收';
IdPOP31.Retrieve(LVmail.ItemIndex+1,IdMessage1);
sStatusBar1.SimpleText:='接收完毕';
memomail.Lines:=IdMessage1.Body;//邮件正文
for Index:=0 to Pred(IdMessage1.MessageParts.Count) do
begin
if IdMessage1.MessageParts.Items[Index] is TIdAttachment then
begin
AttachItem:=lvAttach.Items.Add;
AttachItem.Caption:=IntTostr(index);
AttachItem.SubItems.Add(TIdAttachMent(IdMessage1.MessageParts.Items[Index]).FileName);
end
else if IdMessage1.MessageParts.Items[index] is TIdText then
begin
MemoMail.Lines.Clear;
MemoMail.Lines.AddStrings(TIdText(IdMessage1.MessageParts.Items[Index]).Body);
end;
end;
end;procedure TFormMain.N6Click(Sender: TObject);
begin
FormConfig.showmodal;//显示设置邮件服务器窗体
end;
end.现在主要有3个问题:
1,邮件乱码
2,为什么在接收邮件时程序出现假死
3,发邮件乱码的解决办法
希望大大们帮助解答
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货