Close and Delete Objects

We would quickly fill our hard disks with large compound documents if we could never remove objects from them. So now we must add some way to delete an object from a document. This is similar to, but not exactly the same as, closing an object when the document is being closed and the object still exists—that is, the object moves from the loaded state to the passive state. Deleting an object means taking it from the running or the loaded state to outright nonexistence.

Closing an embedded object requires two actions: ensuring that the object's storage is updated and calling IOleObject::Close. The latter tells the object's local server to completely shut down and purge itself from memory if no other containers are using it. As far as our container is concerned, however, this object is now in the passive state, so we must call OleLoad to bring it back to the loaded state.

IOleObject::Close takes one argument—the Save option—which instructs the object how to proceed. OLECLOSE_SAVEIFDIRTY tells the object to call IOleClientSite::SaveObject if it's dirty before closing. OLECLOSE_NOSAVE simply closes the object regardless of its dirty state. OLECLOSE_PROMPTSAVE closes the object if it is not dirty; otherwise, it displays a Yes/No/Cancel message box asking the user whether he or she wants to save the object. In this case, Close will return OLE_E_PROMPTSAVECANCELLED to indicate that the user did not want to close the object after all.

Destroying an object (as Patron does when selecting Delete Object from the Edit menu), still involves IOleObject::Close but always with OLECLOSE_NOSAVE. This is in addition to destroying the storage element for this object, which your site manages. Finally, after destroying an object, you should call CoFreeUnusedLibraries as a matter of habit.