在Visual Studio8.0(Visual Studio 2005)开发包中,包含了一些由Microsoft提供的实用类,其中包括CMimeMessage和CSMTPConnection。这些类可以帮助轻松地发送电子邮件。然而,发现CMimeMessage类并没有直接支持发送HTML内容的邮件。在互联网上搜索后,发现许多人也在寻找这个问题的答案,但似乎没有人给出明确的解决方案。因此,决定扩展CMimeMessage类,添加一个能够将文本作为HTML添加到邮件消息中的函数。这个过程相对简单,并且可以内联完成。
首先,需要扩展CMimeText类,因为它有一个自动调用的MakeMimeHeader函数,用于生成它所代表的Mime部分的电子邮件头部。将这个新类命名为CMimeHtml。简单地复制了CMimeText类的MakeMimeHeader函数,并做了唯一的修改,即将Content-Type从text/plain更改为text/html:
C++
// 这个函数是CMimeText::MakeMimeHeader函数的副本。它已经被更新,将Content-Type更改为text/html而不是text/plain。
//
// 创建MIME头部
virtual
inline
BOOL MakeMimeHeader(CStringA& header, LPCSTR szBoundary)
throw
()
{
char szBegin[256];
if (*szBoundary)
{
// 这不是唯一的正文部分
Checked::memcpy_s(szBegin, sizeof(szBegin), ATLMIME_SEPARATOR, sizeof(ATLMIME_SEPARATOR));
Checked::memcpy_s(szBegin+6, sizeof(szBegin)-6, szBoundary, ATL_MIME_BOUNDARYLEN);
*(szBegin+(ATL_MIME_BOUNDARYLEN+6)) = '\0';
}
else
{
// 这是唯一的正文部分,因此输出完整的MIME头部
Checked::memcpy_s(szBegin, sizeof(szBegin), ATLMIME_VERSION, sizeof(ATLMIME_VERSION));
}
_ATLTRY
{
// 在这里可以看到Content-Type是text/html而不是text/plain。这是使电子邮件消息以文本或HTML格式输出的唯一区别,这是在部分头部中写入的Content-Type标记。
header.Format("%s\r\nContent-Type: text/html;\r\n\tcharset=\"%s\"\r\nContent-Transfer-Encoding: 8bit\r\n\r\n", szBegin, m_szCharset);
return TRUE;
}
_ATLCATCHALL()
{
return FALSE;
}
}
接下来,需要在CMimeMessage类中添加一个函数,以添加HTML Mime部分。将这个函数命名为AddHtml。复制了CMimeMessage类中AddText函数的代码。将这个新类命名为CExtMimeMessage。唯一的修改是将CMimeText类替换为扩展的CMimeHtml类:
C++
// 基本上取自Microsoft CMimeMessage::AddText函数。
// 唯一的区别是在BodyParts列表中添加了一个CMimeHtml类,而不是CMimeText类。
//
// 在邮件正文部分列表中的位置nPos添加一些文本
// szText - 文本
// nTextLen - 文本大小(字节)
// (可选 - 如果未指定,则执行_tcslen)
// nPos - 在邮件中插入文本的位置(可选)
// uiCodePage - 代码页(可选)
inline
BOOL AddHtml(LPCTSTR szText, int nTextLen = -1, int nPos = 1, UINT uiCodePage = 0)
throw()
{
if (szText == NULL)
return FALSE;
if (nPos < 1)
{
nPos = 1;
}
CAutoPtr spNewText;
// 注意只是使用CExteMimeHtml类(扩展的CMimeText)
// 扩展的部分是MakeMimeHeader函数使Content-Type为text/html而不是text/plain
CExtMimeHtml *pNewText = NULL;
ATLTRY(spNewText.Attach(pNewText = new CExtMimeHtml()));
if (!spNewText || !pNewText)
return FALSE;
BOOL bRet = pNewText->Initialize(szText, nTextLen, m_spMultiLanguage, uiCodePage);
if (bRet)
{
_ATLTRY
{
POSITION currPos = m_BodyParts.FindIndex(nPos-1);
if (!currPos)
{
if (!m_BodyParts.AddTail(spNewText))
bRet = FALSE;
}
else
{
if (!m_BodyParts.InsertBefore(currPos, spNewText))
bRet = FALSE;
}
}
_ATLCATCHALL()
{
bRet = FALSE;
}
}
return bRet;
}