SIMPITEM.CPP

/* 
* SIMPITEM.CPP
* Simple Item Object for Link Source, Chapter 9
*
* Implementation of an item object with nothing more
* than the shared IDescription in IDESCRIP.CPP.
*
* Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
*
* Kraig Brockschmidt, Microsoft
* Internet : kraigb@microsoft.com
* Compuserve: >INTERNET:kraigb@microsoft.com
*/


#include "linksrc.h"

#ifdef WIN32ANSI
/*
* This is to turn off the mapping to ANSI wrapper APIs because
* we're actually using wide char strings under Win32 all the time
* in parts of this code.
*/
#undef CreateItemMoniker
#define CreateItemMoniker CreateItemMoniker

#endif


/*
* CSimpleItem::CSimpleItem
* CSimpleItem::~CSimpleItem
*
* Parameters (Constructor):
* pUnkParent LPUNKNOWN to the parent in which this
* item lives
* pfnDestroy PFNDESTROYED to call when an object
* is destroyed.
*/

CSimpleItem::CSimpleItem(LPUNKNOWN pUnkParent
, PFNDESTROYED pfnDestroy)
{
m_cRef=0;

//This keeps the parent storage open as well
m_pUnkParent=pUnkParent;
pUnkParent->AddRef();

m_pfnDestroy=pfnDestroy;

m_pIStorage=NULL;
m_pmk=NULL;
m_dwRegROT=0;

m_pImpIDescription=NULL;
return;
}

CSimpleItem::~CSimpleItem(void)
{
//Remove us from the running object table
if (0!=m_dwRegROT)
{
IRunningObjectTable *pROT;

if (SUCCEEDED(GetRunningObjectTable(0, &pROT)))
{
pROT->Revoke(m_dwRegROT);
pROT->Release();
}
}

ReleaseInterface(m_pmk);
ReleaseInterface(m_pIStorage);
DeleteInterfaceImp(m_pImpIDescription);

ReleaseInterface(m_pUnkParent);
return;
}



/*
* CSimpleItem::Init
*
* Purpose:
* Performs any intiailization of a CSimpleItem that's prone to
* failure that we also use internally before exposing the object
* outside.
*
* Parameters:
* pmkLeft IMoniker * of our containing object.
* pbc IBindCtx * to use to register ourselves
* as running.
* pszItem LPOLESTR naming this object.
* pIStorage IStorage * to our information.
*
* Return Value:
* BOOL TRUE if the function is successful,
* FALSE otherwise.
*/

BOOL CSimpleItem::Init(IMoniker *pmkLeft, IBindCtx *pbc
, LPOLESTR pszItem, IStorage *pIStorage)
{
OLECHAR szDelim[]=OLETEXT("!");
HRESULT hr=ResultFromScode(S_FALSE);
IMoniker *pmkItem;

m_pImpIDescription=new CImpIDescription(this);

if (NULL==m_pImpIDescription)
return FALSE;

m_pIStorage=pIStorage;
m_pImpIDescription->SetStorage(m_pIStorage);


/*
* Create an item moniker for ourselves and register as
* running. Failure here is not critical.
*/
if (FAILED(CreateItemMoniker(szDelim, pszItem, &pmkItem)))
return TRUE;

//Create a composite for ourselves
if (SUCCEEDED(pmkLeft->ComposeWith(pmkItem, FALSE, &m_pmk)))
{
IRunningObjectTable *pROT;

if (SUCCEEDED(pbc->GetRunningObjectTable(&pROT)))
{
pROT->Register(0, this, m_pmk, &m_dwRegROT);
pROT->Release();
}
}

pmkItem->Release();
return TRUE;
}




/*
* CSimpleItem::QueryInterface
* CSimpleItem::AddRef
* CSimpleItem::Release
*
* Purpose:
* IUnknown members for CSimpleItem object.
*/

STDMETHODIMP CSimpleItem::QueryInterface(REFIID riid, PPVOID ppv)
{
*ppv=NULL;

if (IID_IUnknown==riid)
*ppv=this;

if (IID_IDescription==riid)
*ppv=m_pImpIDescription;

if (NULL!=*ppv)
{
((LPUNKNOWN)*ppv)->AddRef();
return NOERROR;
}

return ResultFromScode(E_NOINTERFACE);
}


STDMETHODIMP_(ULONG) CSimpleItem::AddRef(void)
{
return ++m_cRef;
}


STDMETHODIMP_(ULONG) CSimpleItem::Release(void)
{
if (0L!=--m_cRef)
return m_cRef;

if (NULL!=m_pfnDestroy)
(*m_pfnDestroy)();

delete this;
return 0;
}