用Delphi编程发送E-mail
接发E-mail是许多“网虫”必修的功课,E-mail工具软件也很多,国外的有Microsoft的Outlook Express、The Bat等,国内则有FoxMail这样的精品。
其实,利用可视化编程工具Delphi4.0也能够制作出自己的E-mail软件。
Delphi4.0有关E-mail的组件有两个:NmPOP3和NmSTMP,它们都位于Internet 选项卡上,其中,NmPOP3组件封装并实现POP3协议,用来从Internet POP3服务 器上读取电子邮件;NmSTMP封装并实现STMP协议,可用来向Internet的STMP服务器发送电子邮件。限于篇幅,我们不能两者都介绍,这里只用NmSTMP编写一个发送E-mail的程序,至于NmPOP3,以后有机会再谈,或者在看完本文后你有兴趣,也可以借助于Delphi的帮助文档尝试用NmPOP3编程。
我们先来看一下程序运行界面。图1是程序主窗体,上面有一个字符串网格(StringGrid)和三个按钮,它们的容器是仅有一个标签的PageControl。单击“Clear”钮清除网格内容,单击“Send”钮发送E-mail,单击“New Mail”钮弹出图2所示的对话框,此对话框用来设置STMP服务器名称、发件人地址、收件人地址、发件人名称和邮件主题,其中前三项必须填写,“Select File”按钮用来打开Open对话框,以便选取要发送的附件。
NmSTMP的属性和方法不多,关键的属性是Host(STMP服务器名称)和PostMessage(包含邮件信息),正确设置了Host属性和PostMessage属性后,就可以用Connect方法(连接服务器)和SendMail方法发送E-mail了。
编写代码之前先要改变StringGrid1的一些缺省属性:ColCount属性为6,FixedCols属性为0,RowCount属性为2,另外,将PageControl1的Align属性置为alClient。
以下是Unit1(主窗体)代码清单:
unit Unit1;
interface
uses Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms,Dialogs,
Grids, ComCtrls, StdCtrls, Psock, NMsmtp;
type
TForm1 = class(TForm)
PageControl1: TPageControl;
TabSheet1: TTabSheet;
StatusBar1: TStatusBar;
StringGrid1: TStringGrid;
Button1: TButton;
Button2: TButton;
Button3: TButton;
NMSMTP1: TNMSMTP;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure NMSMTP1Failure(Sender: TObject);
procedure NMSMTP1SendStart(Sender: TObject);
procedure NMSMTP1Success(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses Unit2;
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
PageControl1.Pages[0].Caption:=‘Send Mail’;
self.Caption:=‘My Mailer’;
self.BorderIcons:=[biSystemMenu,biMinimize];
self.BorderStyle:=bsSingle;
Application.Icon:=self.Icon;
Application.Title:=self.Caption;
with StringGrid1 do
begin
Cells[0,0]:=‘Host’;
Cells[1,0]:=‘To Address’;
Cells[2,0]:=‘From Address’;
Cells[3,0]:=‘Your Name’;
Cells[4,0]:=‘Subject’;
Cells[5,0]:=‘File’;
end;
Button2.Enabled:=False;
Button3.Enabled:=False;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2.Show;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
i:Integer;
begin
for i:=1 to StringGrid1.RowCount-2 do
with Nmsmtp1 do
begin
Host:=StringGrid1.Cells[0,i];
PostMessage.ToAddress.Add(StringGrid1.Cells[1,i]);
PostMessage.FromAddress:=StringGrid1.Cells[2,i];
PostMessage.FromName:=StringGrid1.Cells[3,i];
PostMessage.Subject:=StringGrid1.Cells[4,i];
PostMessage.Attachments.Add(StringGrid1.Cells[5,i]);
Connect;
Sendmail;
DisConnect;
end;
Button2.Enabled:=False;
Button3.Click;
end;
procedure TForm1.Button3Click(Sender: TObject);
var
i:Integer;
begin
with StringGrid1 do
begin
for i:=1 to RowCount-2 do
begin
Cells[0,i]:=‘’;
Cells[1,i]:=‘’;
Cells[2,i]:=‘’;
Cells[3,i]:=‘’;
Cells[4,i]:=‘’;
Cells[5,i]:=‘’;
end;
RowCount:=2;
end;
Button2.Enabled:=False;
Button3.Enabled:=False;
end;
procedure TForm1.NMSMTP1Failure(Sender: TObject);
begin
StatusBar1.SimpleText:=‘Mail send failure!’;
end;
procedure TForm1.NMSMTP1SendStart(Sender: TObject);
begin
StatusBar1.SimpleText:=‘Now Sending...’;
end;
procedure TForm1.NMSMTP1Success(Sender: TObject);
begin
StatusBar1.SimpleText:=‘Send Success!’;
end;
end.
Button1是“NewMail”按钮,Button2是“Send”按钮,Button3是“Clear”按钮。
以下是Unit2代码清单:
unit Unit2;
interface
uses Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms,Dialogs, StdCtrls;
type
TForm2 = class(TForm)
OpenDialog1: TOpenDialog;
GroupBox1: TGroupBox;
GroupBox2: TGroupBox;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
uses Unit1;
{$R *.DFM}
procedure TForm2.FormCreate(Sender: TObject);
begin
self.Caption:=‘New Mail’;
self.BorderStyle:=bsDialog;
end;
procedure TForm2.FormActivate(Sender: TObject);
begin
Edit1.Text:=‘’;
Edit2.Text:=‘’;
Edit3.Text:=‘’;
Edit4.Text:=‘’;
Edit5.Text:=‘’;
Label1.Caption:=‘No File’;
end;
procedure TForm2.Button1Click(Sender: TObject);
begin
if OpenDialog1.Execute then
Label1.Caption:=Opendialog1.Filename;
end;
procedure TForm2.Button2Click(Sender: TObject);
var
i:Integer;
begin
if (Edit1.Text<>'') and (Edit2.Text<>'')
and (Edit5.Text<>'') and
(Label1.Caption<>'No File') then
begin
with Form1.StringGrid1 do
begin
RowCount:=RowCount+1;
i:=RowCount-2;
Cells[0,i]:=Edit1.Text;
Cells[1,i]:=Edit2.Text;
Cells[2,i]:=Edit5.Text;
Cells[3,i]:=Edit3.Text;
Cells[4,i]:=Edit4.Text;
Cells[5,i]:=Label1.Caption;
end;
Form1.Button2.Enabled:=True;
Form1.Button3.Enabled:=True;
end;
self.Hide;
end;
procedure TForm2.Button3Click(Sender: TObject);
begin
self.Hide;
end;
end.
Edit1、Edit2、Edit3、Edit4、Edit5编辑框分别用于填写服务器名称、收件人地址、发件人名称、邮件主题和发件人地址。
现在一个E-mail发送程序就完成了。你可以试一试,自已给自已发几封邮件,用FoxMail之类的软件是否能收到信。顺便说一句,本文就是用这个自编程序发到编辑部的。
--------------------------------------------------------------------------------
编写你的电子邮件软件
如果你每天上网,那么你肯定每天要使用电子邮件软件,有没有想过写一个属于自己的电子邮件软件,用自己写的软件来收信和发信,那种感觉肯定很好。
众所周知,Delphi这个windows开发平台中的贵族可以开发各个方面的应用程序,当然基于internet的程序用它开发也是得心应手。
从Delphi3开始,它自己的控件中就有了基于interent开发的控件,不过这些控件不是Delphi本身的vcl控件,而是ActiveX控件,这样多多少少对于应用程序的发布不是很方便。好在借助于Delphi强大的控件技术,我们可以从internet上找到很多免费的vcl控件来帮助我们写电子邮件软件,比较有名的是ics控件组和sakemai控件组。Ics是一个全面的internet程序解决方案,而sakemail是专门用来开发电子邮件软件的控件。本文就是要介绍如何使用sakemail控件来写支持POP3和SMTP协议的收信和发信程序。
一、下载和安装
sakemail在很多著名的Delphi站点都可以下载sakemail控件,比如www.torry.ru。在Delphi中安装sakemail是很简单的,先将下载的zip文件释放在你指定的目录中,在Delphi中选择打开文件,设定文件类型为dpk,然后选择目录下的emaildak.dpk文件,选择compile,然后install就行了。安装完后,会在控件的internet页中添加4个相应的控件。
二、收信程序
让我们先来看看利用POP3协议收信的范例程序是如何来写的。从这个设计时的画面(如图1)看到,收信主要利用sakemail的sakmsglist和sakpop控件。让我们来看看关键的按钮“Connect and retrieve msgs”后面的代码。
procedure TForm1.CntClick(Sender: TObject);
begin
//指定服务器
SakPOP1.Host := EditHost.text;
//指定用户名称
SakPOP1.UserId := EditUserId.text;
//指定用户密码
SakPOP1.Passwd := EditPasswd.text;
StatusBar1.Panels[0].text :=
'Wait a moment, please...';
SakPOP1.connect;//连接服务器
if SakPOP1.POPError then //连接服务器失败
begin
MessageDlg(
'Connect failed. Maybe the server is
down or not responding.',
mtError, [mbOk], 0);
exit;
end;
if not SakPOP1.login then //登陆服务器失败
begin
ShowMessage('Unauthorized access...');
exit;
end;
//显示共有多少电子邮件
showMessage( 'You have ' +
intToStr( SakPOP1.Init) + ' new msg(s) of ' +
intToStr(SakPOP1.MsgsCount));
BtnCancel.Enabled := true;
//接受电子邮件
sakPOP1.retrieveAllMessages( SakMsgList1);
BtnCancel.Enabled := false;
SakPOP1.quit; //退出POP3连接
if SakMsgList1.count > 0 then
begin
currentMsg := 0;
showCurrentMsg; //显示当前的电子邮件内容
end;
StatusBar1.Panels[0].text := 'Done. ' +
intToStr( SakMsgList1.count) + ' msgs retrieved.';
end;
在上面的程序中,我们已经加入了比较详细的注释。利用sakemail的控件来收取信件基本上有以下几个步骤:
1.服务器连接的准备工作。你需要制定服务器的域名、用户名和密码。用以下语句实现:
SakPOP1.Host:=EditHost.text;
SakPOP1.UserId:=EditUserId.text;
SakPOP1.Passwd:=EditPasswd.text;
2.服务器连接。在这个阶段如果一切正常,你只需要等待几秒,但是如果服务器地址错,或者用户名和密码错误,则会退出,需要重新连接。用以下语句实现:SakPOP1.connect3.获得邮件的数量。这是通过语句
SakPOP1.MsgsCount来获得的。
3.从服务器将邮件传送到本地。显示一封电子邮件由以下的过程完成:
//显示当前的邮件
procedure TForm1.showCurrentMsg;
var msg: TSakMsg;
i: integer;
begin
msg := SakMsgList1.items[ currentMsg];
labelMsgId.Caption := msg.MessageId;
labelInReplyTo.Caption := msg.InReplyTo;
labelFrom.caption := msg.From;
labelTo.caption := msg.SendTo;
labelSubject.caption := msg.Subject;
labelDate.caption := msg.Date;
labelReplyTo.Caption := msg.ReplyTo;
memo1.text := msg.Text.Text;
{msg.Text is a StringList}
if msg.AttachedFiles.Count > 0 then
begin
comboBoxAttach.items.clear;
for i := 0 to msg.AttachedFiles.Count-1 do
comboBoxAttach.items.add(
msg.AttachedFiles[ i].fileName);
comboBoxAttach.enabled := true;
comboBoxAttach.itemIndex := 0;
buttonSave.enabled := true;
end else begin
comboBoxAttach.enabled := false;
buttonSave.enabled := false;
end;
end;
从上面的过程我们可以看到显示一个电子邮件的内容的程序并不复杂,正文内容直接交给memo来显示,如果有附件的话,读出附件的数量,然后将其文件名写入combo box中。收信程序的框架就大致如此了(如图2)。下面我们来看看发信程序。
三、发信程序
单纯的发信程序很简单,我们来看看“send”按钮背后的代码:
//发信
procedure TForm1.ButtonSendClick(Sender: TObject);
begin
screen.cursor := crHourGlass;
StatusBar1.Panels[0].Text :=
'Wait a moment, please';
SakSMTP1.host := EditHost.text; //指定地址
SakMsg1.UserName := EditUserName.text;
//以下指定发送人有关信息
SakMsg1.From := EditFrom.text;
SakMsg1.SendTo := EditTo.text;
SakMsg1.Subject := EditSubject.text;
SakMsg1.Text.Assign( Memo1.Lines);//信件正文
SakSMTP1.connect;//连接服务器
if not SakSMTP1.SMTPError then
begin
BtnCancel.Enabled := true;
SakSMTP1.SendMessage( SakMsg1);
BtnCancel.Enabled := false;
SakSMTP1.quit;
StatusBar1.Panels[0].Text :=
SakSMTP1.ReplyString;
end;
screen.cursor := crDefault;
end;
发信有以下几个步骤: 1.指定发送邮件相关的信息,比如服务器地址、发信人等。
2.服务器连接。
3.如果连接正常,发送电子邮件。
利用SakeMail我们可以看到发信的步骤是比较简单的。同时sakemail的发信控件提供了很多的控件,比如发信前、发信后、解码过程中等,可以让你很好的控制发信的整个过程。同样收信控件也具有相应的这些事件。
四、电子邮件程序需要注意的其它问题。
我们从以上的分析可以看出利用sakemail这个优秀的电子邮件引擎,我们也可以写出具有自己特色的电子邮件软件或者让自己的应用程序轻易地具有电子邮件功能。不过如果你像要写一个真的可以用的电子邮件软件,至少还应该具有以下的设计和功能:
1.对于电子邮件的储存和查找功能。不能保存邮件的电子邮件软件是没有实际使用价值的,同样在这个信息爆炸的时代,你的程序必须具有良好的查询功能,让使用者快速地找到需要的信息。
2.多帐户功能。越来越多的免费电子邮件使得支持多帐户功能成为我们选择电子邮件软件的一个基本特性。多帐户功能增加了程序设计的复杂性。
3.完备的邮件过滤功能。随着越来越多的信息通过电子邮件的形式发送过来,如果不能建立起一套完备的过滤功能,那么有些重要的邮件一旦被疏忽,影响可能很大。所以你的电子邮件程序应该具有一点人工智能,能自动过滤、自动挑选甚至自动恢复指定的电子邮件。
4.文件格式的支持。Html格式的电子邮件可以具有更好的表现形式,因此你应该支持Html格式的电子邮件。另外,因为很多的电子邮件附件是zip格式,如果你的电子邮件程序内部直接支持察看zip格式以及释放操作,就更加锦上添花了。
以上简要概括地谈了一些作者自己开发Email程序的看法和经验,希望对于有兴趣于开发电子邮件程序的朋友有所帮助。