Coordinating with Server to Determine Size of Object

The following exercise demonstrates why Container needs to coordinate better with servers to determine the size of embedded objects.

To demonstrate why coordinating with the server is necessary

  1. If you have not already run the HIERSVR sample, do so now. Run HIERSVR once to register this OLE component application and then close it.

  2. Similarly, run Step 1 of Container, but leave it running. (You can either use your version, or the sample source version.)

  3. On the Container Edit menu, click Insert New Object.

  4. Select MFC Hierarchy List as the object type.

    Notice that the initial size of the HIERSVR object is (10, 10, 50, 50), as determined by the CContainerItem constructor. Container does not give HIERSVR the opportunity to set the initial size of the object.

  5. From HIERSVR’s Edit menu, click Add Node to add a second node.

    Fill in a name for the node; the other options in the Add Node dialog box don’t matter for the purpose of this demonstration.

    Notice that Container correctly increases the height of the object to accommodate the new node. You can add more nodes, and Container continues to increase the height of the object. In Step 1, the implementation of CContainerItem::OnChangeItemPosition changes the height of the in-place activated object at the request of HIERSVR.

  6. Deactivate the HIERSVR object, then click once to select it.

  7. From the Edit menu, click Hierarchy List Object, then click Open from the submenu.

    This fully opens the HIERSVR server application. Arrange HIERSVR and Container on the screen so you can see both applications at once.

  8. In HIERSVR, from the Edit menu click Add Node to add another node.

    Notice that the size of the object in Container does not change to accommodate the new node. Rather, it stays the same size and compresses the nodes using a smaller font, so that the N+1 nodes now occupy the same space as the original N nodes. Add more nodes, and they become more and more compressed in the same space in the container.

  9. Close both applications.

Why does OnChangeItemPosition change the size of the in-place window when a new HIERSVR node is added, but not if it is being updated when HIERSVR is running fully opened?

Because OnChangeItemPosition is called by the framework only when the object is in-place activated. The server temporarily provides the object with its own in-place window and calls to give the container a chance to customize the size of the in-place window.

When the server is fully opened, the situation is much different (although it appears to be the same): When the server is fully opened, the object in the container is selected but not activated in place. When the user edits the fully opened object so that its natural size changes, as in the case of adding a node in HIERSVR, the server indirectly (through the framework) calls CContainerItem::OnChange instead of OnChangeItemPosition. At this time, Container needs to find out the new natural size of the object from HIERSVR. It does this by calling COleClientItem::GetCachedExtent.

COleClientItem::GetCachedExtent asks the server for the natural extent of the object. The natural extent is the size of the object as it would appear on the printed page (in MM_HIMETRIC units). In HIERSVR’s case, the natural extent reflects (1) the font size that the user can specify with the Change Font command on the Tree menu, and (2) the number of nodes in the HIERSVR object.

The CContainerItem::OnChange function is not the only place where Container needs to call COleClientItem::GetCachedExtent to get the natural extent of the object and then set the m_rect of the CContainerItem. Therefore, you will implement the helper function UpdateFromServerExtent as described in the next topic, Get the Extent of the CContainerItem Object from the Server.