Click here to Skip to main content
15,881,803 members
Articles / Desktop Programming / ATL

Send HTML Via SMTP By Extending CMimeMessage

Rate me:
Please Sign up or sign in to vote.
3.18/5 (6 votes)
18 Jan 2007CPOL2 min read 40.6K   297   15   11
Extending the CMimeMessage class to send HTML messages

Introduction

I had a project recently that required sending emails with HTML content. I found an article by PJ Naughter on CodeProject that provided a couple of nice classes from Microsoft that are included in the Visual Studio 8.0 (Visual Studio 2005) development package.  These classes are CMimeMessage and CSMTPConnection.  This article explains how to use these classes to easily send email messages.

I looked through the CMimeMessage class to see if there was a way to use it without modification to send emails with HTML content and didn't see a clear path, but may be wrong.  I searched the internet for a while and found that some others were asking the same question.  I didn't find an answer.

So I decided to extend the CMimeMessage class to add a function that would add Text as HMTL to the Mail Message. It turned out to be pretty simple and could be done inline.

The Code

The first thing that I had to do was to extend the CMimeText class, as it has a function MakeMimeHeader that is automatically called to generate the email header for the Mime Section that it represents. I named this class CMimeHtml

I just simply copied the MakeMimeHeader function from the existing CMimeText class. The only modification was to replace the Content-Type: text/plain with Content-Type: text/html:

C++
// 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;
}
}

The next step was to add a function to the CMimeMessage class to add an HTML Mime section. So I called the function AddHtml. I copied the code from the AddText function of the existing CMimeMessage class. I named this class CExtMimeMessage

The only modification here is to replace the CMimeText class with our extended CMimeHtml class:

C++
// 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;
}

All done.  All you have to do is copy in the included ExtMimeMessage.h file into your project, include "ExtMimeMessage.h", and use the CExtMimeMessage class in exactly the same way that you would have used the original CMimeMessage class.

I haven't seen any errors from using this class, but am open to all comments.

History

  • 18th January, 2007: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questionhow about getting not adding Pin
monsieur_jj13-Nov-07 14:40
monsieur_jj13-Nov-07 14:40 
GeneralAnother issue please help me Pin
monsieur_jj28-Aug-07 16:42
monsieur_jj28-Aug-07 16:42 
QuestionHow about getting the embedded image? Pin
monsieur_jj23-Aug-07 19:35
monsieur_jj23-Aug-07 19:35 
AnswerRe: How about getting the embedded image? Pin
MBrooker24-Aug-07 3:24
MBrooker24-Aug-07 3:24 
GeneralRe: How about getting the embedded image? Pin
monsieur_jj28-Aug-07 15:10
monsieur_jj28-Aug-07 15:10 
GeneralRe: How about getting the embedded image? Pin
MBrooker28-Aug-07 15:19
MBrooker28-Aug-07 15:19 
GeneralUnicode messages Pin
thanhnt11-Jun-07 21:00
thanhnt11-Jun-07 21:00 
GeneralRe: Unicode messages Pin
MBrooker24-Aug-07 2:52
MBrooker24-Aug-07 2:52 
GeneralRe: Unicode messages [modified] Pin
thanhnt30-Aug-07 16:10
thanhnt30-Aug-07 16:10 
JokeToo easy :) Pin
richard sancenot26-Jan-07 0:11
richard sancenot26-Jan-07 0:11 
GeneralRe: Too easy :) Pin
MBrooker12-Feb-07 4:57
MBrooker12-Feb-07 4:57 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.