Implement Skeletal In-Place Interfaces and Object Helper Functions

In-place activation for a server generally affects only the object in question, leaving most of the rest of the server unaffected. Cosmo's embedded object is implemented in CFigure. To this we need to add the IOleInPlaceObject interface (IIPOBJ.CPP) and provide an implementation of IOleInPlaceActiveObject (IIPAOBJ.CPP). We'll implement the latter as part of CFigure as well, but its QueryInterface is hobbled so as not to respond to any interface but itself. I've included this interface with CFigure because most of what we need to do in it concerns the object. But we could have implemented it with a separate object altogether.

At this point, it is useful to start implementing a set of centralized functions to do most of the work involved with in-place activation. For this reason, I've added a number of internal (but public in C++) member functions to CFigure that will be called from the in-place interfaces:


class CFigure : public IUnknown
{
§

public:
§

HRESULT InPlaceActivate(LPOLECLIENTSITE, BOOL);
void InPlaceDeactivate(void);
HRESULT UIActivate(void);
void UIDeactivate(void);
BOOL InPlaceMenuCreate(void);
BOOL InPlaceMenuDestroy(void);
BOOL InPlaceToolsCreate(void);
BOOL InPlaceToolsDestroy(void);
BOOL InPlaceToolsRenegotiate(void);

void OpenIntoWindow(void);
BOOL Undo(void);
}

InPlaceDeactivate and UIDeactivate will contain the same code we need in the IOleInPlaceObject functions of the same name, so we can have the interface simply call CFigure directly:


STDMETHODIMP CImpIOleInPlaceObject::InPlaceDeactivate(void)
{
m_pObj->InPlaceDeactivate();
return NOERROR;
}

STDMETHODIMP CImpIOleInPlaceObject::UIDeactivate(void)
{
m_pObj->UIDeactivate();
return NOERROR;
}

Why bother with these and functions such as CFigure::InPlaceActivate? The reason is that we might need to call them from multiple locations—for example, IOleObject::DoVerb and IOleInPlaceObject::ReactivateAndUndo. In Cosmo, CFigure has more access to the rest of the application than the interface implementations themselves, so we end up with cleaner code in the bargain. Also, InPlaceActivate is the only function that takes any arguments—an IOleClientSite pointer (generally the one passed to IOleObject::DoVerb) and a BOOL flag indicating that we want to activate the UI as well.