⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 delphi让你发送flash电子邮件.txt

📁 大量Delphi开发资料
💻 TXT
📖 第 1 页 / 共 2 页
字号:
Delphi让你发送Flash电子邮件  
责任编辑:admin [常熟青年 CSYOUTH ]  添加时间:2004-3-10  人气:319 作者:
    无论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 

...... 
procedure TForm1.btnOpenClick(Sender: TObject); 
begin 
{打开对话框,选择SWF文件} 
if OpenDialog1.Execute then 

procedure TForm1.NMSMTP1SendStart(Sender: TObject); 
begin 
{在邮件发送开始时修改邮件的消息头,标明邮件为多部分组成} 
NMSMTP1.FinalHeader.Values['Content-Type'] := 'multipart/related; boundary="------------SwfEmail by JDH"'; 
end; 

procedure TForm1.chkSmtpVerifyClick(Sender: TObject); 
begin 
{根据是否需要SMTP服务器认证,改变用户名、密码状态} 
if chkSmtpVerify.Checked = True then 

...... 


三、程序运行 

  首先在Delphi 5中编译运行,接着在对话框中输入收信人、发信人、主题、正文内容以及SMTP服务器,比如填写“smtp.263.net”,端口号使用默认的25,选中“SMTP服务器需要认证”,并根据发信人输入用户名、密码。单击“打开文件”按钮,选择要发送的Flash动画文件,确认无误后,单击“发送”按钮即可。发送成功后,会出现发信成功 

{******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: TEdit; 
chkSmtpVerify: TCheckBox; 
btnSend: TButton; 
btnOpen: TButton; 
txtSwfFile: TEdit; 
Label7: TLabel; 
OpenDialog1: TOpenDialog; 
Label8: TLabel; 
txtSmtpServer: TEdit; 
NMSMTP1: TNMSMTP; 
Label9: TLabel; 
txtPort: TEdit; 
procedure btnOpenClick(Sender: TObject); 
procedure btnSendClick(Sender: TObject); 
procedure NMSMTP1SendStart(Sender: TObject); 
procedure NMSMTP1Connect(Sender: TObject); 
procedure chkSmtpVerifyClick(Sender: TObject); 
private 
{ Private declarations } 
public 
{ Public declarations } 
end; 

var 
Form1: TForm1; 
function EncodeString(Decoded:string):String; 
function EncodeBASE64(Encoded: TMemoryStream {TMailText}; Decoded: TMemoryStream): Integer; //编码函数 
implementation 
{$R *.dfm} 
{对参数TMemoryStrema中的字节流进行Base64编码,编码后的结果 
保存在Encoded中,函数返回编码长度} 
function EncodeBASE64(Encoded: TMemoryStream ; Decoded: TMemoryStream): Integer; 
const 
_Code64: String[64] = 
('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'); 
var 
I: LongInt; 
B: array[0..2279] of Byte; 
J, K, L, M, Quads: Integer; 
Stream: string[76]; 
EncLine: String; 
begin 
Encoded.Clear; 
Stream := ''; 
Quads := 0; 
{为提高效率,每2280字节流为一组进行编码} 
J := Decoded.Size div 2280; 
Decoded.Position := 0; 
{对前J*2280个字节流进行编码} 
for I := 1 to J do 
begin 
Decoded.Read(B, 2280); 
for M := 0 to 39 do 
begin 
for K := 0 to 18 do 
begin 
L:= 57*M + 3*K; 
Stream[Quads+1] := _Code64[(B[L] div 4)+1]; 
Stream[Quads+2] := _Code64[(B[L] mod 4)*16 + (B[L+1] div 16)+1]; 
Stream[Quads+3] := _Code64[(B[L+1] mod 16)*4 + (B[L+2] div 64)+1]; 
Stream[Quads+4] := _Code64[B[L+2] mod 64+1]; 
Inc(Quads, 4); 
if Quads = 76 then 
begin 
Stream[0] := #76; 
EncLine := Stream+#13#10; 
Encoded.Write(EncLine[1], Length(EncLine)); 
Quads := 0; 
end; 
end; 
end; 
end; 

{对以2280为模的余数字节流进行编码} 
J := (Decoded.Size mod 2280) div 3; 
for I := 1 to J do 
begin 
Decoded.Read(B, 3); 
Stream[Quads+1] := _Code64[(B[0] div 4)+1]; 
Stream[Quads+2] := _Code64[(B[0] mod 4)*16 + (B[1] div 16)+1]; 
Stream[Quads+3] := _Code64[(B[1] mod 16)*4 + (B[2] div 64)+1]; 
Stream[Quads+4] := _Code64[B[2] mod 64+1]; 
Inc(Quads, 4); 
{每行76个字符} 
if Quads = 76 then 
begin 
Stream[0] := #76; 
EncLine := Stream+#13#10; 
Encoded.Write(EncLine[1], Length(EncLine)); 
Quads := 0; 
end; 
end; 
{“=”补位} 
if (Decoded.Size mod 3) = 2 then 
begin 
Decoded.Read(B, 2); 
Stream[Quads+1] := _Code64[(B[0] div 4)+1]; 
Stream[Quads+2] := _Code64[(B[0] mod 4)*16 + (B[1] div 16)+1]; 
Stream[Quads+3] := _Code64[(B[1] mod 16)*4 + 1]; 
Stream[Quads+4] := '='; 
Inc(Quads, 4); 
end; 

if (Decoded.Size mod 3) = 1 then 
begin 
Decoded.Read(B, 1); 
Stream[Quads+1] := _Code64[(B[0] div 4)+1]; 
Stream[Quads+2] := _Code64[(B[0] mod 4)*16 + 1]; 
Stream[Quads+3] := '='; 
Stream[Quads+4] := '='; 
Inc(Quads, 4); 
end; 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -