Linking to Embeddings: Patron

To name an embedded object within a page in a document, this chapter's version of Patron (CHAP21\PATRON) uses a File!Item!Item moniker. The File is the document filename, the first Item is the page name, and the second Item is the tenant name. As a source for this kind of moniker, Patron enables other containers to link to embedded objects within a compound document.

In the Link Source sample in Chapter 9, we demonstrated how to bind File!Item and File!Item!Item monikers in which the item monikers contained the names of elements within the source's compound file. Because Patron's file structure is almost the same, much of the code for IPersistFile and the two necessary IOleItemContainer implementations is quite similar to the code in Link Source. In Patron, the page name has the form "Page n," which corresponds to the name of the page's storage element in the file. The tenant name has the form "Tenant n." This identifies the tenant's storage element, in which an embedded object resides.

To this end, Patron now implements a class factory for its document objects (in ICLASSF.CPP) and implements both IPersistFile (IPERFILE.CPP) and IOleItemContainer (IOLECONT.CPP) interfaces on that document object. Patron already writes its CLSID into its documents, so finding the CLSID associated with the name in the file moniker isn't a problem. Patron's Page objects (PAGE.CPP) also now implement IOleItemContainer, sharing most of the code with the document's version of this interface, just as we did for Link Source many moons ago.

Because we've seen most of this sort of code already, the following sections highlight those areas of specific concern for a linking to embedding container. First we have to create and manage the monikers that name the embeddings as well as the document and the page. Doing this includes registering the monikers in the running object table. Then, whenever we copy an embedded object (one that does not have OLEMISC_CANTLINKINSIDE) to the clipboard or in a drag and drop, we have to include the moniker in CFSTR_LINKSOURCE data as well. Once another container creates a linked object with this moniker, our problem is mostly one of binding support.