Click here to Skip to main content
15,889,808 members
Articles / Desktop Programming / MFC

The Ultimate TCP/IP Home Page

Rate me:
Please Sign up or sign in to vote.
4.98/5 (77 votes)
25 Aug 2007CPOL13 min read 2.6M   45.4K   267  
Ultimate TCP-IP is now Open Source
//=================================================================
//  class: CMessage
//  File:  Message.cpp
//
//  Implementation of CMessage class
//
//=================================================================
// Ultimate TCP/IP v4.2
// This software along with its related components, documentation and files ("The Libraries")
// is � 1994-2007 The Code Project (1612916 Ontario Limited) and use of The Libraries is
// governed by a software license agreement ("Agreement").  Copies of the Agreement are
// available at The Code Project (www.codeproject.com), as part of the package you downloaded
// to obtain this file, or directly from our office.  For a copy of the license governing
// this software, you may contact us at legalaffairs@codeproject.com, or by calling 416-849-8900.
//=================================================================

#include "stdafx.h"
#include "UTMsg.h"
#include "Message.h"
#include "AboutDlg.h"

/////////////////////////////////////////////////////////////////////////////
// CMessage
/////////////////////////////////////////////////////////////////////////////
/***************************************************
CMessage
	Standart constructor. 
Params
    none
Return
	none
****************************************************/
CMessage::CMessage() 
{
	// Load Message Icon
	m_hMessageIcon = LoadIcon(_Module.m_hInst, MAKEINTRESOURCE(IDI_ICON_MESSAGE));	

	// Initiate default control size 32 x 32 pixels
    SIZE	sz = { 32, 32 };
    AtlPixelToHiMetric (&sz, &m_sizeExtent);		// convert pixels to himetric
    m_sizeNatural	= m_sizeExtent;					// store natural extent

	// Disable resizing of the control
	m_bAutoSize		= TRUE;				
  
}

/***************************************************
~CMessage
	Destructor.
Params
    none
Return
	none
****************************************************/
CMessage::~CMessage()
{
	// Destroy Message icon handle
	if(m_hMessageIcon) {
		DestroyIcon( m_hMessageIcon );							
		m_hMessageIcon = NULL;
		}
}

/***************************************************
InterfaceSupportsErrorInfo
	Checks if specified interface supports error
	information.
Params
    riid	- inteface id
Return
	S_OK	- support error info
	S_FALSE - don't support error info
****************************************************/
STDMETHODIMP CMessage::InterfaceSupportsErrorInfo(REFIID riid)
{
	static const IID* arr[] = 
	{
		&IID_IMessage,
	};
	for (int i=0; i<sizeof(arr)/sizeof(arr[0]); i++)
	{
		if (InlineIsEqualGUID(*arr[i], riid))
			return S_OK;
	}
	return S_FALSE;
}

/***************************************************
OnDraw
	Draw the icon
Params
    di	- A reference to the ATL_DRAWINFO structure
Return
	S_OK	- success
****************************************************/
HRESULT CMessage::OnDraw(ATL_DRAWINFO& di)
{
	// Fill background & draw a boreder
	RECT& rc = *(RECT*)di.prcBounds;
	Rectangle(di.hdcDraw, rc.left, rc.top, rc.right, rc.bottom);

	// Draw Message Icon
	if(m_hMessageIcon)
		DrawIcon(di.hdcDraw, rc.left, rc.top, m_hMessageIcon);	
 		
	return S_OK;
}



////////////////////////////////////////////////////
//	IMessage interface methods
////////////////////////////////////////////////////

/***************************************************
AboutBox
	Display about box
Params
    none
Return
	S_OK		- success
****************************************************/
STDMETHODIMP CMessage::AboutBox()
{
	CAboutDlg	dlg;

	dlg.DoModal();
	return S_OK;
}

/***************************************************
GetErrorText
	Returns a string representation of numeric error code.
Params
	ErrorCode	- number of error code
	ErrorText	- pointer to the error text varaible
Return
	S_OK			- success
	E_OUTOFMEMORY	- out of memory
****************************************************/
STDMETHODIMP CMessage::GetErrorText(long ErrorCode, BSTR *ErrorText)
{
 	HRESULT		hResult			= S_OK;
 	CComBSTR	bstrErrorMsg	= CUT_ERR::GetErrorString(ErrorCode);
 
 	if(!SysReAllocString(ErrorText, bstrErrorMsg))
 		hResult = E_OUTOFMEMORY;
 
 	return hResult;
}

/***************************************************
GetInterfaceSafetyOptions
	Gets inteface safety options
Params
	riid				- interface ID
	pdwSupportedOptions	- supported options
	pdwEnabledOptions	- enabled options
Return
	S_OK			- success
	E_NOINTERFACE	- no such interface
	E_FAIL			- failed
****************************************************/
STDMETHODIMP CMessage::GetInterfaceSafetyOptions(REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
{

	ATLTRACE(_T("CObjectSafetyImpl::GetInterfaceSafetyOptions\n"));

	if (!pdwSupportedOptions || !pdwEnabledOptions)
		return E_FAIL;

	LPUNKNOWN pUnk;
	if (_InternalQueryInterface (riid, (void**)&pUnk) == E_NOINTERFACE) {
		// Our object doesn't even support this interface.
		return E_NOINTERFACE;
		}
	else {
		// Cleanup after ourselves.
		pUnk->Release();
		pUnk = NULL;
		}

	if (riid == IID_IDispatch) {
		// IDispatch is an interface used for scripting. If your
		// control supports other IDispatch or Dual interfaces, you
		// may decide to add them here as well. Client wants to know
		// if object is safe for scripting. Only indicate safe for
		// scripting when the interface is safe.
		*pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
		*pdwEnabledOptions = m_dwCurrentSafety & INTERFACESAFE_FOR_UNTRUSTED_CALLER;
		return S_OK;
		}
	else if ((riid == IID_IPersistStreamInit) || (riid == IID_IPersistStorage) || (riid == IID_IPersistPropertyBag)) {
		// IID_IPersistStreamInit and IID_IPersistStorage are
		// interfaces used for Initialization. If your control
		// supports other Persistence interfaces, you may decide to
		// add them here as well. Client wants to know if object is
		// safe for initializing. Only indicate safe for initializing
		// when the interface is safe.
		*pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
		*pdwEnabledOptions = m_dwCurrentSafety & INTERFACESAFE_FOR_UNTRUSTED_DATA;
		return S_OK;
		}
	else {
		// We are saying that no other interfaces in this control are
		// safe for initializing or scripting.
		*pdwSupportedOptions = 0;
		*pdwEnabledOptions = 0;
		return E_FAIL;
		}
   }


/***************************************************
SetInterfaceSafetyOptions
	Sets inteface safety options
Params
	riid				- interface ID
	dwOptionSetMask		- options mask
	pdwEnabledOptions	- enabled options
Return
	S_OK			- success
	E_NOINTERFACE	- no such interface
	E_FAIL			- failed
****************************************************/
STDMETHODIMP CMessage::SetInterfaceSafetyOptions(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions)
{

	ATLTRACE(_T("CObjectSafetyImpl::SetInterfaceSafetyOptions\n"));

	if (!dwOptionSetMask && !dwEnabledOptions) return E_FAIL;
   
	LPUNKNOWN pUnk;
	if (_InternalQueryInterface (riid, (void**)&pUnk) == E_NOINTERFACE) {
		// Our object doesn't even support this interface.
		return E_NOINTERFACE;
		}
	else {
		// Cleanup after ourselves.
		pUnk->Release();
		pUnk = NULL;
		}

	// Store our current safety level to return in
	// GetInterfaceSafetyOptions
	m_dwCurrentSafety |= dwEnabledOptions & dwOptionSetMask;
	if ((riid == IID_IDispatch) && (m_dwCurrentSafety & INTERFACESAFE_FOR_UNTRUSTED_CALLER)) {
		// Client wants us to disable any functionality that would
		// make the control unsafe for scripting. The same applies to
		// any other IDispatch or Dual interfaces your control may
		// support. Because our control is safe for scripting by
		// default we just return S_OK.
		return S_OK;
		}
	else if (((riid == IID_IPersistStreamInit) || (riid == IID_IPersistStorage) || (riid == IID_IPersistPropertyBag)) &&
             (m_dwCurrentSafety & INTERFACESAFE_FOR_UNTRUSTED_DATA)) {
		// Client wants us to make the control safe for initializing
		// from persistent data. For these interfaces, this control
		// is safe so we return S_OK. For Any interfaces that are not
		// safe, we would return E_FAIL.
		return S_OK;
		}
	else {
		// This control doesn't allow Initialization or Scripting
		// from any other interfaces so return E_FAIL.
		return E_FAIL;
		}
}

/***************************************************
AddAttachment
	Adds attachment to the message
Params
	FileName	- full path to add
    Params      - optional attachment parameters separated by ','.
                  Different encoding classes will have different needs. 
                  e.g. the UUEncode ignores the string entirely, 
                  whereas the MimeEncode uses the first four:

                  The first string in the list contains the encoding 
                  type, which can be any of the following values:
  
                        "0" - CUT_MIME_7BIT
                        "1" - CUT_MIME_BASE64
                        "2" - CUT_MIME_QUOTEDPRINTABLE
                        "3" - CUT_MIME_8BIT
                        "4" - CUT_MIME_BINARY

                  The second string contains MIME compliant content 
                  type that the attachment will be identified by,
                  E.g. "image/bmp"

                  The third string contains the char-set portion of 
                  the content type, E.g. "US-ASCII"

                  The fourth string contains attachment type.

                  Each of these can be the empty string, in which 
                  case the default will be used.
 
	Result	    - pointer to the varaible receiving the return value
Return
	S_OK			- success
	E_OUTOFMEMORY	- out of memory
****************************************************/
STDMETHODIMP CMessage::AddAttachment(BSTR FileName, BSTR Params, long *Result)
{
    CUT_StringList  listParams;
	int				index = 0;
	char			buffer[1024];

    // Make String list out of string items separated with coma
    while(CUT_StrMethods::ParseString(_bstr_t(Params), ",", index++, buffer, sizeof(buffer)-1) == UTE_SUCCESS)
		listParams.AddString(buffer);

    // Call message class function
    *Result = CUT_Msg::AddAttachment(_bstr_t(FileName), &listParams);
	return S_OK;
}

/***************************************************
GetAttachmentNumber
	Gets the number of the attachments
Params
	Number	- pointer to the varaible receiving the return value
Return
	S_OK			- success
	E_OUTOFMEMORY	- out of memory
****************************************************/
STDMETHODIMP CMessage::GetAttachmentNumber(long *Number)
{
	*Number = CUT_Msg::GetAttachmentNumber();
	return S_OK;
}

/***************************************************
EmptyAttachmentList
	Clears attachment list
Params
	none
Return
	S_OK			- success
	E_OUTOFMEMORY	- out of memory
****************************************************/
STDMETHODIMP CMessage::EmptyAttachmentList()
{
	CUT_Msg::EmptyAttachmentList();
	return S_OK;
}

/***************************************************
GetAttachmentSize
	Gets attachment size
Params
    Index   - index of the attachment or -1 to get
              the size of all attachments.
	Size	- pointer to the varaible receiving the return value
Return
	S_OK			- success
	E_OUTOFMEMORY	- out of memory
****************************************************/
STDMETHODIMP CMessage::GetAttachmentSize(long Index, long *Size)
{
	*Size = CUT_Msg::GetAttachmentSize(Index);
	return S_OK;
}

/***************************************************
GetAttachmentName
	Gets attachment name
Params
    Index   - index of the attachment.
	Name	- pointer to the varaible receiving the return value
Return
	S_OK			- success
	E_OUTOFMEMORY	- out of memory
****************************************************/
STDMETHODIMP CMessage::GetAttachmentName(long Index, BSTR *Name)
{
    _bstr_t         bstrName;
 	HRESULT		    hResult			= S_OK;
    char            szName[MAX_PATH+1], szType[MAX_PATH+1];
    CUT_StringList  listParams;
 
    if(CUT_Msg::GetAttachmentInfo(Index, szName, MAX_PATH, szType, MAX_PATH, &listParams) == UTE_SUCCESS) 
        bstrName = szName;

 	if(!SysReAllocString(Name, bstrName))
 		hResult = E_OUTOFMEMORY;

	return hResult;
}

/***************************************************
GetAttachmentType
	Gets attachment type
Params
    Index   - index of the attachment.
	Type	- pointer to the varaible receiving the return value
Return
	S_OK			- success
	E_OUTOFMEMORY	- out of memory
****************************************************/
STDMETHODIMP CMessage::GetAttachmentType(long Index, BSTR *Type)
{
    _bstr_t         bstrType;
 	HRESULT		    hResult			= S_OK;
    char            szName[MAX_PATH+1], szType[MAX_PATH+1];
    CUT_StringList  listParams;
 
    if(CUT_Msg::GetAttachmentInfo(Index, szName, MAX_PATH, szType, MAX_PATH, &listParams) == UTE_SUCCESS) 
        bstrType = szType;

 	if(!SysReAllocString(Type, bstrType))
 		hResult = E_OUTOFMEMORY;

	return hResult;
}

/***************************************************
GetAttachmentParam
	Gets attachment optional param. 
    UUEncode class will not use this. 
    The MimeEncode will return the encoding type (e.g. 7bit, base-64) 
    See AddAttachment function.
Params
    Index   - index of the attachment.
	Param	- pointer to the varaible receiving the return value
Return
	S_OK			- success
	E_OUTOFMEMORY	- out of memory
****************************************************/
STDMETHODIMP CMessage::GetAttachmentParam(long Index, BSTR *Param)
{
    _bstr_t         bstrParam;
 	HRESULT		    hResult			= S_OK;
    char            szName[MAX_PATH+1], szType[MAX_PATH+1];
    CUT_StringList  listParams;
 
    if(CUT_Msg::GetAttachmentInfo(Index, szName, MAX_PATH, szType, MAX_PATH, &listParams) == UTE_SUCCESS) 
        for(int i=0; i < listParams.GetCount(); i++) {
            if(i != 0)
                bstrParam += ",";
            bstrParam += listParams.GetString(i);
            }

 	if(!SysReAllocString(Param, bstrParam))
 		hResult = E_OUTOFMEMORY;

	return hResult;
}

/***************************************************
AddAttachmentHeaderTag
	Add custom headers to an individual attachment
	Affect the last added attachment. Can be called
	several times to form a list of headers.
Params
    Tag     - tag to add
	Param	- pointer to the varaible receiving the return value
Return
	S_OK			- success
	E_OUTOFMEMORY	- out of memory
****************************************************/
STDMETHODIMP CMessage::AddAttachmentHeaderTag(BSTR Tag, long *Result)
{
	*Result = CUT_Msg::AddAttachmentHeaderTag(_bstr_t(Tag));
	return S_OK;
}

/***************************************************
SetDefaultEncoding
	Sets default encoding MIME or UUEncode.
    Default is Mime.
Params
    Type    - etUUEncode or etMime
	Result	- pointer to the varaible receiving the return value
Return
	S_OK			- success
	E_OUTOFMEMORY	- out of memory
****************************************************/
STDMETHODIMP CMessage::SetDefaultEncoding(EncodingType Type, long *Result)
{
    *Result = CUT_Msg::SetDefEncoding((Type == etMime) ? "Mime" : "UUEncode");
	return S_OK;
}

/***************************************************
GetCustomFieldName
	Gets custom field name by index
Params
    Index   - index of the field to get
	Name    - pointer to the varaible receiving the return value
Return
	S_OK			- success
	E_OUTOFMEMORY	- out of memory
****************************************************/
STDMETHODIMP CMessage::GetCustomFieldName(long Index, BSTR *Name)
{
 	HRESULT		hResult			= S_OK;
 
 	if(!SysReAllocString(Name, _bstr_t(CUT_Msg::GetCustomFieldName(Index))))
 		hResult = E_OUTOFMEMORY;

	return hResult;
}

/***************************************************
GetFieldName
	Gets field name by field ID
Params
    Field   - field id
	Name    - pointer to the varaible receiving the return value
Return
	S_OK			- success
	E_OUTOFMEMORY	- out of memory
****************************************************/
STDMETHODIMP CMessage::GetFieldName(HeaderFieldType Field, BSTR *Name)
{
 	HRESULT		hResult			= S_OK;
 
 	if(!SysReAllocString(Name, _bstr_t(CUT_Msg::GetFieldName((HeaderFieldID)Field))))
 		hResult = E_OUTOFMEMORY;

	return hResult;
}

/***************************************************
GetMessageBody
	Gets message body text
Params
    Text    - message body text
Return
	S_OK			- success
	E_OUTOFMEMORY	- out of memory
****************************************************/
STDMETHODIMP CMessage::GetMessageBody(BSTR *Text)
{
 	HRESULT		hResult			= S_OK;
 
 	if(!SysReAllocString(Text, _bstr_t(CUT_Msg::GetMessageBody())))
 		hResult = E_OUTOFMEMORY;

	return hResult;
}

/***************************************************
SetMessageBody
	Sets message body text
Params
    Text    - message body text to set
    Result  - pointer to the varaible receiving the return value
Return
	S_OK			- success
	E_OUTOFMEMORY	- out of memory
****************************************************/
STDMETHODIMP CMessage::SetMessageBody(BSTR Text, long *Result)
{
	*Result = UTE_MSG_BODY_TOO_BIG;
    if(CUT_Msg::SetMessageBody(_bstr_t(Text)))
        *Result = UTE_SUCCESS;

	return S_OK;
}

/***************************************************
AddHeaderField
	Adds a new message field. If nID == UTM_CUSTOM_FIELD
	you must specify the name of the field in lpszFieldName
Params
    Data		- pointer to the field's field data
    Type		- ID of the field 
	[FieldName] - pointer to the field's field name
    Result      - pointer to the varaible receiving the return value
Return
	S_OK			- success
	E_OUTOFMEMORY	- out of memory
****************************************************/
STDMETHODIMP CMessage::AddHeaderField(BSTR Data, HeaderFieldType Type, BSTR FieldName, long *Result)
{
	*Result = UTE_ERROR;
    if(CUT_Msg::AddHeaderField(_bstr_t(Data), (HeaderFieldID)Type, _bstr_t(FieldName)) != 0)
        *Result = UTE_SUCCESS;

	return S_OK;
}

/***************************************************
ClearHeader
	Clears fields
Params
    Type		- ID of the field to clear
Return
	S_OK			- success
	E_OUTOFMEMORY	- out of memory
****************************************************/
STDMETHODIMP CMessage::ClearHeader(HeaderFieldType Type, BSTR CustomName)
{
    _bstr_t bstrCustomName = CustomName;
    if(bstrCustomName.length() > 0)
	    CUT_Msg::ClearHeader((HeaderFieldID)Type, bstrCustomName);
    else
        CUT_Msg::ClearHeader((HeaderFieldID)Type);
	return S_OK;
}

/***************************************************
GetHeaderCountByName
	Returns number of field with specified name
Params
    Name        - name of the fields to count
    Number      - pointer to the varaible receiving the return value
Return
	S_OK			- success
	E_OUTOFMEMORY	- out of memory
****************************************************/
STDMETHODIMP CMessage::GetHeaderCountByName(BSTR Name, long *Number)
{
	*Number = CUT_Msg::GetHeaderCount(_bstr_t(Name));
	return S_OK;
}

/***************************************************
GetHeaderCountByType
	Returns number of field with specified type
Params
    Type        - type of the fields to count
    Number      - pointer to the varaible receiving the return value
Return
	S_OK			- success
	E_OUTOFMEMORY	- out of memory
****************************************************/
STDMETHODIMP CMessage::GetHeaderCountByType(HeaderFieldType Type, long *Number)
{
	*Number = CUT_Msg::GetHeaderCount((HeaderFieldID)Type);
	return S_OK;
}

/***************************************************
GetHeaderByName
	Get header field data with specified index by it's name
Params
    Name        - field name
    Index       - index of the field
    Header      - pointer to the varaible receiving the return value
Return
	S_OK			- success
	E_OUTOFMEMORY	- out of memory
****************************************************/
STDMETHODIMP CMessage::GetHeaderByName(BSTR Name, long Index, BSTR *Header)
{
 	HRESULT		hResult			= S_OK;
    _bstr_t     bstrHeader;
 
    if(Index == -1) {
        char    szBuffer[5120];
        if(CUT_Msg::GetHeaderByName(_bstr_t(Name), szBuffer, sizeof(szBuffer)-1))
            bstrHeader = szBuffer;
        }
    else
        bstrHeader = CUT_Msg::GetHeaderByName(_bstr_t(Name), Index);

 	if(!SysReAllocString(Header, bstrHeader))
 		hResult = E_OUTOFMEMORY;

	return hResult;
}

/***************************************************
GetHeaderByType
	Get header field data with specified index by it's type
Params
    Type        - type of the field
    Index       - index of the field
    Header      - pointer to the varaible receiving the return value
Return
	S_OK			- success
	E_OUTOFMEMORY	- out of memory
****************************************************/
STDMETHODIMP CMessage::GetHeaderByType(HeaderFieldType Type, long Index, BSTR *Header)
{
 	HRESULT		hResult			= S_OK;
    _bstr_t     bstrHeader;
 
    if(Index == -1) {
        char    szBuffer[5120];
        if(CUT_Msg::GetHeaderByType((HeaderFieldID)Type, szBuffer, sizeof(szBuffer)-1))
            bstrHeader = szBuffer;
        }
    else
        bstrHeader = CUT_Msg::GetHeaderByType((HeaderFieldID)Type, Index);

 	if(!SysReAllocString(Header, bstrHeader))
 		hResult = E_OUTOFMEMORY;

	return hResult;
}

/***************************************************
Load
	Loads message from the file
Params
    FileName    - file name to load
    Result      - pointer to the varaible receiving the return value
Return
	S_OK			- success
	E_OUTOFMEMORY	- out of memory
****************************************************/
STDMETHODIMP CMessage::Load(BSTR FileName, long *Result)
{
	*Result = CUT_Msg::LoadMessage(_bstr_t(FileName));
	return S_OK;
}

/***************************************************
Save
	Saves message to the file
Params
    FileName    - file name to save
    Result      - pointer to the varaible receiving the return value
Return
	S_OK			- success
	E_OUTOFMEMORY	- out of memory
****************************************************/
STDMETHODIMP CMessage::Save(BSTR FileName, long *Result)
{
	*Result = CUT_Msg::SaveMessage(_bstr_t(FileName));
	return S_OK;
}

/***************************************************
DecodeAttachment
	Decodes attachment
Params
    Index       - zero based index of the attachment
    FileName    - file name to save
    Result      - pointer to the varaible receiving the return value
Return
	S_OK			- success
	E_OUTOFMEMORY	- out of memory
****************************************************/
STDMETHODIMP CMessage::DecodeAttachment(long Index, BSTR FileName, long *Result)
{
	*Result = CUT_Msg::Decode(Index, _bstr_t(FileName));
	return S_OK;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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


Written By
Web Developer
Canada Canada
In January 2005, David Cunningham and Chris Maunder created TheUltimateToolbox.com, a new group dedicated to the continued development, support and growth of Dundas Software’s award winning line of MFC, C++ and ActiveX control products.

Ultimate Grid for MFC, Ultimate Toolbox for MFC, and Ultimate TCP/IP have been stalwarts of C++/MFC development for a decade. Thousands of developers have used these products to speed their time to market, improve the quality of their finished products, and enhance the reliability and flexibility of their software.
This is a Organisation

476 members

Comments and Discussions