• 在Delphi中使用Indy控件实现邮件群发


    摘要:本文通过对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控件用来构建要发送的邮件信息。它通过以下几个主要属性及子属性构建发送的邮件信息:

    l         Subject:             邮件主题;

    l         Body:                邮件正文;

    l         From.Text:         发件人邮件地址;

    l         Priority:             邮件优先级

    l         Recipients.EmailAddresses:       目的地址;

    l         CCList.EmailAddresses:            抄送地址;

    l         BccList.EmailAddresses:           暗送地址;

    l         ReceiptRecipient.Text:              收条地址;

    l         MessageParts:                         附件信息。

    2. TIdSMTP

    l         Username:                 帐户名;

    l         Password:                 密码;

    l         Host:                        SMTP服务器地址;

    l         Port:                         端口号;

    l         AuthenticationType:   身份验证方式;

    l         Connect方法:           连接SMTP服务器;

    l         Send方法:                发送创建的邮件;

    l         Disconnect方法:       断开服务器连接。

    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<>nil THEN StatusBar1.SimpleText:=AStatusText;

    end;

    // 删除选定附件

    procedure TFormMail.btnDelAttachmentClick(Sender: TObject);

    begin

    if lvFiles.ItemIndex>=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中调试通过

  • 相关阅读:
    【转】深入理解CSS定位中的偏移
    【转】css清除浮动float的三种方法总结,为什么清浮动?浮动会有那些影响?
    执行sql时出现错误 extraneous input ';' expecting EOF near '<EOF>'
    jquery操作select(增加,删除,清空)
    mybatis 错误CGLIB is not available
    spring事务不会进行回滚的情况
    Hive 存储类型 StoreType
    Sublimetext3安装Emmet插件步骤
    spring-mvc List及数组的配置接收
    solr 学习片段
  • 原文地址:https://www.cnblogs.com/baikingco/p/1547985.html
Copyright © 2020-2023  润新知