C++Builder 4.0在线接收电子邮件

发表于:2007-07-04来源:作者:点击数: 标签:
河南濮阳中原油田计算中心 李 东 我们在使用163、长通飞华等免费电子邮件的时候,会发现这些电子信箱具有在线收发的功能,即可以通过浏览器发送和接收电子邮件。这些功能一般是通过CGI 实现的,而CGI 技术正在逐渐被ISAPI/NSAPI 技术所取代,下面的例子使用C
河南濮阳中原油田计算中心 李 东

  我们在使用163、长通飞华等免费电子邮件的时候,会发现这些电子信箱具有在线收发的功能,即可以通过浏览器发送和接收电子邮件。这些功能一般是通过CGI 实现的,而CGI 技术正在逐渐被ISAPI/NSAPI 技术所取代,下面的例子使用C ++Builder4.0 中的ISAPI/NSAPI 实现了电子邮件的在线接收。使用C ++Builder4 开发Web Server 程序是非常简单的,C ++Builder 4 的VCL 提供了大量的元件和对象,支持Web Server 程序的开发。

  本程序由两个文件构成,分别为:

  index.htm:接收电子邮件的浏览器界面,放到WEB 服务器的缺省目录下(如:C:\.netpub\wwwroot);ReadMail.dll:在浏览器内显示邮件列表以及指定邮件内容的Web Server Application。这个动态链结库文件放在可执行文件路径下(如C:\Inetpub\scripts)。

  用户在浏览器内通过Web Server 浏览index.htm,输入主机名、端口(一般是110)、用户名、口令后,首先会看到用户的邮件列表,单击相应的邮件序号即可查看邮件内容。

  首先建立index.htm,其内容如下:

< html >
< head >
< meta http -equiv="Content -Type"
content="text/html; charset=gb_2312 -80" >
< meta name="GENERATOR" content="Microsoft FrontPage Express 2.0" >
< title > 邮件查看< /title >
< /head >
< body bgcolor=" #FFFFFF" >
< form action=" /scripts/MailList.dll/MailList"
method="POST" >
< p > 主机:< input type="text" size="20" name="Host" >< /p >
< p > 端口:< input type="text" size="20" name="Port" >< /p >
< p > 用户名:< input type="text" size="20" name="Name" >< /p >
< p > 口令:< input type="password" size="20" name="Code" >< /p >
< p >< input type="submit" name="B1" value=" 提交" >< input
  type="reset" name="B2" value=" 复原" >< /p >
< /form >
< /body >
< /html >
  下面编写ReadMail.dll:

  在C ++Builder 中新建一个基于ISAPI 的Web Server Application,手动增加NMPOP31,PageProducer1。在Unit1.h 头文件中定义几个变量:

AnsiString HostName,HostPort,UserName,UserCode;
TStrings *URLData;
 // 接受HTTP 请求传递的参数
bool ConnectFlag;
int EmailOrder;
  增加一个路径为/MailList 的动作项,其代码如下:

void __fastcall TWebModule1::WebModule1
WebActionItem1Action(TObject *Sender,
TWebRequest *Request, TWebResponse
     *Response,bool &Handled)
{
  // 接受HTTP 请求传递的参数,
 从中获取主机、端口、户名和口令
URLData = NULL;
switch(Request ->MethodType)
  {case mtPost:
  URLData = Request ->ContentFields;
  break;
  case mtGet:
  URLData = Request ->QueryFields;
  break;
  }
HostName = URLData ->Values["Host"];
HostPort = URLData ->Values["Port"];
UserName = URLData ->Values["Name"];
UserCode = URLData ->Values["Code"];

  // 下面开始连接邮件服务器
NMPOP31 ->AttachFilePath=".";
// 存储邮件路径为当前路径
NMPOP31 ->DeleteOnRead=false;
// 不删除服务器上的副本
NMPOP31 ->ReportLevel=Status_Basic;
//Status 的详细程度
NMPOP31 ->TimeOut=20000;// 设定超时
NMPOP31 ->Host=HostName;
NMPOP31 ->Port=StrToInt(HostPort);
NMPOP31 ->UserID=UserName;
NMPOP31 ->Password=UserCode;
ConnectFlag=true;
NMPOP31 ->Connect();

// 如果连接成功,
则制作邮件列表的HTML 语句
if(ConnectFlag)
{PageProducer1 ->HTMLDoc ->Clear();
PageProducer1 ->HTMLDoc ->Add
  ("< html >< body > ");
PageProducer1 ->HTMLDoc ->Add
(" 邮件个数" +IntToStr
  (NMPOP31 ->MailCount));
if(NMPOP31 ->MailCount)
for(int i=1;i<=NMPOP31 ->MailCount;i ++)
{PageProducer1 ->HTMLDoc ->Add("< a href='");
PageProducer1 ->HTMLDoc ->Add("ReadMail?Mx=");
PageProducer1 ->HTMLDoc ->Add(IntToStr(i));
PageProducer1 ->HTMLDoc ->Add("'>");
PageProducer1 ->HTMLDoc ->Add(IntToStr(i));
PageProducer1 ->HTMLDoc ->Add("< /a >");}
}
PageProducer1 ->HTMLDoc ->Add("< /body >< /html >");
NMPOP31 ->Disconnect();}
else
{PageProducer1 ->HTMLDoc ->Clear();
PageProducer1 ->HTMLDoc ->Add("< html >
");
PageProducer1 ->HTMLDoc ->Add
  (" 连接服务器失败!");
PageProducer1 ->HTMLDoc ->Add("< /body >
< /html >");}
// 将邮件列表的HTML 语句发送给浏览器
Response ->Content = PageProducer1 ->Content( );
}
// --------------
  以上部分程序完成了显示邮件服务器邮件列表的功能。接下来,再增加一个路径为/MailList 的动作项,它的功能是显示指定的邮件内容。

void __fastcall TWebModule1::WebModule1
WebActionItem2Action(TObject *Sender,
TWebRequest *Request, TWebResponse
  *Response,bool &Handled)
{
// 接受HTTP 请求传递的参数,
从中获取用户名和口令、
欲查看的邮件序号

URLData = NULL;
switch(Request ->MethodType)
  {case mtPost:
  URLData = Request ->ContentFields;
  break;
  case mtGet:
  URLData = Request ->QueryFields;
  break;}
EmailOrder = StrToInt(URLData ->Values["Mx"]);

  // 下面开始连接邮件服务器
NMPOP31 ->AttachFilePath=".";
  // 存储邮件路径为当前路径
NMPOP31 ->DeleteOnRead=false;
  // 不删除服务器上的副本
NMPOP31 ->ReportLevel=Status_Basic;
  //Status 的详细程度
NMPOP31 ->TimeOut=20000; // 设定超时
NMPOP31 ->Host=HostName;
NMPOP31 ->Port=StrToInt(HostPort);
NMPOP31 ->UserID=UserName;
NMPOP31 ->Password=UserCode;
ConnectFlag=true;
NMPOP31 ->Connect();

 // 如果连接成功,打开指定的邮件
if(ConnectFlag)
{PageProducer1 ->HTMLDoc ->Clear();
PageProducer1 ->HTMLDoc ->Add
  ("< html >< body >");
PageProducer1 ->HTMLDoc ->Add
(" 第" +IntToStr(EmailOrder) +
  " 个邮件内容:");
NMPOP31 ->GetMailMessage(EmailOrder);
PageProducer1 ->HTMLDoc ->AddStrings
(NMPOP31 ->MailMessage ->Head);
PageProducer1 ->HTMLDoc ->AddStrings
 (NMPOP31 ->MailMessage ->Body);
PageProducer1 ->HTMLDoc ->Add("< /body >
< /html >");
NMPOP31 ->Disconnect(); }
else
{PageProducer1 ->HTMLDoc ->Clear();
PageProducer1 ->HTMLDoc ->Add
("< html >< body >");
PageProducer1 ->HTMLDoc ->Add
(" 连接服务器失败!");
PageProducer1 ->HTMLDoc ->Add
("< /body >< /html >");}
// 将显示指定邮件内容的
HTML 语句发送给浏览器
Response ->Content = PageProducer1 ->
  Content( );
}
// -------------
最后在NMPOP31 的ConnectionFailed
 事件中加入:
void __fastcall TWebModule1::NMPOP31
ConnectionFailed(TObject *Sender)
{
ConnectFlag=false;    
}
// -------------
  编译完成后,将生成的DLL 文件更名为和HTML 文件相对应的名称(如:ReadMail.dll),放在C:\Inetpub\scripts 即可。以上程序在Pwin98 +PWS4 上通过。

  此外,本程序还有不足之处,比如只能查看内容为纯文本格式的邮件,没有处理异常的能力。读者感兴趣的话,不妨改进。 

原文转自:http://www.ltesting.net