/*
*********************************************************************
*
*	The Essence of OLE
*
*	Source code sample
*
*	Copyright (c) 1996, Rolling Thunder Computing, Ipswich MA
*
*	e-mail: essence@rollthunder.com
*	CompuServe: 73540,3430
*	Web: http://www.rollthunder.com
*
*	File Name: CMONIKERDATA.CPP
*
*	Purpose: IDataObject that transfers a moniker from server to client
*
*********************************************************************
*/

#include <windows.h>
#include "cmonikerdata.h"
#include "cenum.h"

extern UINT cfLinkSource ;

FORMATETC MonikerFeArray []= {
						{ 0, NULL, DVASPECT_CONTENT,  -1, TYMED_HGLOBAL },
					  };
/*
constructor/destructor 
*/

CMonikerData::CMonikerData(LPMONIKER pMoniker)
{
	m_RefCount = 1 ; 
	m_pMoniker = pMoniker ;
	m_pMoniker->AddRef( ) ;
 
	return;
}


CMonikerData::~CMonikerData(void)
{
	m_pMoniker->Release( ) ;
    return;
}

/*
GetData Method.  Caller is asking if we can supply data in a given 
format and medium
*/

STDMETHODIMP CMonikerData::GetData (LPFORMATETC lpfe, LPSTGMEDIUM lpstg) 
{

/*
We support the stream format for a moniker
STEP 4
Create a stream on an HGLOBAL, place it in the output STGMEDIUM structure.
Save the moniker to the stream.  
*/

	if (lpfe->cfFormat == cfLinkSource && 
		lpfe->dwAspect == DVASPECT_CONTENT)
	{
		if (lpfe->tymed == TYMED_ISTREAM)
		{
			CreateStreamOnHGlobal (NULL, TRUE, &lpstg->pstm) ;
			OleSaveToStream (m_pMoniker, lpstg->pstm) ;

			lpstg->tymed = TYMED_ISTREAM ;
			lpstg->pUnkForRelease = NULL ;

    		return S_OK ;
		}
	}




/*
User asked for a format that we couldn't supply.  Return error code.
*/
	
	return DATA_E_FORMATETC ;
}



STDMETHODIMP CMonikerData::QueryGetData (LPFORMATETC lpfe) 
{

/*
We'll give you a link source (moniker), transferred through an hGlobal
or a stream, with aspect content.  
*/

	if (lpfe->cfFormat == cfLinkSource && 
		lpfe->dwAspect == DVASPECT_CONTENT &&
		(lpfe->tymed == TYMED_ISTREAM))
	{
    	return S_OK ;
	}


	
/*
But we won't give you anything else
*/
	return DATA_E_FORMATETC ;
    
}

STDMETHODIMP CMonikerData::EnumFormatEtc (DWORD dwDir, LPENUMFORMATETC * lpEnum) 
{
	MonikerFeArray [0].cfFormat = cfLinkSource ;

	*lpEnum = (LPENUMFORMATETC) new CEnumerator (this, MonikerFeArray, 1, 
		sizeof (FORMATETC), IID_IEnumFORMATETC) ;

	if (*lpEnum == NULL)	
	{
		return E_FAIL ;
	}
	
	return S_OK ;
}

/*
Unimplemented members
*/

STDMETHODIMP CMonikerData::GetDataHere (LPFORMATETC lpfe, LPSTGMEDIUM lpst)
{
	return E_NOTIMPL ;
}

STDMETHODIMP CMonikerData::GetCanonicalFormatEtc (LPFORMATETC lpout, LPFORMATETC lpin)
{
	return E_NOTIMPL ;
}

STDMETHODIMP CMonikerData::SetData (LPFORMATETC lpfe, STGMEDIUM * lpst, BOOL fRelease)
{
	return E_NOTIMPL ;
}

STDMETHODIMP CMonikerData::DAdvise (FORMATETC * lpfe, DWORD dw, LPADVISESINK lpas, 
	DWORD FAR* lpdw) 
{
	return E_NOTIMPL ;
}

STDMETHODIMP CMonikerData::DUnadvise  (DWORD dw)
{
	return E_NOTIMPL ;
}

STDMETHODIMP CMonikerData::EnumDAdvise  (LPENUMSTATDATA * lpen)
{
	*lpen = NULL ;
	return E_NOTIMPL ;
}


HRESULT CMonikerData::QueryInterface(REFIID riid, LPVOID FAR *ppv)
{
    if (riid == IID_IUnknown || riid == IID_IDataObject)
    {
        *ppv = (LPVOID)this;  
        AddRef();
        return S_OK ;
    }
    else
    {
    	*ppv = NULL;       
    	return E_NOINTERFACE ;
    }
}


STDMETHODIMP_(ULONG) CMonikerData::AddRef(void)
{
    m_RefCount ++ ;
    return m_RefCount ;
}


STDMETHODIMP_(ULONG) CMonikerData::Release(void)
{
    
    m_RefCount -- ;
    
	if (m_RefCount == 0L)
    {
        delete this;
    }	return 0 ;

    return m_RefCount ;
}

