/*
* CONTITEM.CPP
* Container Item Object for Link Source, Chapter 9
*
* Implementation of an item object that is itself a container
* of other items. It implements IDescription and
* IOleItemContainer using the shared implemenations in
* IDESCRIP.CPP and IOLECONT.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
/*
* CContainerItem::CContainerItem
* CContainerItem::~CContainerItem
*
* Parameters (Constructor):
* pUnkParent LPUNKNOWN to the parent in which this
* item lives
* pfnDestroy PFNDESTROYED to call when an object
* is destroyed.
*/
CContainerItem::CContainerItem(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_pImpIOleItemContainer=NULL;
m_pImpIDescription=NULL;
return;
}
CContainerItem::~CContainerItem(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);
DeleteInterfaceImp(m_pImpIOleItemContainer);
ReleaseInterface(m_pUnkParent);
return;
}
/*
* CContainerItem::Init
*
* Purpose:
* Performs any intiailization of a CContainerItem 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 CContainerItem::Init(IMoniker *pmkLeft, IBindCtx *pbc
, LPOLESTR pszItem, IStorage *pIStorage)
{
OLECHAR szDelim[]=OLETEXT("!");
HRESULT hr=ResultFromScode(S_FALSE);
IMoniker *pmkItem;
m_pImpIOleItemContainer=new CImpIOleItemContainer(this, this
, FALSE);
if (NULL==m_pImpIOleItemContainer)
return FALSE;
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;
}
/*
* CContainerItem::QueryInterface
* CContainerItem::AddRef
* CContainerItem::Release
*
* Purpose:
* IUnknown members for CContainerItem object.
*/
STDMETHODIMP CContainerItem::QueryInterface(REFIID riid, PPVOID ppv)
{
*ppv=NULL;
if (IID_IUnknown==riid)
*ppv=this;
if (IID_IParseDisplayName==riid || IID_IOleContainer==riid
|| IID_IOleItemContainer==riid)
*ppv=m_pImpIOleItemContainer;
if (IID_IDescription==riid)
*ppv=m_pImpIDescription;
if (NULL!=*ppv)
{
((LPUNKNOWN)*ppv)->AddRef();
return NOERROR;
}
return ResultFromScode(E_NOINTERFACE);
}
STDMETHODIMP_(ULONG) CContainerItem::AddRef(void)
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) CContainerItem::Release(void)
{
if (0L!=--m_cRef)
return m_cRef;
if (NULL!=m_pfnDestroy)
(*m_pfnDestroy)();
delete this;
return 0;
}