home account info subscribe login search My ITKnowledge FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
To access the contents, click the chapter and section titles.

Fast Track Visual C++ 6.0 Programming
(Publisher: John Wiley & Sons, Inc.)
Author(s): Steve Holzner
ISBN: 0471312908
Publication Date: 09/01/98

Bookmark It

Search this book:
 
Previous Table of Contents Next


Chapter 12
COM and OLE

The Component Object Model (COM) is the “object” model on which OLE (Object Linking and Embedding) and ActiveX are based, and we investigate these topics in both Chapter 12 and Chapter 13. COM lets you expose functions and data of objects for other programs to make use of. In this chapter, we look at what support Visual C++ offers us in one major section of COM programming: OLE.

The MFC library includes a good encapsulation of the COM packages for OLE handling, including built-in support for all aspects of COM: interfaces, reference counting, and marshalling. In this chapter, we create both an OLE container program and an OLE server.

Our OLE container program can accept OLE items from OLE servers. For example, we are able to place Microsoft Excel, Microsoft Word, or other OLE items into our container. Our OLE server program acts as a server, creating OLE items that we can insert into containers. We start with our Container program, making use of the MFC library.

Creating a Container

Using AppWizard, create a new SDI program named Container. We include the support AppWizard offers for OLE containers, which it calls “compound document applications,” in Step 3 of AppWizard, in answer to the question “What compound document support would you like to include?” We then select the option button marked Container, as shown in Figure 12.1, and finish creating the application.

There’s already a lot of support for OLE items in the new Container program. The user can select the Insert New Object item in the program’s Edit menu, and the Insert Object box appears, as shown in Figure 12.2. When the user selects an object to insert, such as a Microsoft Excel Worksheet, and clicks OK, that item appears in the container’s view.


Figure 12.1  Creating a Container program with AppWizard.

However, there are a few shortcomings that we have to fix. First, the OLE item appears with a default size, which doesn’t match the actual size set by the OLE server, usually causing the OLE item to be truncated in one or the other dimension. In addition, the OLE item originally appears open for editing, but there is way to close it. We allow the user to click in the view outside the OLE item to close it. When closed, however, there’s no way to open it, so we enable the user to double-click the item to open it.


Figure 12.2  Inserting a new OLE item.

First, we need to set the OLE item’s size. The OLE item is supported in our Container project with a new MFC class, CContainerCntrItem. When OLE items are embedded in our program’s document, they are objects of this class, and we work with that class first to set the item’s size correctly.

The Container Item

To store a size rectangle for the OLE item, we add a CRect object named rect to the CntrItem class’s header.

// CntrItem.h : interface of the CContainerCntrItem class
//
    .
    .
    .
// Attributes
public:
    CContainerDoc* GetDocument()
        { return (CContainerDoc*)COleClientItem::GetDocument(); }
    CContainerView* GetActiveView()
        { return (CContainerView*)COleClientItem::GetActiveView(); }

    CRect rect;                                                    ⇐
        .
        .
        .

We store the dimensions of the OLE item in this rectangle and give it a default size in the CContainerCntrItem class’s constructor in CntrItem.cpp.

CContainerCntrItem::CContainerCntrItem(CContainerDoc* pContainer)
    : COleClientItem(pContainer)
{
    rect.SetRect(10, 10, 100, 100);                                ⇐

}

There are two places we have to update the item’s size in CntrItem.cpp. The first is in OnChangeItemPosition(), which is called if the user changes the size of the item when editing it. The second is in OnGetItemPosition(), which returns the item’s bounding rectangle.

The OnChangeItemPosition() function is called when the item’s position or dimensions have changed, and that function is passed a new bounding rectangle, so we simply store that new rectangle as rect.

BOOL CContainerCntrItem::OnChangeItemPosition(const CRect& rectPos)
{
    ASSERT_VALID(this);

    // During in-place activation CContainerCntrItem::OnChangeItemPosition
    //  is called by the server to change the position of the in-place
    //  window.  Usually, this is a result of the data in the server
    //  document changing such that the extent has changed or as a result
    //  of in-place resizing.
    //
    // The default here is to call the base class, which will call
    //  COleClientItem::SetItemRects to move the item
    //  to the new position.

    if (!COleClientItem::OnChangeItemPosition(rectPos))

        return FALSE;

    // TODO: update any cache you may have of the item's rectangle/extent

    rect = rectPos;                                                ⇐

    return TRUE;

}

In addition, the OnGetItemPosition() function must return the OLE item’s location and size. Currently, that function returns a default size.

void CContainerCntrItem::OnGetItemPosition(CRect& rPosition)
{
    ASSERT_VALID(this);

    // During in-place activation, CContainerCntrItem::OnGetItemPosition
    //  will be called to determine the location of this item.  The default
    //  implementation created from AppWizard simply returns a hard-coded
    //  rectangle.  Usually, this rectangle would reflect the current
    //  position of the item relative to the view used for activation.
    //  You can obtain the view by calling
CContainerCntrItem::GetActiveView.

    // TODO: return correct rectangle (in pixels) in rPosition

    rPosition.SetRect(10, 10, 210, 210);                            ⇐

}

We return the rect rectangle instead.

void CContainerCntrItem::OnGetItemPosition(CRect& rPosition)
{
    ASSERT_VALID(this);

    // During in-place activation, CContainerCntrItem::OnGetItemPosition
    //  will be called to determine the location of this item.  The default
    //  implementation created from AppWizard simply returns a hard-coded
    //  rectangle.  Usually, this rectangle would reflect the current
    //  position of the item relative to the view used for activation.
    //  You can obtain the view by calling
CContainerCntrItem::GetActiveView.

    // TODO: return correct rectangle (in pixels) in rPosition

    //rPosition.SetRect(10, 10, 210, 210);
    rPosition = rect;                                              ⇐

}


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.