Besides building on OLE Documents, OLE Controls adds more behavior to existing compound document functionality. First, a control container should implement IOleClientSite::RequestNewObjectLayout. In OLE Controls, a control that is only loaded or running uses this member function to tell the container that it wants to change its size, as opposed to using IOleInPlaceSite::OnPosRectChange, which works only for in-place–active objects. Inside RequestNewObjectLayout, the control container should get the new size by calling the control's IOleObject::GetExtent and pass it back to the control when convenient through IOleInPlaceObject::SetObjectRects.
Second, OLE Controls defines the verb OLEIVERB_PROPERTIES, which tells a control to display its own property pages through IOleObject::DoVerb. Typically, a control will show a Properties item on its verb menu as well. In doing so, an OLE control that can be inserted into a standard OLE Documents container (one that does not understand controls at all) gives the user access to those property pages without any modification to the container itself. Such controls usually display their property pages when handling OLEIVERB_PRIMARY as well. In this way, activating a control from a noncontrol container still gives the user plenty of useful functionality, even if the container doesn't handle the control's events.
The other addition to OLE Documents is a set of control-specific MiscStatus flags that contain status information. Objects store this information in the registry; the information is returned by IOleObject::GetMiscStatus. Besides usually specifying OLEMISC_ACTIVATEWHENVISIBLE, a control can include any of the flags described in Table 24-2.
MiscStatus Flag | Description |
OLEMISC_INVISIBLEATRUNTIME | Indicates that the control has no run-time user interface but that it should be visible at design time. For example, a timer control that fires a specific event periodically would not show itself at run time, but it needs a design-time user interface so that a form designer can set the event period and other such properties. |
OLEMISC_ALWAYSRUN | Tells the container that this control always wants to be running. This means that the container should call OleRun when loading or creating the object. |
OLEMISC_ACTSLIKEBUTTON | Indicates that the control is buttonlike in that it can understand default and cancel properties, as described in "Keyboard Handling, Mnemonics, and ISimpleFrameSite" later in this chapter. |
OLEMISC_ACTSLIKELABEL | Marks the control as a label for whatever control comes after it in the form's ordering. Pressing a mnemonic key for a label control activates the control after it. |
OLEMISC_NOUIACTIVATE | Indicates that the control has no UI-active state, meaning that it requires no in-place tools, no shared menu, and no accelerators. It also means that the control never needs the focus. |
OLEMISC_ALIGNABLE | Indicates that the control understands alignment properties such as left, center, and right. |
OLEMISC_SIMPLEFRAME | Indicates that the control is a simple grouping of other controls and does little more than pass Windows messages to the control container managing the form. Controls of this sort require the implementation of ISimpleFrameSite on the container's site. |
OLEMISC_SETCLIENTSITEFIRST | Indicates that the control wants to use IOleObject::SetClientSite as its initialization function, even before a call such as IPersistStreamInit::InitNew or IPersistStorage::InitNew. This allows the control to access a container's ambient properties before loading information from persistent storage.* |
OLEMISC_IMEMODE | Marks the control as an Input Method Editor (IME). You can use an IME to enter information in large Asian character sets with a regular keyboard. A Japanese IME, for example, allows you to type a word such as "sushi," and when you hit the spacebar, the control converts that word to appropriate kanji or proposes possible choices. Containers sensitive to Asian languages use this bit to communicate IME-specific properties such as font and pop-up–window placement. |
Table 24-2
Control-specific MiscStatus bits.
* At the time of writing, this bit was difficult to support from a container's perspective because neither OleCreate (and all variations), OleLoad, nor OleLoadFromStream currently understand this bit, and OleLoadFromStream doesn't understand IPersistStreamInit. Therefore, a container has to emulate the exact behavior of these functions to correctly handle this bit. However, the internal working of such functions is not documented, so this is difficult to do correctly. I hope Microsoft will soon update these functions in order to handle OLE controls more robustly or document their exact internal steps.
We'll see how some of these bits are used in the sections ahead.