通过扩展 CMimeMessage 发送 HTML
扩展 CMimeMessage 类以发送 HTML 消息。
引言
我最近的一个项目需要发送包含 HTML 内容的电子邮件。 我找到了 PJ Naughter 在 CodeProject 上的一篇文章,该文章提供了 Microsoft 包含在 Visual Studio 8.0(Visual Studio 2005)开发包中的几个不错的类。 这些类是 CMimeMessage
和 CSMTPConnection
。 本文解释了如何使用这些类轻松发送电子邮件。
我查看了 CMimeMessage
类,看看是否可以在不修改的情况下使用它来发送 HTML 内容的电子邮件,但没有看到明确的路径,但可能我错了。 我在互联网上搜索了一段时间,发现其他人也在问同样的问题。 我没有找到答案。
因此,我决定扩展 CMimeMessage
类,添加一个将文本作为 HTML 添加到邮件消息的功能。 结果非常简单,可以直接内联完成。
代码
我首先需要做的是扩展 CMimeText
类,因为它有一个函数 MakeMimeHeader
,该函数会自动调用以生成它所代表的 Mime 部分的电子邮件标头。 我将这个类命名为 CMimeHtml
。
我只是简单地从现有的 CMimeText
类中复制了 MakeMimeHeader
函数。 唯一的修改是将 Content-Type: text/plain
替换为 Content-Type: text/html
// This function is a copy of the CMimeText::MakeMimeHeader function. It has been
// updated to change the Content-Type text/html rather than text/plain.
//
// Make the MIME header
virtual inline BOOL MakeMimeHeader(CStringA& header, LPCSTR szBoundary) throw()
{
char szBegin[256];
if (*szBoundary)
{
// this is not the only body part
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
{
// this is the only body part, so output the full MIME header
Checked::memcpy_s(szBegin, sizeof(szBegin), ATLMIME_VERSION, sizeof(ATLMIME_VERSION));
}
_ATLTRY
{
// Here you can see that the Content-Type is text/html instead of text/plain. This is
// the only thing that makes the email message come out as text or html is this
// Content-Type marker that is written in the section header.
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
。
这里唯一的修改是用我们的扩展类 CMimeHtml
类替换 CMimeText
类
// Pretty much taken from the Microsoft CMimeMessage::AddText function.
// The only difference is that we add a CMimeHtml class to the BodyParts
// list instead of a CMimeText class.
//
// Add some text to the message at position nPos in the body parts list
// szText - the text
// nTextLen - the size of the text in bytes
// (optional - if not specified a _tcslen will be done)
// nPos - the position in the message at which to insert the text (optional)
// uiCodePage - the codepage (optional)
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<CMimeBodyPart> spNewText;
// Note that we are simply using the CExteMimeHtml Class (Extended CMimeText)
// The extended part is that the MakeMimeHeader function makes the Content-Type
// text/html instead of 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;
}
完成了。 你只需要将包含的 ExtMimeMessage.h 文件复制到你的项目中,包含 "ExtMimeMessage.h",并以与使用原始 CMimeMessage
类完全相同的方式使用 CExtMimeMessage
类。
我还没有在使用这个类时遇到任何错误,但我欢迎所有评论。
历史
- 2007 年 1 月 18 日:初始发布