Create, Register, and Revoke a File Moniker

Cosmo manages its file moniker in the m_pMoniker variable of its CCosmoDoc class. It creates and registers this moniker only when it has a known filename for the document itself. A new, untitled document is not registered as running. When you load a file with a known name or save a file, Cosmo ends up in CCosmoDoc::Rename. Here we revoke and release any old moniker and then create and register a new one for the new filename:


void CCosmoDoc::Rename(LPTSTR pszFile)
{
LPMONIKER pmk;

//We don't need to change base class, just augment....
CDocument::Rename(pszFile);

//Unregister old moniker (m_dwRegROT set to 0).
INOLE_RevokeAsRunning(&m_dwRegROT);

ReleaseInterface(m_pMoniker);

if (NULL!=pszFile)
{
CreateFileMoniker(pszFile, &pmk);

if (NULL!=pmk)
{
m_pMoniker=pmk; //pmk AddRef'd in CreateFileMoniker
INOLE_RegisterAsRunning(m_pFigure, m_pMoniker
, 0, &m_dwRegROT);

m_pFigure->SendAdvise(OBJECTCODE_RENAMED);
}
}

return;
}

The helper functions from INOLE.DLL, INOLE_RegisterAsRunning and INOLE_RevokeAsRunning, are wrappers for calls to IRunningObjectTable. (See INOLE\HELPERS.CPP.) A side effect of INOLE_RevokeAsRunning is that it sets our registration key to 0 to indicate a successful revoke. INOLE_RegisterAsRunning will actually call INOLE_RevokeAsRunning for us if m_dwRegROT is nonzero when we make the call. I'm not using this feature here; I want to show the steps explicitly.

When we change the name of the running object in this way, we have to advise any linked objects connected to this source that the name has changed. This is the purpose of calling IAdviseSink::OnRename. Containers themselves don't care about this notification, but the linking handler does. It uses the notification to inform the container of changes to the source.

Anyway, Cosmo sends this notification through IOleAdviseHolder::SendOnRename, passing the new moniker, which gets forwarded to the necessary advise sinks:


//In CFigure::SendAdvise, FIGURE.CPP
case OBJECTCODE_RENAMED:
m_pMoniker=m_pDoc->m_pMoniker; //For IOleObject::GetMoniker
m_dwRegROT=m_pDoc->m_dwRegROT;

if (NULL!=m_pIOleAdviseHolder)
m_pIOleAdviseHolder->SendOnRename(m_pMoniker);

break;

In response to this, the linking handlers will update their internal monikers so that the link remains intact.