65.9K
CodeProject 正在变化。 阅读更多。
Home

通过扩展 CMimeMessage 发送 HTML

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.18/5 (6投票s)

2007年1月18日

CPOL

2分钟阅读

viewsIcon

41897

downloadIcon

319

扩展 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 日:初始发布
© . All rights reserved.