Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Email in c++ or invoking print in C++ 4

Status
Not open for further replies.

Moogles

MIS
Oct 6, 2002
37
US
Is there anything similar to VB mapisession in C++? I would like to email out a text file on the OS within in a C++ program; Or if you know how to invoke print to print the text file on OS within the C++ program.

Any help is greatly appreciated!
 
what do you mean:
to email out ... on the OS ...?

Ion Filipski
1c.bmp

ICQ: 95034075
AIM: IonFilipski
filipski@excite.com
 
Thank you for the response!

I meant I would like to email a text file that resides on my c: drive.

thanks!
 
there are many ways, for example, you could use SMTP, and
1. send your file as attachment
or
2. read the file line by line and send its contents

Ion Filipski
1c.bmp

ICQ: 95034075
AIM: IonFilipski
filipski@excite.com
 
Thank you very much for the hint, that's exactly what I am going to do.
 
Hi,

I provide here for you two classes that are working :

//---MailMessage.h

#if !defined(_MAILMESSAGE_H_)
#define _MAILMESSAGE_H_

#include <afxtempl.h>

class CMailMessage
{
public:
CMailMessage();
virtual ~CMailMessage();

int GetNumRecipients();
BOOL GetRecipient( CString& sEmailAddress, CString& sFriendlyName, int nIndex = 0 );
BOOL AddRecipient( LPCTSTR szEmailAddress, LPCTSTR szFriendlyName = &quot;&quot; );
BOOL AddMultipleRecipients( LPCTSTR szRecipients = NULL );

CString m_sFrom;
CString m_sSubject;
CString m_sHeader;
CTime m_tDateTime;
CString m_sBody;
private:
class CRecipient
{
public:
CString m_sEmailAddress;
CString m_sFriendlyName;
};
CArray <CRecipient, CRecipient&> m_Recipients;
};

#endif

// ---MailMessage.cpp

// MailMessage.cpp: implementation of the CMailMessage class.
//////////////////////////////////////////////////////////////////////

//#include &quot;stdafx.h&quot; -obislavu- uncomment it if you use MFC precompiled headers
#include &quot;MailMessage.h&quot;

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CMailMessage::CMailMessage()
{

}

CMailMessage::~CMailMessage()
{

}

BOOL CMailMessage::AddRecipient( LPCTSTR szEmailAddress, LPCTSTR szFriendlyName)
{
ASSERT( szEmailAddress != NULL );
ASSERT( szFriendlyName != NULL );
CRecipient to;
to.m_sEmailAddress = szEmailAddress;
to.m_sFriendlyName = szFriendlyName;
m_Recipients.Add( to );
return TRUE;
}

// sEmailAddress and sFriendlyName are OUTPUT parameters.
// If the function fails, it will return FALSE, and the OUTPUT
// parameters will not be touched.
BOOL CMailMessage::GetRecipient(CString & sEmailAddress, CString & sFriendlyName, int nIndex)
{
CRecipient to;
if( nIndex < 0 || nIndex > m_Recipients.GetUpperBound() )
return FALSE;
to = m_Recipients[ nIndex ];
sEmailAddress = to.m_sEmailAddress;
sFriendlyName = to.m_sFriendlyName;
return TRUE;
}

int CMailMessage::GetNumRecipients()
{
return m_Recipients.GetSize();
}

BOOL CMailMessage::AddMultipleRecipients(LPCTSTR szRecipients )
{
TCHAR* buf;
UINT pos;
UINT start;
CString sTemp;
CString sEmail;
CString sFriendly;
UINT length;
int nMark;
int nMark2;

ASSERT( szRecipients != NULL );

// Add Recipients
//
length = strlen( szRecipients );
buf = new TCHAR[ length + 1 ]; // Allocate a work area (don't touch parameter itself)
strcpy( buf, szRecipients );
for( pos = 0, start = 0; pos <= length; pos++ )
{
if( buf[ pos ] == ';' ||
buf[ pos ] == 0 )
{
// First, pick apart the sub-strings (separated by ';')
// Store it in sTemp.
//
buf[ pos ] = 0; // Redundant when at the end of string, but who cares.
sTemp = &buf[ start ];

// Now divide the substring into friendly names and e-mail addresses.
//
nMark = sTemp.Find( '<' );
if( nMark >= 0 )
{
sFriendly = sTemp.Left( nMark );
nMark2 = sTemp.Find( '>' );
if( nMark2 < nMark )
{
delete[] buf;
return FALSE;
}
// End of mark at closing bracket or end of string
nMark2 > -1 ? nMark2 = nMark2 : nMark2 = sTemp.GetLength() - 1;
sEmail = sTemp.Mid( nMark + 1, nMark2 - (nMark + 1) );
}
else
{
sEmail = sTemp;
sFriendly = &quot;&quot;;
}
AddRecipient( sEmail, sFriendly );
start = pos + 1;
}
}
delete[] buf;
return TRUE;
}

// -----------------SMTP.h-----------------

// SMTP.h: interface for the CSMTP class.
// use the SMTP Protocol
// 1999-12-01 -obislavu-
// Note: Please keep this note!!!!
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_SMTP_H__55DE48CB_BEA4_11D1_870E_444553540000__INCLUDED_)
#define AFX_SMTP_H__55DE48CB_BEA4_11D1_870E_444553540000__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#include <afxsock.h>
#include &quot;MailMessage.h&quot;

#define SMTP_PORT 25 // Standard port for SMTP servers
#define RESPONSE_BUFFER_SIZE 1024

// CSMTP Encapsulate SMTP protocol
class CSMTP
{
public:
CSMTP( LPCTSTR szSMTPServerName, UINT nPort = SMTP_PORT );
virtual ~CSMTP();

void SetServerProperties( LPCTSTR sServerHostName, UINT nPort = SMTP_PORT );
CString GetLastError();
CString GetMailerName();
UINT GetPort();
BOOL Disconnect();
BOOL Connect();
virtual BOOL FormatMailMessage( CMailMessage* msg );
BOOL SendMessage( CMailMessage* msg );
CString GetServerHostName();

private:
BOOL get_response( UINT response_expected );
BOOL transmit_message( CMailMessage* msg );
CString prepare_body( CMailMessage* msg );
BOOL prepare_header( CMailMessage* msg);

CString m_sError;
BOOL m_bConnected;
UINT m_nPort;
CString m_sMailerName;
CString m_sSMTPServerHostName;
CSocket m_wsSMTPServer;
protected:

//
// Helper Code
//
struct response_code
{
UINT nResponse; // Response we're looking for
TCHAR* sMessage; // Error message if we don't get it
};

enum eResponse
{
GENERIC_SUCCESS = 0,
CONNECT_SUCCESS,
DATA_SUCCESS,
QUIT_SUCCESS,
// Include any others here
LAST_RESPONSE // Do not add entries past this one
};
TCHAR response_buf[ RESPONSE_BUFFER_SIZE ];
static response_code response_table[];
};

#endif // !defined(AFX_SMTP_H__55DE48CB_BEA4_11D1_870E_444553540000__INCLUDED_)

// --------------------------SMTP.CPP ---

// SMTP.cpp: implementation of the CSMTP class.
// 1999-12-01 -obislavu--
//////////////////////////////////////////////////////////////////////

// #include &quot;stdafx.h&quot; - uncomment it if MFC with precompiled headers
#include &quot;SMTP.h&quot;

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

// Static member initializers
//

// Note: the order of the entries is important.
// They must be synchronized with eResponse entries.
CSMTP::response_code CSMTP::response_table[] =
{
{ 250, &quot;SMTP server error&quot; }, // GENERIC_SUCCESS
{ 220, &quot;SMTP server not available&quot; }, // CONNECT_SUCCESS
{ 354, &quot;SMTP server not ready for data&quot; }, // DATA_SUCCESS
{ 221, &quot;SMTP server didn't terminate session&quot; } // QUIT_SUCCESS
};


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CSMTP::CSMTP( LPCTSTR szSMTPServerName, UINT nPort )
{
ASSERT( szSMTPServerName != NULL );
AfxSocketInit();
m_sMailerName = _T( &quot;WC Mail&quot; );
m_sSMTPServerHostName = szSMTPServerName;
m_nPort = nPort;
m_bConnected = FALSE;
m_sError = _T( &quot;OK&quot; );
}

CSMTP::~CSMTP()
{
if( m_bConnected )
Disconnect();
}

CString CSMTP::GetServerHostName()
{
return m_sSMTPServerHostName;
}

BOOL CSMTP::Connect()
{
CString sHello;
TCHAR local_host[ 80 ]; // Warning: arbitrary size
if( m_bConnected )
return TRUE;

if( !m_wsSMTPServer.Create() )
{
m_sError = _T( &quot;Unable to create the socket.&quot; );
return FALSE;
}
if( !m_wsSMTPServer.Connect( GetServerHostName(), GetPort() ) )
{
m_sError = _T( &quot;Unable to connect to server&quot; );
m_wsSMTPServer.Close();
return FALSE;
}
if( !get_response( CONNECT_SUCCESS ) )
{
m_sError = _T( &quot;Server didn't respond.&quot; );
m_wsSMTPServer.Close();
return FALSE;
}
gethostname( local_host, 80 );
sHello.Format( &quot;HELO %s\r\n&quot;, local_host );
m_wsSMTPServer.Send( (LPCTSTR)sHello, sHello.GetLength() );
if( !get_response( GENERIC_SUCCESS ) )
{
m_wsSMTPServer.Close();
return FALSE;
}
m_bConnected = TRUE;
return TRUE;
}

BOOL CSMTP::Disconnect()
{
BOOL ret;
if( !m_bConnected )
return TRUE;
// Disconnect gracefully from the server and close the socket
CString sQuit = _T( &quot;QUIT\r\n&quot; );
m_wsSMTPServer.Send( (LPCTSTR)sQuit, sQuit.GetLength() );

// No need to check return value here.
// If it fails, the message is available with GetLastError
ret = get_response( QUIT_SUCCESS );
m_wsSMTPServer.Close();

m_bConnected = FALSE;
return ret;
}

UINT CSMTP::GetPort()
{
return m_nPort;
}

CString CSMTP::GetMailerName()
{
return m_sMailerName;
}

CString CSMTP::GetLastError()
{
return m_sError;
}

BOOL CSMTP::SendMessage(CMailMessage * msg)
{
ASSERT( msg != NULL );
if( !m_bConnected )
{
m_sError = _T( &quot;Must be connected&quot; );
return FALSE;
}
if( FormatMailMessage( msg ) == FALSE )
{
return FALSE;
}
if( transmit_message( msg ) == FALSE )
{
return FALSE;
}
return TRUE;
}

BOOL CSMTP::FormatMailMessage( CMailMessage* msg )
{
ASSERT( msg != NULL );
if( prepare_header( msg ) == FALSE )
{
return FALSE;
}
// Append a CR/LF to body if necessary.
if( msg->m_sBody.Right( 2 ) != &quot;\r\n&quot; )
msg->m_sBody += &quot;\r\n&quot;;
return TRUE;
}

void CSMTP::SetServerProperties( LPCTSTR sServerHostName, UINT nPort)
{
ASSERT( sServerHostName != NULL );
// Needs to be safe in non-debug too
if( sServerHostName == NULL )
return;
m_sSMTPServerHostName = sServerHostName;
m_nPort = nPort;
}

// Create the SMTP message header as per RFC822
BOOL CSMTP::prepare_header(CMailMessage * msg)
{
ASSERT( msg != NULL );
CString sTo;
CString sDate;
CString& sHeader = msg->m_sHeader; // Shorthand

if( msg->GetNumRecipients() <= 0 )
{
m_sError = &quot;No Recipients&quot;;
return FALSE;
}

sHeader = &quot;&quot;; // Clear it

// Get the recipients into a single string
sTo = &quot;&quot;;
CString sEmail = &quot;&quot;;
CString sFriendly = &quot;&quot;;
for( int i = 0; i < msg->GetNumRecipients(); i++ )
{
msg->GetRecipient( sEmail, sFriendly, i );
sTo += ( i > 0 ? &quot;,&quot; : &quot;&quot; );
sTo += sFriendly;
sTo += &quot;<&quot;;
sTo += sEmail;
sTo += &quot;>&quot;;
}
msg->m_tDateTime = msg->m_tDateTime.GetCurrentTime();
// Format: Mon, 01 Jun 98 01:10:30 GMT
sDate = msg->m_tDateTime.Format( &quot;%a, %d %b %y %H:%M:%S %Z&quot; );
sHeader.Format( &quot;Date: %s\r\n&quot; &quot;From: %s\r\n&quot; &quot;To: %s\r\n&quot; &quot;Subject: %s\r\n&quot; &quot;X-Mailer: <%s>\r\n\r\n&quot;,
// Include other extension lines if desired
(LPCTSTR)sDate,
(LPCTSTR)msg->m_sFrom,
(LPCTSTR)sTo,
(LPCTSTR)msg->m_sSubject,
(LPCTSTR)m_sMailerName );
return TRUE;
}

CString CSMTP::prepare_body(CMailMessage * msg)
{
ASSERT( msg != NULL );
CString sTemp;
CString sCooked = &quot;&quot;;
LPTSTR szBad = &quot;\r\n.\r\n&quot;;
LPTSTR szGood = &quot;\r\n..\r\n&quot;;
int nPos;
int nStart = 0;
int nBadLength = strlen( szBad );
sTemp = msg->m_sBody;
if( sTemp.Left( 3 ) == &quot;.\r\n&quot; )
sTemp = &quot;.&quot; + sTemp;
//
// This is a little inefficient because it beings a search
// at the beginning of the string each time. This was
// the only thing I could think of that handled ALL variations.
// In particular, the sequence &quot;\r\n.\r\n.\r\n&quot; is troublesome.
// (Even CStringEx's FindReplace wouldn't handle that situation
// with the global flag set.)
//
while( (nPos = sTemp.Find( szBad )) > -1 )
{
sCooked = sTemp.Mid( nStart, nPos );
sCooked += szGood;
sTemp = sCooked + sTemp.Right( sTemp.GetLength() - (nPos + nBadLength) );
}
return sTemp;
}

BOOL CSMTP::transmit_message(CMailMessage * msg)
{
CString sFrom;
CString sTo;
CString sTemp;
CString sEmail;

ASSERT( msg != NULL );
if( !m_bConnected )
{
m_sError = _T( &quot;Must be connected&quot; );
return FALSE;
}

// Send the MAIL command
//
sFrom.Format( &quot;MAIL From: <%s>\r\n&quot;, (LPCTSTR)msg->m_sFrom );
m_wsSMTPServer.Send( (LPCTSTR)sFrom, sFrom.GetLength() );
if( !get_response( GENERIC_SUCCESS ) )
return FALSE;

// Send RCPT commands (one for each recipient)
//
for( int i = 0; i < msg->GetNumRecipients(); i++ )
{
msg->GetRecipient( sEmail, sTemp, i );
sTo.Format( &quot;RCPT TO: <%s>\r\n&quot;, (LPCTSTR)sEmail );
m_wsSMTPServer.Send( (LPCTSTR)sTo, sTo.GetLength() );
get_response( GENERIC_SUCCESS );
}

// Send the DATA command
sTemp = &quot;DATA\r\n&quot;;
m_wsSMTPServer.Send( (LPCTSTR)sTemp, sTemp.GetLength() );
if( !get_response( DATA_SUCCESS ) )
{
return FALSE;
}
// Send the header
//
m_wsSMTPServer.Send( (LPCTSTR)msg->m_sHeader, msg->m_sHeader.GetLength() );

// Send the body
//
sTemp = prepare_body( msg );
m_wsSMTPServer.Send( (LPCTSTR)sTemp, sTemp.GetLength() );

// Signal end of data
//
sTemp = &quot;\r\n.\r\n&quot;;
m_wsSMTPServer.Send( (LPCTSTR)sTemp, sTemp.GetLength() );
if( !get_response( GENERIC_SUCCESS ) )
{
return FALSE;
}
return TRUE;
}

BOOL CSMTP::get_response( UINT response_expected )
{
ASSERT( response_expected >= GENERIC_SUCCESS );
ASSERT( response_expected < LAST_RESPONSE );

CString sResponse;
UINT response;
response_code* pResp; // Shorthand

if( m_wsSMTPServer.Receive( response_buf, RESPONSE_BUFFER_SIZE ) == SOCKET_ERROR )
{
m_sError = _T( &quot;Socket Error&quot; );
return FALSE;
}
sResponse = response_buf;
sscanf( (LPCTSTR)sResponse.Left( 3 ), &quot;%d&quot;, &response );
pResp = &response_table[ response_expected ];
if( response != pResp->nResponse )
{
m_sError.Format( &quot;%d:%s&quot;, response, (LPCTSTR)pResp->sMessage );
return FALSE;
}
return TRUE;
}


How to use ?


CSMTP smtp(STRINGSERVER); // &quot;mail.yyy.uk&quot;);


if( !smtp.Connect() )
{
LogError( smtp.GetLastError() );
return FALSE;
}
CMailMessage objMailMessage;
objMailMessage.AddRecipient(&quot;obislavu@hotmail.com&quot;);
objMailMessage.AddRecipient(&quot;abc@d.ca&quot;);
}
objMailMessage.m_sFrom = &quot;.....FROMSTRING&quot;;
objMailMessage.m_sSubject =&quot;....SUBJECTSTRING&quot;;
objMailMessage.m_sHeader = &quot;&quot;;
objMailMessage.m_sBody = &quot; ....sTextFromFile&quot;;

smtp.SendMessage(&objMailMessage);

if( !smtp.Disconnect() )
{
LogError( smtp.GetLastError() );
return FALSE;
}
See the // commented lines for the StdAfx.h.
Let me know if it is not working!

-obislavu-
 
Thank you, that is very nice of you to provide all that codes. Our POP3 server is not working currently, but I will give it a try later on.
 
Another question, how to determine an accessible server within a corporate firewall ? How does outlook do it? I've tried mapi but it appears broken.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top