Step Five: Implement the IUnknown Interface

Both the IFileViewer and the IPersistFile interfaces implement the standard IUnknown interface. This is a snap once you know what to do. By using the macros in the preceding code, you create an embedded class through the local name (FileViewer and PersistFile), with an uppercase X prepended to the name (XFileViewer and XPersistFile). This means that the embedded class for FileViewer is XFileViewer.

Another macro that I use liberally is METHOD_PROLOGUE, which lets you access the parent—the CCmdTarget derived class, CFileViewer—through a special pointer, pThis. The AddRef, Release, and QueryInterface functions can delegate to the CCmdTarget implementation through a call to ExternalAddRef, ExternalRelease, and ExternalQueryInterface, respectively.

// IUnknown for IFileViewer
STDMETHODIMP CFileView::XFileViewer::QueryInterface (
REFIID riid, void **ppv)
{
METHOD_PROLOGUE (CFileView, FileViewer);
TRACE ("CFileView::IFileViewer::QueryInterface\n");
return pThis->ExternalQueryInterface (&riid, ppv);
}

STDMETHODIMP_(ULONG) CFileView::XFileViewer::AddRef (void)
{
METHOD_PROLOGUE (CFileView, FileViewer);
return pThis->ExternalAddRef ();
}

STDMETHODIMP_(ULONG) CFileView::XFileViewer::Release (void)
{
METHOD_PROLOGUE (CFileView, FileViewer);
return pThis->ExternalRelease ();
}