在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參數設置窗體上放置五個TEdit控件,一個TComboBox控件(其Items屬性值依次爲None,Simple Login,表示發送郵件時是否使用身份驗證)和一個TBitBtn控件。

SMTP參數設置窗體界面如圖二所示 (箭頭所指向的文字標識了該控件的名字)。窗體的Name屬性值設爲fmSMTPOption。


四、    程序設計與系統實現

1. 郵件發送窗體的單元代碼如下(單元定義部分略):


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', '[email protected]');

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中調試通過。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章