The final feature that I want to discuss here is Copy and Cut operations for the currently selected tenant. I will not discuss exactly how I implemented the sizing functionality because that's just a lot of straight Windows programming that's pretty clear from the source code itself. I admit that the sizing code took about three times as long to write and debug as any part of this application that is using OLE, but I don't want to sedate you with the details.
Patron uses the technique developed in Cosmo at the beginning of this chapter. The data for the object is stuffed into one of our data transfer component objects, and it is that object that we put on the clipboard. The Copy and Cut operations start in CPatronDoc::Clip, which simply calls CPages::TenantClip, which then calls the current page's CPage::TenantClip. Inside this last function, the page calls its internal TransferObjectCreate function. TransferObjectCreate places two data formats in the data transfer object. The first is a PATRONOBJECT structure that describes where the object lives on the page. If we paste into a Patron document later, we can use this data to try to put the tenant in the same place that it was in the source. We'll use this as well in Patron's drag-and-drop implementation in the next chapter. In addition to this placement data, we include the graphical presentation we're using for the object in the tenant. A rendering of this graphic is readily available through the object's IDataObject::GetData. Mostly harmless, I would say, and when TransferObjectCreate is finished, CPage::TenantClip calls OleSetClipboard and possibly destroys the selected tenant if we're doing a Cut operation.
Note that I created the separate TransferObjectCreate function because we'll want to use it again when we need a data object as a drag-and-drop source. This is why there's the pptl parameter to TransferObjectCreate, which describes the offset from the top left of the tenant's rectangle, where it was picked up in the drag and drop.