在VFP中利用API实现批量邮件发送

用电子邮件与朋友、客户或亲友联系已经成为非常流行的方式。在管理系统中实现电子邮件功能显然是很适合用户和市场发展需求的明智之举。当然实现发送电子邮件功能并不困难,实现批量邮件发送功能才是有更大的实用意义的举措。我们在开发《实验室管理系统labman2001》(下载主页:http://labman.yeah.net)的时候,充分考虑了这样的需求,完整地实现了批量邮件发送功能。当然,实现这样的功能需要用到Windows的API函数,可能许多的用户觉得API非常的神秘,不敢轻易去尝试。事实上,API功能非常强大,许多功能的实现非此不可。其实掌握一定的规律,API就不那么困难了。下面简要说明如何实现。
   批量邮件发送表单(如(图1))包含四个命令按钮(“选择包含邮件表”、“确认邮件列表”、“转到邮件处理器”、“退出”),两个标签,一个下拉组合框,一个编辑框,一个文本框(与下拉组合框重合)。处理的流程是这样的:程序先检测是否有打开的表,如果有,就不提示,没有就提示目前没有打开的表,可以单击“选择包含邮件表”,选择一个数据表打开。以后就可以从下拉组合框中选择包含邮件地址的字段,然后单击“确认邮件列表”,筛选符合条件的邮件地址,这些邮件地址会出现在编辑框里面。如果想删除或添加邮件地址,就可以在编辑框中进行。接下来单击“转到邮件处理器”,则这些电子邮件地址会被系统默认的邮件接受和发送程序如Foxmail、Outlook等程序接受作为“收件人”,并且出现邮件编辑窗口,在编辑窗口就可以方便地写信啦!下面依次说明核心代码。

图1
图1

   “选择包含邮件表”的鼠标单击事件代码:
   m.cfilename2 = getfile(“dbf”) &&显示文件打开选择窗口,选择一个dbf文件
   if file(m.cfilename2)= .t.
   use &cfilename2 exclusive &&以独占方式打开表
   else
   return
   endif
   thisform.cbomailziduan.RowSourceType = 8 &&确定数据源类型为表结构
   thisform.cbomailziduan. RowSource = cfilename2 &&确定数据源名称
   下拉组合框cbomailziduan的鼠标单击事件代码:
   thisform.txtmailziduan.value = thisform.cbomailziduan.value
   “确认邮件列表” 的鼠标单击事件代码:
   if dbf(1)==''
   if messagebox(“没有打开的表,请选择包含邮件表重试!”,64,“邮件处理”)=1
   return
   endif
   endif
   do form frm查找 &&利用vfp本身提供的一个查找类构造一个查找表单。符合条件的记录将被下面的程序利用。
   browse nomenu noedit nodelete &&显示符合条件的记录
   m.lcemail=upper(alltrim(thisform.txtmailziduan.value))&&获取电子邮件字段名称
   m.lmailok = .f.
   &&检查字段是否存在。
   for i =1 to fcount
   if m.lcemail <> field(i)
   else
   m.lmailok = .t.
   exit
   endif
   endfor
   if m.lmailok == .f.
   if messagebox(“表中不存在该字段,请修改字段名重试!”,64,“邮件处理”)=1
   return
   endif
   endif
   &&在下面的程序段中,将把符合条件的数据输出到一个文本文件。再把文本内容读入edtmaillist编辑框供编辑修改。
   if file(“maillist.txt”)= .t.
   delete file maillist.txt &&如果临时文件已经存在,则先删除。
   endif
   COPY TO maillist FIELDS &lcemail TYPE DELIMITED WITH blank
   Handlemail = fopen(“maillist.txt”)
   m.cmail=''
   &&读取邮件地址的程序段。
   do while .not. feof(handlemail)
   m.cmail = alltrim(fgets(handlemail))+','+m.cmail
   enddo
   thisform.edtmaillist.value = m.cmail
   fclose(handlemail)
   if file(“maillist.txt”)= .t.
   delete file maillist.txt
   endif
   return
   “转到邮件处理器” 的鼠标单击事件代码:
   xgjfileopen(“mailto:” + thisform.edtmaillist.value)
   return
   表单的activate事件代码:
   SET PROCEDURE TO XGJUDF
   if dbf(1)==''
   if messagebox(“没有打开的表,请选择包含邮件表重试!”,64,“邮件处理”)=1
   return
   endif
   endif
   thisform.cbomailziduan.RowSourceType = 8 &&指定下拉组合框的数据源类型。
   thisform.cbomailziduan.RowSource = alias(1) &&指定下拉组合框的数据源。
   xgjudf中的xgjfileopen()函数
   ********
   函数说明:利用API中的ShellExecute函数,调用相应程序处理文件的打开,如.doc文件用Word打开,发邮件使用默认的邮件处理器。
   参数m.cxgjfilename代表文件的名字,如发邮件写m.cxgjfilename=“mailto:labman2001@sina.com”,打开rtf文件可写 m.cxgjfilename=“C:\Documents and Settings\xgj\My Documents\客户.rtf”
   ********
   function xgjfileopen()
   parameter m.cxgjfilename
   && 声明ShellExecute函数
   DECLARE INTEGER ShellExecute IN shell32.DLL INTEGER HWND,;
   STRING lpszOP,;

STRING lpszFile,;,

STRING lpszParams,;,

STRING lpszDir,;

INTEGER fsshowcmd
   && 声明GetDesktopWindow函数,该函数激活Windows桌面
   DECLARE INTEGER GetDesktopWindow IN win32api
   && 指定从Windows桌面上运行ShellExecute函数
   HWND = GetDesktopWindow
   lpszOP = “”
   && 指定ShellExecute操作的文件为mailto:labman2001@sina.com
   lpszFile = alltrim(m.cxgjfilename)
   lpszParams = “”
   &&指定ShellExecute的缺省目录为C:\
   lpszDir = “C:\”
   fsshowcmd = 1
   && 执行ShellExecute命令
   LNRETURN=ShellExecute(HWND,lpszOP,lpszFile,lpszParams,lpszDir,fsshowcmd) return