Round Out IOleClientSite

We need two more pieces of implementation before we can call a linking to embedding container complete. Remember IOleClientSite::GetContainer? When a container supports linking to the objects in its document, this function must return the IOleContainer interface for the immediate container of the objects themselves. In Patron's case, this is the IOleItemContainer interface on the page object—remember that IOleItemContainer is derived from IOleContainer. Patron's implementation of IOleClientSite::GetContainer does the following:


STDMETHODIMP CImpIOleClientSite::GetContainer(LPOLECONTAINER FAR
*ppContainer)
{
PCPage pPage;

*ppContainer=NULL;

m_pTen->m_pPG->IPageGetFromID((DWORD)-1, &pPage, FALSE);

if (NULL!=pPage)
{
return pPage->QueryInterface(IID_IOleItemContainer
, (PPVOID)ppContainer);
}

return ResultFromScode(E_FAIL);
}

The function CPages::IPageGetFromID conveniently returns to us the current CPage pointer, through which we can call QueryInterface.

The other change we must make is a modification to IOleClientSite::ShowObject. In Chapters 17 and 20, this container function was responsible only for bringing the object into view. Because Patron can now be launched with -Embedding on the command line, the main window might not be visible. Thus, to truly show the object, ShowObject must now also make the frame window visible:


STDMETHODIMP CImpIOleClientSite::ShowObject(void)
{
HWND hWnd, hWndT;

m_pTen->ShowYourself();

//For linking to embeddings, now show main window.
hWndT=GetParent(m_pTen->m_hWnd);

while (NULL!=hWndT)
{
hWnd=hWndT;
hWndT=GetParent(hWnd);
}

ShowWindow(hWnd, SW_SHOWNOACTIVATE);
return NOERROR;
}

The use of SW_SHOWNOACTIVATE in the ShowWindow call means that Patron will not be brought to the foreground when we show the main window. This prevents Patron from obscuring the linking container that the user is working in. We want to make the intermediate container visible but not obnoxious.

A final note about containers and linking to embeddings is that unbeknownst to the container, OLE will establish advises between the other linking container and the embedded object in the running server. When you make a change to the object in the server, you will see the object change in both containers, as a user would expect. What appears to be happening is that the user makes a change to the embedded object, and that change is reflected in the immediate container. This amounts to a change to the object in the container that the second container is linked to, so the change is also reflected in the second container. But the immediate container doesn't have to do anything to make this happen: OLE will automatically connect the embedded object to the linked object in the second container.