
    Ole2Test application

    Copyright 1993 Macromedia, Inc.

    Initial Version:
        J. Paul Kase, 5/23/93


    This shell application demonstrates OLE2 container functionality, 
    including InPlace editing and Drag and Drop, with a minimal C++ 
    implementation.


Functional Description:
    This shell has an extremely simple interface and an extremely limited 
    functionality.  It allows you to add five different types of objects
    to a list of objects that are drawn into the main window.  The five 
    object types are; Text, Rectangle, Ellipse, Embedded & Linked; with the 
    latter two being the only OLE2 objects.  Each new object is placed
    40 pixels down and 40 pixels to the right of the previous object's origin.
    The menu settings are based on the last (topmost) object.  There is
    no concept of selected objects, and objects can not be moved or deleted.

    Regular (non-OLE) objects are from the New menu.

    OLE objects are created by: 
        o Edit Paste menu item (creates either embedded or linked objects)
        o Edit Paste Link menu item
        o Object Insert Object... menu item
        o Dragging from a server application and dropped into the shell

    Also, the topmost object may be copied to the clipboard (in native format 
    only) and pasted as a new object.

    Documents can be saved and retrieved via the File menu.

    The topmost OLE object can be sent a verb, by choosing from the available
    list in the Object Do Verb pullright menu.

    If the Edit verb is chosen and the associated server application supports
    InPlace editing, the shell's frame will yield to the server and InPlace
    activation will occur.  The Object Deactivate menu item is used to dismiss
    the editing session.


Development Environment:
    The source files were compiled with Microsoft C/C++ 7.0, and are also 
    compatible with Visual C++.  The executable file runs under Windows 3.1
    with OLE 2.0 (released version) installed.

    The source code itself is written in C++ and relies on the Large memory
    model (so that the pointers are far by default).

    The OLE2 header files and libraries are taken unmodified from the OLE2
    SDK.  OUTLUI.H and OUTLUI.LIB are found in the \OLE2\SAMP\REL directory.


Code Organization:
    OLE2TEST.CPP contains the WinMain routine and message callback function,
    although the actual smarts of the message parser are in APP.CPP.  There
    is one CApplication for each session (gApplication), that has a pointer
    to its only CDocument.  That one CDocument maintains a list of 
    CDrawnObject's.  CDrawnObject is the base class for the different object
    types.  

    APP.CPP and .HPP describe CApplication, DOC.CPP and .HPP define
    CDocument, and DRAWOBJ.CPP and .HPP deal with the various drawn objects.
    DROP.CPP and .HPP hold the CDropTarget implementation.  IO.CPP and .HPP
    describe the two InputOutput subclasses, FileObject and ClipboardObject.

    The OLE classes are found in the following locations:
        CAppUnknown (IUnknown) is in APP.
        CAppInPlaceSite (IOleInPlaceSite) is in APP.
        CAppInPlaceFrame (IOleInPlaceFrame) is in APP.
        CDocUnknown (IUnknown) is in DOC.
        CDrawnObjectUnknown (IUnknown) is in DRAWOBJ.
        CDrawnObjectOleClientSite (IOleClientSite) is in DRAWOBJ.
        CDrawnObjectAdviseSink (IAdviseSink) is in DRAWOBJ.
        CDropTarget (IDropTarget) is in DROP.

    The methods in these classes typically call a similarly-named method in 
    either the CApplication, CDocument or CDrawnObject class.  Many of these
    methods are not yet implemented, since they seemed to serve little or
    no purpose in this particular application, even though they must be
    defined since almost all of the root class methods are pure virtuals.

    The list of objects attached to the document are in a singly-linked list, 
    in back to front order.

    The clipboard and file I/O code use the same CDrawnObject methods.  This
    is accomplished by first allocating either a ClipboardObject or FileObject
    pointer, then passing that InputOutput * to CDrawnObject::Write (), which
    eventually calls (InputOutput *)::WriteBytes to do the work.

    OLE2TEST is built from roughly 2800 lines of code, which should be
    small enough to read and learn.  I developed it while learning OLE2, 
    so expect some "work in progress" and less-than thorough error
    recovery and other lost indications of production-level coding.  

    Since what I learned in this shell was meant to be transferred to a
    relatively large existing application, it didn't make sense to use
    a compound document file format.  At first there were IMoniker's and
    root IStorage and IPersistFile implementations, but I transitioned to
    using ILockBytes to create stand alone IStorage instances for the
    individual OLE objects.

    I've found C++ to be a much better language for implementing OLE2
    interfaces than C, mainly because of all the things you get for free, 
    such as VTable initialization.

    Feel free to use any or all parts of it in your own application 
    development.


--J. Paul Kase, Macromedia
