在软件开发过程中,经常会遇到需要集成邮件支持的应用场景。记得有一次,需要开发一个应用程序,它能够在特定时间向特定人群发送带有自定义消息的邮件。为此,开发了一个使用MAPI(Messaging Application Programming Interface,消息应用程序编程接口)的COM服务。MAPI是标准的消息架构,提供了一套完整的函数和面向对象的接口。这里有一个电子邮件组件,一个COM DLL,它是一组消息函数,可以帮助创建具有消息功能的应用程序。这个COM组件使用简单的MAPI来实现这一点。
MAPI被各种行业标准的电子邮件客户端使用,比如Microsoft Exchange客户端、所有版本的Microsoft Outlook和Outlook Express,包括QUALCOMM Incorporated(Eudora)和Netscape Communications Corporation。因此,也可以将这个组件与这些客户端应用程序一起使用。
电子邮件组件的CLSID是CLSID_Mail,它只有一个接口IMail,接口ID是IID_IMail。CMail是实现类,包含以下数据成员:
m_MAPILogon Function pointer for MAPILogon
m_MAPISendMail Function pointer for MAPISendMail
m_MAPISendDocuments Function pointer for MAPISendDocuments
m_MAPIFindNext Function pointer for MAPIFindNext
m_MAPIReadMail Function pointer for MAPIReadMail
m_MAPIResolveName Function pointer for MAPIResolveName
m_MAPIAddress Function pointer for MAPIAddress
m_MAPILogoff Function pointer for MAPILogoff
m_MAPIFreeBuffer Function pointer for MAPIFreeBuffer
m_MAPIDetails Function pointer for MAPIDetails
m_MAPISaveMail Function pointer for MAPISaveMail
IMail具有以下函数:
IsMapiInstalled Checks if the MAPI is installed on the system. It searches Win.INI file for the MAPI key. If found it returns S_OK.
InitMapi After checking the through IsMapiInstalled, it initializes the MAPI function pointers. Method should be called once before using the component.
put_strProfileName Takes the name of the outlook profile name you are using to send the email.
put_strEmailAddress Sets the recipient email address. You can specify more than one comma (,) separated recipient addresses.
put_strRecipient Sets the name you want to specify for the recipients, sets the email names of the sender – it may be different from your specified profile email address.
put_strSubject Sets the subject of the email.
get_strSubject Returns the email subject.
put_strMessage Sets email message text.
get_strMessage Returns message text.
put_strAttachmentFilePath Sets the email attachment with the full path like “c:\abc.txt”.
get_strAttachmentFilePath Returns the path of email attachment.
put_strAttachmentFile The display name of the attachment (Sample.txt), by default, it’s the same as that specified in put_strAttachmentFilePath.
get_strAttachmentFile Returns the attachment file name.
Logon Opens a new logon session if not already opened, using specified outlook profile, name and the profile password, you must logon before sending the email. I have set password to NULL assuming that the profile you will specify have NO password, but you can specify your own password. Automatically called by Send method.
Logoff Logs off, and closes the session. Automatically called by Send method after sending the email.
Send Sends the email, requires valid outlook profile name, recipient email address and a login session to send email.
演示项目展示了如何使用该组件发送邮件。为了执行演示项目,需要以下设置:
步骤1:必须有一个有效的Outlook Express电子邮件帐户或创建一个名为TestProfile的帐户。可以从Tools>Accounts菜单中创建Outlook Express的电子邮件配置文件。这将打开Internet Accounts属性表。在All标签页上,点击Add按钮,然后选择Mail。向导将帮助创建一个电子邮件帐户,指定有效的电子邮件地址。对于hotmail帐户,向导会自动设置电子邮件服务器的名称。
成功创建帐户后,从All标签页的列表中选择帐户名称(对于hotmail帐户,默认帐户名称是Hotmail)。通过按Properties按钮打开帐户属性,并将帐户名称从默认名称(比如Hotmail)更改为TestProfile。
步骤2:注册DLL。所有COM DLL都需要注册。复制DLL源代码后,可以通过右键单击DLL并选择Register DLL或Register COM component选项来注册DLL,或者简单地双击DLL。在Visual Studio中编译DLL代码将自动注册DLL。
步骤3:登录到网络。确保已经登录到网络。如果没有,Outlook将无法发送电子邮件,但是仍然可以在发件箱中检查已编写的电子邮件。
在对话框中指定信息后,点击Send按钮。将显示一个警告消息,点击Send按钮。
注意:由于安全限制,会显示警告对话框。如果想摆脱这个对话框,那么必须使用扩展MAPI而不是简单的MAPI。
以下是CTestEmailDlg::OnSend方法,它用于将用户指定的信息传递给电子邮件对象,并在设置所有内容后调用IMail::Send方法。
void CTestEmailDlg::OnSend()
{
UpdateData();
try
{
CComPtr objMail;
HRESULT hr;
hr = objMail.CoCreateInstance(CLSID_Mail);
if (SUCCEEDED(hr))
{
if (hr == S_OK)
{
if (m_strProfile.IsEmpty())
{
AfxMessageBox("Please specify email profile name");
return;
}
if (m_strTo.IsEmpty())
{
AfxMessageBox("Please specify recipient's email address");
return;
}
hr = objMail->put_strProfileName((_bstr_t)m_strProfile);
hr = objMail->put_strSubject((_bstr_t)m_strSubject);
hr = objMail->put_strEmailAddress((_bstr_t)m_strTo);
hr = objMail->put_strRecipient((_bstr_t)m_strTo);
hr = objMail->put_strAttachmentFilePath((_bstr_t)m_strAttachment);
hr = objMail->put_strMessage((_bstr_t)m_strMessage);
hr = objMail->Send();
if (hr != S_OK)
AfxMessageBox("Error, make sure the info is correct");
}
}
}
catch(...)
{
AfxMessageBox("Error, make sure specified info is correct");
}
}
检查收件人收件箱中的邮件。
这个组件可以扩展到打开现有的收件箱,自动从收件箱中读取电子邮件,并自动编写新电子邮件等功能。它可以用于在特定时间自动发送带有自定义用户消息和附件的电子邮件给特定的人,特别是在使用某些exe服务器或NT服务时。