Notes on Patron as a Partial OLE Control Container

As an in-place–capable container for OLE Documents, the Patron sample from Chapter 22 is already well on its way to becoming an OLE control container. For this chapter's sample (CHAP24\PATRON), we'll try adding some control-related features to demonstrate a number of the concepts we've been describing. As elsewhere in our work with OLE Documents, implementing container features involves a good deal of user interface. Supporting OLE Controls is no exception.

Let me state again that Patron is not a complete control container by any stretch of the imagination. Patron merely demonstrates some of the techniques involved while leaving others unsupported. This sample doesn't implement any Tab key handling or tab order support, nor does it implement ISimpleFrameSite. It also does not handle default and cancel buttons, exclusive buttons, or labels. It doesn't have any way to call a control's methods or to manipulate its properties. Patron does not implement IPropertyNotifySink, demonstrate extended controls, provide a user interface for self-registering controls, use a control's toolbox bitmap, or deal at all with licensing issues. And finally, Patron ignores OLEMISC_SETCLIENTSITEFIRST and works only with controls that implement IPersistStorage and those marked "Insertable."

This last point deserves some clarification—Patron doesn't supply its own Insert Control dialog box, which normally would be populated with those objects marked with "Control" in the registry. Instead, it relies on the Insert Object dialog box we've used since Chapter 17. Therefore, Patron works only with controls marked "Insertable" and those that use the storage-based persistence model. If you'd like to play around with a control in Patron, you'll have to manually add the Insertable key and see what happens.

So does Patron do anything? What's left to demonstrate? Well, we still have a number of important pieces of a container—event handling, ambient properties, and keyboard mnemonics. The following list describes those parts of the OLE Controls technology that are demonstrated in this sample:

Patron best demonstrates the handling of an arbitrary event set. To display the dialog shown in Figure 24-4 (whose template is in EVENTS.DLG, by the way), we need some list of events and also to maintain a mapping from each event dispID to an action. We also need to implement an IDispatch that works with any event set to execute the action assigned to whatever event comes into IDispatch::Invoke. To receive these events in the first place, we have to find the type information for the event set. The following sections describe how Patron performs these steps.

Figure 24-4.

Patron's Control Events dialog box in which the user can assign actions (system sounds) to individual events. The events shown are those of the Polyline control implemented in this chapter.