======================================================
注:本文源代码点此下载
======================================================
摘要:本文通过对indy控件集中tidmessage、tidsmtp控件的属性、方法分析,介绍了一种使你的计算机具有邮件群发功能的方法,使你与大量朋友之间的沟通更为方便。可以不加修改地应用于delphi应用程序中,具有很强的实用性。
关键字:delphi,indy控件集,邮件群发
随着人们交往的不断扩大,人与人、单位与单位之间的邮件通讯日益普及,通过邮件群发,可以将会议通知、产品说明、产品报价等通过邮件方式把大量邮件送到用户的邮箱中,既加快了信息的传递,又节省了费用。目前网上有许多邮件群发是基于delphi 5中的tnmsmtp控件的,很多的smtp邮件服务器要对发送邮件的用户进行身份验证,即要求给出用户名和密码信息,否则无法发送,包括163.net,263.net,sina.com,sohu.com等均在此列,而delphi 5的tnmsmtp构件本身未提供身份验证方面的属性,如此就不能在这些邮件服务器上通过tnmsmtp控件发送邮件,因此delphi的高版本中去掉了这组控件,取而代之的是indy控件集。本文介绍在delphi 7中使用indy控件集实现邮件群发的功能。
一、实现原理
indy的全名是internet direct(也叫winshoes),它是一套开放源代码的internet控件集,它支持大部分流行的internet协议,包括tcp、udp、dns、icmp、finger、ftp、gopher、http、pop3、smtp、telnet、whois等,支持base64、md2、md4、md5等编解码,提供internet流行协议的客户端和服务器控件。indy控件集的客户端和服务器控件都有完整、详细的源代码例程和帮助文件,用户可以根据这些例子,简单方便快速的创建各种服务器程序,如:web服务器、telnet服务器、irc服务器、tcp、udp服务器等,而这些服务器都是支持多线程的。用户也可以很方便地编写出各种客户端程序,如email、finger、ftp、ping、telnet等。
如果你使用的是delphi 6以前的版本,请先到indy主页http://www.nevrona.com/indy/download.html下载并安装该控件集。
二、用到的核心控件
indy控件集包含了大量internet控件,为了实现邮件群发功能,使用了以下三个控件:
1. tidmessage
tidmessage控件用来构建要发送的邮件信息。它通过以下几个主要属性及子属性构建发送的邮件信息:
lsubject:邮件主题;
lbody:邮件正文;
lfrom.text:发件人邮件地址;
lpriority:邮件优先级
lrecipients.emailaddresses:目的地址;
lcclist.emailaddresses:抄送地址;
lbcclist.emailaddresses:暗送地址;
lreceiptrecipient.text:收条地址;
lmessageparts:附件信息。
2. tidsmtp
lusername:帐户名;
lpassword:密码;
lhost:smtp服务器地址;
lport:端口号;
lauthenticationtype:身份验证方式;
lconnect方法:连接smtp服务器;
lsend方法:发送创建的邮件;
ldisconnect方法:断开服务器连接。
3. tidantifreeze
由于indy是以同步的方式进行工作的,在读或写操作完成之前,其它代码无法执行,加入tidantifreeze可以在每隔一段时间通过呼叫application.processmessage方法响应来自外界的消息,因此tidantifreeze可以确保indy控件在工作时程序能响应来自外界的消息。
三、界面设计
邮件群发需要使用二个窗体:一个是邮件发送窗体,另一个是smtp参数设置窗体。在邮件发送窗体上放置一个tedit控件,二个tmemo控件,一个tcombobox控件(其items属性值依次为highest,high,normal,low,lowest),一个tcheckbox控件和五个tbitbtn控件,用到的indy控件为tidsmtp、tidmessage和tidantifreeze。其中tidmessage用来创建要发送的邮件信息,tidsmtp用来发送邮件。
邮件发送窗体界面如图一所示 (箭头所指向的文字标识了该控件的名字)。窗体的name属性值设为formmail。
图一:smtp参数设置窗体
smtp参数设置窗体用来设置邮件发送服务器的参数。在smtp参数设置窗体上放置五个tedit控件,一个tcombobox控件(其items属性值依次为none,simple login,表示发送邮件时是否使用身份验证)和一个tbitbtn控件。
smtp参数设置窗体界面如图二所示 (箭头所指向的文字标识了该控件的名字)。窗体的name属性值设为fmsmtpoption。
四、程序设计与系统实现
1. 邮件发送窗体的单元代码如下(单元定义部分略):
图二:smtp参数设置窗体
uses unitsmtpoption;// 引用smtp参数设置单元
// 添加附件
procedure tformmail.btnattachmentclick(sender: tobject);
begin
if opendialog1.execute then begin // 增添一个附件
tidattachment.create(idmsgsend.messageparts, opendialog1.filename);
resetattachmentlistview; // 邮件列表显示
end;
end;
// 邮件列表显示
procedure tformmail.resetattachmentlistview;
var li: tlistitem;
idx: integer;
begin
lvfiles.items.clear;
for idx := 0 to pred(idmsgsend.messageparts.count) do begin
li := lvfiles.items.add; // 添加一行
if idmsgsend.messageparts.items[idx] is tidattachment then begin
li.imageindex := 0;
li.caption := tidattachment(idmsgsend.messageparts.items[idx]).filename;
li.subitems.add(tidattachment(idmsgsend.messageparts.items[idx]).contenttype);
end
end;
end;
// 发送邮件:
procedure tformmail.bbtnokclick(sender: tobject);
var
i:integer;
mailaddresses: string;
begin
// 根据用户所填写的内容创建邮件
for i:= 0 to pred(memomaillist.lines.count) do begin
mailaddresses := memomaillist.lines[i];
with idmsgsend do begin
subject := edtsubject.text; //邮件主题
body.assign(memo1.lines); //邮件正文
from.text := fmsmtpoption.edtemail.text; //发件人地址
replyto.emailaddresses := from.text; //回复地址
priority := tidmessagepriority(cbopriority.itemindex); // 邮件优先级
recipients.emailaddresses := mailaddresses; //目的地址
//cclist.emailaddresses := edtcc.text; {cc}
//bcclist.emailaddresses := edtbcc.text; {bbc}
if chkreturnreceipt.checked then // 返回收条
receiptrecipient.text := from.text
else // 不返回收条
receiptrecipient.text := '';
end;
if smtp.connected then
smtp.disconnect; //断开服务器连接
// 身份验证
case fmsmtpoption.cboauthtype.itemindex of
0: smtp.authenticationtype := atnone;
1: smtp.authenticationtype := atlogin;// 需要身份验证
end;
smtp.username := fmsmtpoption.edtaccount.text; // 帐户名
smtp.password := fmsmtpoption.edtpassword.text; // 密码
smtp.host := fmsmtpoption.smtpserver.text;// smtp地址
smtp.port := strtointdef(fmsmtpoption.smtpport.text, 25); //端口(默认25)
try// 发送邮件
smtp.connect; //连接服务器
try
smtp.send(idmsgsend); // 发送创建的邮件
statusbar1.simpletext:='成功发送邮件:'+mailaddresses;
except
statusbar1.simpletext:='不能发送邮件:'+mailaddresses+',请检查网络或参数配置的设置!';
end;
finally
smtp.disconnect; //断开服务器连接
end;
end;
showmessage('发送邮件完毕!');
end;
// 设置属性按钮:
procedure tformmail.bitbtn1click(sender: tobject);
begin
fmsmtpoption.showmodal;
end;
procedure tformmail.bbtncancelclick(sender: tobject);
begin
close;
end;
procedure tformmail.smtpconnected(sender: tobject);
begin
statusbar1.simpletext:='已经连接到网上';
end;
// smtp控件的onstatus事件:
procedure tformmail.smtpstatus(asender: tobject; const astatus: tidstatus;
const astatustext: string);
begin
if statusbar1=0 then // 删除选定的附件
idmsgsend.messageparts.delete(lvfiles.itemindex);
resetattachmentlistview;
end;
2. smtp参数设置窗体的单元代码如下(单元定义部分略):
uses inifiles;// 引用.ini文件处理单元
procedure tfmsmtpoption.formcreate(sender: tobject);
var
mailini: tinifile;
begin
mailini := tinifile.create(extractfilepath(paramstr(0)) + 'mail.ini');
with mailini do begin // 从配置文件中取出参数
smtpserver.text := readstring('smtp', 'servername', 'smtp.server.com');
smtpport.text := readstring('smtp', 'serverport', '25');
edtaccount.text := readstring('smtp', 'serveruser', 'your_login');
edtpassword.text := readstring('smtp', 'serverpassword', 'your_password');
cboauthtype.itemindex := readinteger('smtp', 'smtpauthenticationtype', 0);
edtemail.text := readstring('email', 'personalemail', 'axmanj@21cn.com');
end;
mailini.free;
end;
// 确定按钮
procedure tfmsmtpoption.bitbtnokclick(sender: tobject);
var
mailini: tinifile;
begin
mailini := tinifile.create(extractfilepath(paramstr(0)) + 'mail.ini');
with mailini do begin // 参数存入配置文件
writestring('smtp', 'servername', smtpserver.text);
writestring('smtp', 'serverport', smtpport.text);
writestring('smtp', 'serveruser', edtaccount.text);
writestring('smtp', 'serverpassword', edtpassword.text);
writestring('email', 'personalemail', edtemail.text);
writeinteger('smtp', 'smtpauthenticationtype', cboauthtype.itemindex);
end;
mailini.free;
end;
五、结束语
发送邮件前,先在smtp参数设置窗体上输入smtp服务器的参数设置,并按“确定”按钮保存smtp服务器的参数信息,以便为以后的邮件发送服务。然后在memomaillist对象中输入需群发邮件的地址,格式为每行一个邮件地址,发送邮件时,程序到该列表中依次取出每个邮件地址,并将用户输入的信息作为邮件信息,发送到各个客户的邮箱中。
由于篇幅有限,本程序中没有对邮件地址的格式进行检测,实际使用时,用户最好加上邮件地址格式的检测功能,以免程序运行出错。该程序在windows 2000server中调试通过
======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/