最近开发的一款应用程序中,有一个功能是要求程序能启动邮件发送程序,并在邮件正文部分自动填入一些图片和文字。这方面我以前没有做过,查了一些资料最后实现了这个功能。现在我把程序控制外部邮件发送程序的常用方法总结如下:
一、使用mailto协议
优点:使用简单,能自动运行系统默认的邮件程序。
缺点:功能简单,不能添加附件,也不能在邮件正文部分添加图片,多用于web页面中。
例子:
CString strEmailBody;
//添加收件邮箱地址
strEmailBody = "mailto:aaaa@hotmail.com;bbbbb@hotmail.com";
//添加抄送邮箱地址
strEmailBody += "&cc=ccccc@hotmail.com";
//添加密送邮箱地址
strEmailBody += "&bcc=yyyyyy@hotmail.com";
//添加邮件主题
strEmailBody += "&subject=Test";
//添加邮件正文
strEmailBody += "&body=This is the EMail body!";
//启动邮件发送程序
::ShellExecute(m_hWnd, "Open", strEmailBody, NULL, NULL, SW_SHOW);
二、使用MAPI
优点:可以发送附件文件,能自动运行系统默认的邮件程序。
缺点:不能在邮件正文部分添加图片。
例子:
//需要包含的头文件
#include "mapi.h"
HMODULE hMapiDll = NULL;
LPMAPISENDMAIL pSendMailFunc = NULL;
//加载 MAPI dll
hMapiDll = LoadLibrary("MAPI32.DLL");
if(hMapiDll == NULL)
{
MessageBox("Load MAPI dll failure!");
return;
}
//获取函数地址
pSendMailFunc = (LPMAPISENDMAIL)GetProcAddress(hMapiDll, "MAPISendMail");
if(pSendMailFunc == NULL)
{
MessageBox("Get the function address failure!");
return;
}
//指定附件文件
MapiFileDesc fileDesc;
memset(&fileDesc, 0, sizeof(fileDesc));
fileDesc.nPosition = (ULONG)-1;
fileDesc.lpszPathName = "C:/test.jpg";
fileDesc.lpszFileName = "test.jpg";
//设置邮件消息结构体
MapiMessage message;
memset(&message, 0, sizeof(message));
//附件
message.nFileCount = 1;
message.lpFiles = &fileDesc;
//邮件主题
message.lpszSubject = "Test";
//邮件正文
message.lpszNoteText = "This is the EMail body!";
//发送
int nError = pSendMailFunc(0, 0, &message, MAPI_LOGON_UI|MAPI_DIALOG, 0);
if((nError != SUCCESS_SUCCESS) && (nError != MAPI_USER_ABORT) && (nError != MAPI_E_LOGIN_FAILURE))
{
MessageBox("The EMail send failure!");
}
三、使用OLE
优点:功能强大,可添加附件,也可把图片添加到正文部分。
缺点:只能针对Outlook
例子:
//要引用的库,Outlook版本不同,该路径也不同
//---------------------------------------------------------------
#import "c://Program Files//Common Files//Microsoft Shared//Office10//mso.dll" named_guids
#import "C://Program Files//Microsoft Office//Office10//MSOUTL.OLB" rename_namespace("Outlook") no_dual_interfaces rename("CopyFile","_CopyFile") //exclude("_IRecipientControl", "_DRecipientControl")
//---------------------------------------------------------------
using namespace Outlook;
//---------------------------------------------------------------
if(CoInitialize(NULL) != S_OK)
return;
_ApplicationPtr pOutlookApplication = NULL;
_MailItemPtr pOutlookMailItem = NULL;
AttachmentsPtr pOulookAttachments = NULL;
AttachmentPtr pOulookAttachment = NULL;
//创建Outlook应用实例
HRESULT hRes = pOutlookApplication.CreateInstance("Outlook.Application");
if(hRes != S_OK)
return;
//获取邮件
pOutlookMailItem = pOutlookApplication->CreateItem(olMailItem);
if(pOutlookMailItem == NULL)
return;
_NameSpacePtr pNameSpace = NULL;
pNameSpace = pOutlookApplication->GetNamespace(L"MAPI");
if(pNameSpace == NULL)
return;
_variant_t covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
pNameSpace->Logon(covOptional, covOptional, covOptional, covOptional);
pOulookAttachments = pOutlookMailItem->GetAttachments();
if(pOulookAttachments == NULL)
return;
//添加附件
pOulookAttachments->Add("C:/1.jpg");
pOulookAttachments->Add("C:/test.jpg");
//指定邮件正文,如果不需要显示图片,可以使用PutBody
pOutlookMailItem->PutHTMLBody(L"<html><body><img src='cid:1.jpg' height=200 width=200><BR>This is the EMail body!</body></html>");
pOutlookMailItem->Display();
由于我需要把图片插入到邮件正文,所以我选择了第三种方法。在正文部分显示图片,需要先把图片作为附件添加到邮件中,然后在PutHTMLBody函数中指定图片文件名。
以上例子均在Windows XP + Office 2000 + VC6调试通过。