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 parentthe CCmdTarget derived class, CFileViewerthrough 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 ();
}