In-Place–Active States vs. UI-Active States

If you look carefully at the interfaces described in the previous two sections, you'll notice that some member functions are given names such as InPlaceActivate while others are named UIActivate. This reflects the fact that in-place activation adds two object states to those we first discussed in Chapter 17. The additional states are in-place active and UI active. The active state we've been describing is the state in which an object's user interface is visible in a separate window. A call to IOleObject::DoVerb with OLEIVERB_SHOW brings an object into this active state. (This is true for any other verb that implies a show operation, such as OLEIVERB_PRIMARY.) In-place activation defines two standard verbs through which a container can tell an object to enter the in-place–active or UI-active state: OLEIVERB_INPLACEACTIVATE and OLEIVERB_UIACTIVATE. The functions IOleInPlaceObject::InPlaceDeactivate and IOleInPlaceObject::UIDeactivate reverse these state transitions, as shown in Figure 22-3.

Figure 22-3.

In-place–active and UI-active state transitions for in-place–capable objects.

When an object is in-place active, it has a window of its own inside the container's document window. This enables the object to respond directly to mouse clicks and control its own rendering. The container also has the object's IOleInPlaceActiveObject pointer. However, an in-place–active object does not have any other user interface available. Only one UI-active object can have its toolbars, menus, and keyboard accelerators active at a given time. When the user clicks the mouse inside an in-place–active object's window, that object becomes the UI-active object. This causes the user interface for the previous UI-active object to be deactivated, but that object's in-place state is not fully deactivated. It remains in-place active if it wants.

In this manner, in-place activation allows a container to manage multiple in-place–active objects at the same time, but only one of them is also UI active. This is perfect for dealing with a form full of elements such as OLE controls; only the control with the keyboard focus needs to be UI active. All others will be in-place active, and a single mouse click on any control will make it the UI-active one.

Objects that support both of these states, which is optional, usually mark themselves as OLEMISC_ACTIVATEWHENVISIBLE. This means that a container should keep those objects in-place active, but not UI active, whenever they are visible to the end user. (This is usually whenever those objects are loaded.) Some of those objects might also be marked OLEMISC_INSIDEOUT, which is a special case that we'll return to later.