Implement the Server Item

AppWizard has done most of the work associated with implementing the server item by providing the COleServerItem-derived class in ScribbleItem.cpp. All you have to do is add the application-specific implementation.

Suggested Reading in the Microsoft Foundation Class Reference

The server item’s OnDraw member function is called when the server document needs to draw itself as an inactive embedded object inside the container window. In contrast, the view’s OnDraw is called when the document is activated in place inside the container. CScribbleItem::OnDraw needs to do essentially the same drawing that CScribbleView::OnDraw does. If your OnDraw code in your view class is complex, you will probably want to reuse that code by having your client item’s OnDraw call a shared draw routine. In Scribble, the CStroke::DrawStroke routine is reused.

Recall that you previously added the AppWizard-generated file, ScribbleItem.cpp, to the project. Now you’ll modify the AppWizard-provided code to support Scribble-specific drawing functions.

To implement the OLE item’s OnDraw function

  1. Use ClassView to jump to CScribbleItem::OnDraw and modify the AppWizard-provided stubbed version of the function so that it looks like the following:
    BOOL CScribbleItem::OnDraw(CDC* pDC, CSize& rSize) 
    {
    CScribbleDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    
    pDC->SetMapMode(MM_ANISOTROPIC);
    CSize sizeDoc = pDoc->GetDocSize();
    sizeDoc.cy = -sizeDoc.cy;
    pDC->SetWindowExt(sizeDoc);
    pDC->SetWindowOrg(0,0);
    
    CTypedPtrList<CObList, CStroke*>& strokeList
    = pDoc->m_strokeList;
    POSITION pos = strokeList.GetHeadPosition();
    while (pos != NULL)
    {
    strokeList.GetNext(pos)->DrawStroke(pDC);
    }
    
    return TRUE;
    }
    

    This code sets the window extent to the size of the document so that when the document is drawn in the in-place window, the drawing will stretch to the size of the window.

    Notice that the above code reverses the sign of the y dimension to reflect the fact that strokes’ positions are maintained in MM_LOENGLISH coordinates by using negative y coordinates.

  2. Similarly, use ClassView to jump to the AppWizard-provided version of CScribbleItem::OnGetExtent and modify it as follows:
    BOOL CScribbleItem::OnGetExtent(DVASPECT dwDrawAspect, CSize& rSize)
    {
    // This implementation of CScribbleItem::OnGetExtent only handles
    // the "content" aspect indicated by DVASPECT_CONTENT.
    
    if (dwDrawAspect != DVASPECT_CONTENT)
    return COleServerItem::OnGetExtent(dwDrawAspect, rSize);
    
    // CScribbleItem::OnGetExtent is called to get the extent in
    //  HIMETRIC units of the entire item.  The default 
    //  implementation here simply returns a hard-coded 
    //  number of units.
    CScribbleDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    
    rSize = pDoc->GetDocSize();
    CClientDC dc(NULL);
    
    // use a mapping mode based on logical units
    //    (we can't use MM_LOENGLISH because MM_LOENGLISH uses 
    //    physical inches)
    dc.SetMapMode(MM_ANISOTROPIC);
    dc.SetViewportExt(dc.GetDeviceCaps(LOGPIXELSX),             
    dc.GetDeviceCaps(LOGPIXELSY));
    dc.SetWindowExt(100, -100);
    dc.LPtoHIMETRIC(&rSize);    
    
    return TRUE;
    }
    
  3. Save ScribbleItem.cpp.

The framework calls the virtual COleServerItem::OnGetExtent member function when the item needs to set the viewport and window extents of the server item window when the item is in-place active. The new code modifies the original code provided by AppWizard, which sets the size of the server item to an arbitrary fixed value. The function must return the size of the server item in HIMETRIC units. In Scribble, the server item must return the size of the document. Scribble stores the drawing size in physical MM_LOENGLISH units. For reasons explained in the next topic, Scribble needs to convert the drawing size to HIMETRIC units based on its logical MM_LOENGLISH size rather than physical MM_LOENGLISH size.