無論Outlook XP還是最新的Foxmail 4.0,都只能在Html格式的電子郵件中嵌入JPG、GIF格式圖片,而音色俱佳的Flash動畫卻只能作為電子郵件附件發送給好友,你可曾感到遺憾?
經過一番實驗探索,我使用Delphi終於實現了將Flash動畫(.SWF格式)嵌入到電子郵件正文中發送的功能,Foxmail、Outlook均可以按照Html格式的郵件查看,而且263、163等免費電子郵件還支持Web界面直接浏覽。可惜的是,Sina、Sohu免費電子郵件的Web界面則不支持,只能將Flash動畫作為附件提供。
一、程序原理 下面對本程序相關的重要理論知識做些解釋,幫助大家理解本程序的原理。更多的內容,限於文章篇幅,請參見相關的參考書、幫助文件。
1.TNMSMTP控件
電子郵件發送過程都必須遵循SMTP協議。客戶端和服務器通過該協議進行通信,由客戶端發送出電子郵件,SMTP服務器通過網絡上其他SMTP服務器,最終將郵件傳遞到收信人的郵件服務器。本程序作為電子郵件客戶端程序,最基本的功能是要實現電子郵件發送,為了簡化編程,使用了Delphi 5自帶的TNMSMTP控件,該控件封裝了對SMTP編程。由於該控件繼承自TPowersock,因而必要時可以直接調用底層的Socket過程,又不失靈活性。
例如,雖然TNMSMTP不直接支持“SMTP服務器認證功能”(請參考《電腦愛好者》2001年16期《制作支持“服務器認證”的VB電子郵件程序》,包括下文“BASE64編碼”),但是,可以利用TNMSMTP的Connect事件和繼承自TPowersock的Transaction方法,實現SMTP服務器認證。其原理在於,Connect事件發生在TNMSMTP與服務器連接成功之時,此時,使用Transaction方法發出SMTP服務器認證所規定的“AUTH LOGIN”命令,並輸入經過BASE64編碼後的用戶名和密碼,可以實現認證。因此,本程序實現了SMTP服務器認證。
另外,TNMSMTP的SendStart事件在郵件發送開始時觸發,在該事件中,可以通過修改TNMSMTP的FinalHeader屬性值,實現修改電子郵件的郵件頭信息。在本程序中需要修改郵件頭的Content-Type屬性,使接收嵌入Flash動畫電子郵件的客戶端軟件(如Foxmail)能正確處理郵件內容。
2.MIME協議
目前,幾乎所有的郵件服務器和客戶端軟件都支持“多用途Internet郵件擴展”協議Multipurpose Internet Mail Extensions (MIME)。該協議的最新版由RFC2045(Internet消息體格式)、RFC2046(媒體類型)、RFC2047(無ASCII文本消息頭擴展)、RFC2048(注冊過程)、RFC2049(一致性標准和例子)等共同規定。該協議遵循了RFC822中規定的電子郵件內容只能包括簡單的ASCII文本字符(如字母、數字、標點符號等),定義了在電子郵件中包括經過編碼的二進制文件的方法,編碼後的內容將只包括文本字符。目前,實現對二進制文件編碼的規范有很多,BASE64編碼規范也是其中之一。本程序使用TMemoryStream對象,實現了通用的BASE64編碼函數EncodeBASE64,能夠對SWF文件進行編碼。
通過MIME協議,電子郵件中不但可以添加附件,還可以添加HTML格式內容,包括圖片、聲音、動畫等。Outlook、Foxmail 4.0等軟件都可以編輯HTML格式的郵件,但是並不支持直接嵌入Flash動畫。事實上,正確利用MIME協議,可以在HTML格式的郵件中嵌入Flash動畫,並在郵件正文中顯示出來,其原理和在HTML格式郵件中顯示圖片、播放聲音是一樣的。在Html格式郵件中嵌入Flash動畫與向網頁中添加動畫所需要的代碼是一樣的,同樣使用< OBJECT >、< EMBED >標記,感興趣的朋友可以查看一個包含Flash動畫的網頁源代碼,對比本程序。
在本程序中,設置郵件MIME消息頭的Content-Type屬性為multipart/related; boundary="---SwfEmail by JDH",表示該郵件包括多個不同數據類型的部分,各個部分之間用"---SwfEmail by JDH"(不包括引號)區分。在郵件內容的這些部分中,根據每部分的內容不同,再為其添加相應的MIME消息頭,具體可參見程序源代碼。
二、編程實戰
啟動Delphi 5,參考圖1在Form1上創建各種控件。圖中黑色方框內標明了控件名稱,其中txt前綴表示TEdit控件,mem前綴表示TMemo控件,chk前綴表示TCheckbox控件,btn前綴表示TButton控件,NMSMTP1是TNMSMTP控件,OpenDialog1是TOpenDialog控件。圖2列出了一部分控件的某些關鍵屬性。
現在添加代碼如下:
{******Unit1.pas源代碼內容如下******}
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, Psock, NMsmtp;
type
TForm1 = class(TForm)
Label1: TLabel;
txtTo: TEdit;
Label2: TLabel;
txtFrom: TEdit;
Label3: TLabel;
txtSubject: TEdit;
Label4: TLabel;
memContents: TMemo;
Label5: TLabel;
txtUserName: TEdit;
Label6: TLabel;
txtPassWord: TEd