December 10 Pre-release version Extensible Application Protocols Object Linking and Embedding Microsoft Corporation One Microsoft Way Redmond WA, 98052 2 December, 1990 Copyright © 1990, Microsoft Corporation Etymological Note, and Acknowledgement The protocol defined in this specification was initiated by Rick Hawes of the Microsoft Applications Graphics Business Unit. Concurrently, a very similar protocol was proposed by Rick Trent of Aldus, called PEZ. This work is a synthesis of the earlier proposals, refined and completed with the help of many people at Microsoft, Lotus, Aldus, and Word Perfect Corp. The original working title of the specification of this protocol was "Linked and Embedded Documents". Following review and comment, the working title was changed to "Extensible Compound Document Architecture" with the intent to convey the nature and purpose of the specification. To avoid confusion with the acronym CDA which is owned by Digital Equipment Corporation, and to convey that the specification defines a protocol between application components, the title was changed to "Compound Document Protocol". Finally, we have decided to return almost to the beginning, and have settled on the current title. User Conceptual Model 8 User Task: Compound Document Management 8 Conceptual Model: Visual Containment and Links 8 Semantic Model 8 Objects 8 Containers 9 Containment 9 Behaviors: editing 9 Presentation: display and printing 9 Dependent objects 9 Operations 10 Move 10 Copy 10 Link 11 Variations 11 Dynamic Objects 11 Voice, sound and animations 11 Actions: executable objects 12 Hypertext and Annotations 12 Client-provided hypertext links 12 Client-provided annotations 12 User Interface 13 Terminology 13 Commands for Embedding and Creating Links 14 Copy 14 Cut 15 Paste 15 Paste Link 15 Insert New Object 15 Paste Special 16 Presentation in Containers 16 Normal Display 16 Section Boundaries 16 Selection Behavior 17 Editing in Containers 17 Opening 17 Operations in Containers 17 Displaying Properties 18 Properties Dialogs for Links 19 Properties Dialogs for Embedded Objects 20 Opening Objects 20 Control of Updates for Links 21 Changing Update Rules 21 Updating Presentations 21 "Disconnecting" Links 21 Repairing Broken Links 21 "Freezing" Presentations of Objects 21 Displaying Section Boundaries 22 Undoing Changes to Embedded Objects 22 Operations in Editors 22 Updating Presentations 22 Saving Copies of Objects 22 Returning to Containers 23 Implementor's Guide 24 Introduction 24 Clipboard Conventions 24 Registration 27 Client 27 Protocol Checking 27 Open a Document 27 Save or Close a Document 28 Display and Print 28 Open an Object 29 Change Printer, Resize 29 Cut and Copy 29 Paste 29 Paste Link 30 Undo 30 Links 30 Properties 31 Shutdown 31 Server 31 Opening 31 Shutdown 31 Copy 32 Save a Copy 32 Update 32 Exit, Close 32 Renaming a Document 32 Installation of Classes 32 API specification 33 Introduction and general definitions 33 Client API specification 33 Types, Data structures and parameter definitions 33 ECDSTATUS 34 Structures provided by the library for the client 34 ECDOBJECT, LPECDOBJECT 34 Structures provided by the client for the library 34 ECD_NOTIFICATION 35 ECDCLIENT, LPECDCLIENT 35 ECDCLIENT: CallBack 35 ECDSTREAM, LPECDSTREAM 36 ECDSTREAM: Get 36 ECDSTREAM: Put 37 ECDSTREAM: Seek 37 Protocol naming and checking 37 Rendering Options 37 ECDOPT_RENDER, ECDCLIPFORMAT 38 API functions 38 Utility functions 38 Enabling Paste and Paste link commands 38 EcdQueryCreateFromClip 38 EcdQueryLinkFromClip 39 Executing Paste and Paste link commands 39 EcdCreateFromClip 39 EcdCreateLinkFromClip 39 Copying or cutting an object to the clipboard 39 EcdCopyToClipboard 39 EcdCutToClipboard 40 Load from and Save to client's file 40 EcdLoadFromStream 40 EcdSaveToStream 40 Object creation 41 Creating new objects 41 EcdCreate 41 EcdCreateFromTemplate 41 Creating an object by converting an existing object 41 EcdObjectConvert 41 Copying and comparing objects 42 EcdClone 42 EcdEqual 42 Making a local copy of a linked object 42 EcdCopyFromLink 42 Object method functions 43 Protocol extensibility 43 EcdQueryProtocol 43 Destroying an object 43 EcdDelete 43 Finding the display size of an object 44 EcdQueryBounds 44 Formatting an object 44 EcdSetTargetDevice 44 EcdSetBounds 44 EcdSetHostNames 44 Rendering an object 45 EcdDraw 45 Initializing and retrieving data 45 EcdEnumObjectFormats 46 EcdGetData 46 EcdSetData 46 Repairing broken links 46 Update control 47 ECDOPT_UPDATE 47 EcdGetLinkUpdateOptions 47 EcdSetLinkUpdateOptions 47 Opening and updating 47 EcdOpen 47 EcdQueryOpen 48 EcdUpdate 48 EcdReconnect 48 EcdQueryOutOfDate 48 EcdClose 48 Object handler API specification 49 Overview 49 Object creation and initialization 49 Dll/DefCreateFromClip 49 Dll/DefLoadFromStream 50 Object methods 51 ECDOBJECT, ECDOBJECTVTBL, LPECDOBJECT 52 Object release 53 Server API specification 53 Types, Data structures and parameter definitions 53 Structures provided by the server for the library 53 LHSERVER, LHDOCUMENT 53 API functions and callbacks (methods) 54 Startup and registration 54 EcdRegisterServer 54 Server Methods 54 ECDSERVER, LPECDSERVER 55 ECDSERVER: Open 55 ECDSERVER: Create 56 ECDSERVER: CreateFromTemplate 56 ECDSERVER: Edit 57 ECDSERVER: Exit 57 ECDSERVER: Release 57 Shutdown 58 EcdRevokeServer 58 Document creation 58 EcdRegisterDocument 58 Document methods 59 ECDDOCUMENT, LPECDDOCUMENT 59 ECDDOCUMENT: Save 59 ECDDOCUMENT: Close 59 ECDDOCUMENT: SetHostNames 60 ECDDOCUMENT: SetDocDimensions 60 ECDDOCUMENT: GetObject 60 ECDDOCUMENT: Release 61 Closing documents 61 EcdRevokeDocument 61 Object creation 61 Server Object methods 61 ECDOBJECT: Delete 62 ECDOBJECT: Show 62 ECDOBJECT: GetData 62 ECDOBJECT: SetData 63 ECDOBJECT: SetTargetDevice 63 Object release 63 EcdRevokeObject 63 Notification 64 Registration 64 Appendix: DDE-based protocol specification 66 Launching the Server Application 66 DDE Conventions 66 Conversations 66 Formats 66 System Topic Items 67 Standard Item Names and Notification Control 67 Standard Commands in DDE Execute Strings 69 StdNewDocument(ClassName,DocumentName) 69 StdNewFromTemplate(ClassName,DocumentName,TemplateName ) 69 StdEditDocument(DocumentName) 69 StdOpenDocument(DocumentName) 69 StdCloseDocument(DocumentName) 69 StdSaveDocument(DocumentName) 69 StdShowItem(DocumentName,ItemName [, fTakeFocus] ) 69 StdExit 70 StdCloseDocument 70 StdSaveDocument 70 StdShowItem(ItemName [, fTakeFocus] ) 70 An example: opening an object for editing 70 User Conceptual Model User Task: Compound Document Management The model developed here is designed to support the general task of combining information from numerous sources. More specifically, it is intended to support the creation, and editing of compound documents built from information of various kinds. This requires that multiple application programs be able to cooperate on editing a single document. Conceptual Model: Visual Containment and Links The conceptual model developed here is a simple one: There are things and there are places those things can reside. Things may be moved from one place to another, and may be linked to in other places. They may also be parts of other things. Things have content and a behavior, neither of which depend on the places they are found. Users visualize and manipulate things through their presentations, which are derived from their contents, behaviors, and their relationships to the places they are found. Things in the same place may have entirely different content, behavior, or presentation; users bring them together because they are part of the same task. Semantic Model This section describes the conceptual model in more detail, and presents a more formal definition of its semantics. This model has two basic elements, objects and containers, two fundamental relationships, containment and reference, and three basic operations, move, copy, and link. Objects Objects are the "things" manipulated by the user. A graph, a range of spreadsheet cells, a paragraph in a document, the current selection in an open window, and an entire document are all potential objects. Each object has two defining features: content and behavior. An object s behavior determines what ac- tions the user can perform on it, how it responds to those actions, and what tools are used to effect those responses. Behavior is what distinguishes objects from simple "data." All objects also have a presentation, which determines how it will appear to the user in a given context. An object s presentation in a place is derived from its content and behavior, subject to constraints im- posed by its relationship to that place. Objects are distinguished from "data" by the possession of behaviors; when they lose them, they cease to be objects. The current implementation of "Paste" in Word, for example, "converts" pasted ranges of spreadsheet cells in just this way. The table that this operation creates in a Word document has lost most of the behavior-dependency, the ability to edit and insert formulae, etc.-of the original cells. What has been pasted is not the original object-a range of cells-nor a copy of the original object, but a new object-a Word table-filled with a copy of the original object s data. On the other hand, graphs created with PowerPoint s "Insert Graph" command, are objects: they retain all of the behavior that they have when they are created in PowerPoint Graph. The user is, in fact, made explicitly aware of this by being returned to Graph each time he attempts to perform any operation affecting the content or behaviors of the graph. Each object has a class that is used to identify what kind of object it is. All objects with the same set of behaviors (e.g. all PowerPoint graphs, all Excel tables) have the same class. Containers Containers are the "places" that hold objects or links to objects. A file folder, for example, is a container for document objects; a PowerPoint slide is a container for a PowerPoint graph. A compound document is the paradigmatic container: it contains numerous objects from many sources and of many different types, that the user has placed in the same container for the purpose of working on them as part of a group of related tasks. Many objects are also containers; they are distinguished from other objects by the containment relationship (see below) that they exhibit with the objects they contain. An object need not act as a container; it may simply refuse to contain any other objects, or just objects of specific types. PowerPoint graphs, for example, though they behave as objects, cannot act as containers for other objects. Whether or not an object acts as a container for another object is one of the behaviors of that object. Most containers are also objects, in the sense that they can be contained, but this is not a requirement. The desktop, for example, is typically treated as a "root" or "high-level" container, that cannot be con- tained in any other containers. Certain kinds of large compound documents or "workspaces" may exhibit similar behavior. Containment At the core of the model developed here is the relationship between objects and their containers. Behaviors: editing The content and behavior of an object are unaffected by its container. A Canvas drawing contained in a Word document, for example, behaves exactly as if it were part of a Canvas document: it retains all of the behaviors of a Canvas drawing, and all of the operations that are legal for such drawings remain le- gal. This is the crucial difference between containment and our current implementations of pasting op- erations: a contained object is conceptually unaltered by its new environment, and all of its behavior is managed by the tools that are associated with its class. Any changes to a contained object are made using the object s (not the container s) tools. In current implementations (e.g., embedded graphs in PowerPoint 2.0) the user is made explicitly aware of this: editing occurs in a window owned by the application representing the contained object s editing tools. While in the container, the object is "shrink-wrapped"; it may be seen, but must be opened in order to modify it. In future implementations, editing may occur in situ using interfaces (editable views) provided by the object but presented in the container. Presentation: display and printing The presentation of a contained object is also determined by the object, but is constrained by its container. In some cases, for example a hypertext link, a container may simply not request any presentation for a contained object, and the object will not be directly visible; instead some marker icon or other indication would be displayed as the handle to activate the link. More often, the object s presentation will be constrained to a region provided by the container. Dependent objects One object may be part of a larger object, such that it has no real meaning independently of the whole. As a result, when such an object is copied (see below) or moved, other parts of the whole may be duplicated or moved with it, and any changes to the behavior (editing) of the object can only take place in the context of the whole, which is exposed to the user when the object is opened. When, for example, a selection (say a summary table) from a spreadsheet is copied, all the portions of the spreadsheet upon which those cells depend are also copied. For simplicity, this will normally mean that the entire spreadsheet is copied even though only a small part is selected and will be visible in the destination container. Operations This model has three fundamental "transfer" operations: move, copy, and link. This operation is always applied to a specific argument, and has two additional operands: a source and a destination. The source contains the argument when the transfer is initiated. After one of these operations is completed, the contents of the source and destination will vary depending on the operation performed. The results of these operations are summarized in the table below, and explained in more detail in the following sections. Form of Transfer Source Destination Move Nothing Argument Copy Argument Duplicate of argument Link Argument Link to argument The argument to one of these operations may be some data managed by the containing document, or it may already be a linked or embedded object managed by some application other than that of the containing document. Thus objects once embedded or linked may be moved to other containers. If the argument is initially data manged by the containing document and it is copied or moved to another type of document, and embedded object will be created. The link operation always creates a link to the selected region of the source document. An object or link is copied (moved) from one place to another using the Copy (Cut) command in the source, followed by a Paste command in the destination. A link to an object is established by using the Copy command followed by Paste Link. (See Parts 2 and 3.) Move When an object or link is moved, it is taken out of the source, and placed in the destination. Note that, as mentioned above, since the object must retain all of its content and behaviors in the destination, and since these may depend on other parts of the source, those may be duplicated, and moved along with the object. If, for example, a range of Excel cells is moved, and if that range has dependencies on other parts of a spreadsheet, those parts of the spreadsheet will be duplicated, and moved along with the selected cells. It is important also to reiterate that the presentation in the destination depends only on the object (not the whole of the source) so that none of these precedent portions of the owner are visible in the destination, except to the extent that they influence the object s presentation through its content or behavior. An object or link (see "Link", below) is moved from one container to another using the Cut and Paste commands. Copy When an object or link is copied, an exact duplicate of that object or link is created in the destination. Note that, as with the move operation, the duplicate must have all of the content and behavior of the original, and since these may depend on its owner, parts of the owner may also be duplicated along with the object. Also, as is the case for moved objects, none of these precedent portions of the owner of the copied object are visible in the destination. An object or link is copied from one container to another using the Copy and Paste commands. Link The link operation creates a link in the destination to the source argument; the object in the source is unaffected. A link behaves as a clone of the object it is a link to. Conceptually, any changes to the behavior or content of an object are immediately reflected in all links to it, in practice, containers may delay the presentation of these changes. Links are subordinate to the objects to which they refer. Because of this difference between objects and links, deletion of a link has no effect on the object it refers to, while deletion of an object makes all links to it invalid. It is up to containers to decide what to do with any invalid links they contain. In a sense, links are a way of sharing objects: an object may exist in only one container, but it may be shared with other containers by placing links to it in those containers. A link to a part of one container is created in another using the Copy and Paste Link commands. Variations The basic functionality described above covers cases where the object is visually contained in the client document, whether it is embedded or linked in storage terms. The model allows for cases where the object itself is not visually contained, but may be opened from the container, in analogy to a footnote or reference citation in a document. Similarly, the basic functionality is described in terms of objects with a static visualization which may be edited. The model also allows for dynamic or non-visual objects such as voice annotations or actions which may be invoked. Dynamic Objects Some applications provide a kind of pop-up annotation, where some textual or other material is attached to some element of a document and may be called up on command. There may or may not be additional visual indication of the existence of the annotation. Some objects have annotation-like user interface appearance and behavior. For example, a voice object might be displayed as a small icon, which when double-clicked would cause the voice message to be played. We discuss the nature of the object (voice etc.) separately from the characteristics of annotations in general. Other aspects of annotations include the ability to show some or all annotations, suppress them, show markers where annotations exist etc., and the ability to specify these attributes separately for display and printing. Unless the container provides support for control of annotations (see below) dynamic objects will appear in the printed form just as they do in the displayed form. Voice, sound and animations When a time-varying object is created by (e.g.) recording a spoken utterance, or constructing a script with an animation editor, the result can be copied or linked into a container document. The creator should provide a static visualization that will be inserted into the container at the insertion point. This visualization might be small in the case of non-visual objects like voice, or a full-size picture if the animation is visual. The user can open the object, in which case the animation should be run (thus playing the voice message, or running the animation or live-action video in place or in a pop-up window). As an example consider adding a voice annotation to a word processor document that does not understand voice. The user would activate the recorder (perhaps simply by switching on a microphone) and say his piece. The recorder tool would construct a voice object with an icon (say a pair of lips) as its visualization, and put it on the clipboard. The user would return to the word processor, and simply Paste the voice object into the current insertion point. Handwritten annotation could work identically except perhaps in how the recorder is started: the user may have to click on a freehand tool or otherwise indicate that his input is to be recorded as strokes rather than recognized as text. If the user wishes to modify the object rather than play it, there are two means at his disposal. First is simply to create a new object and replace the first, which is suitable for recording a new voice message but not for re-scripting a major motion picture. The second method is to open the object, stop playing and activate the editing commands. Actions: executable objects Executable objects such as macro scripts are much the same as animated objects in their creation and visualization except that once execution has started it cannot be undone. A suitable visualization for an action would be a button labelled with a creator-defined name. The editor for the macro script would supply this visualization when the object is copied or linked into the container, using the normal mechanisms. Actions would not execute when opened from the container; instead a button click is required to start execution. Editing the action would be supported simply by activating the editing commands instead of the execute button. Hypertext and Annotations A hypertext link is represented as a small sensitive element in the container document which the user can open to show the linked object. Clearly, if the server has a small element that can be selected and linked, this appearance can be achieved with normal links. Otherwise, links which do not require the full picture of the linked object can be provided without requiring support in either client or server, beyond the functionality required for linked and embedded objects. We will provide an example object type that acts as the intermediary between client and server. It behaves (to the client) as a normal embedded object, and gives as its visualization a small picture. This object acts as a client to the target of the link. It encapsulates the link and substitutes the alternative visualization. The object interprets the "open" action to mean open the linked object, thus giving the look and feel of a simple hypertext-like link. The look and feel of the intermediaryobject and its editor will be specified separately from this document. Client-provided hypertext links The other case of hypertext link is where the sensitive element is part of the container's data, such as a keyword in text, or a drawing element in a picture. In this second case, a the container must provide a Create Link command to attach the link to the selection instead of inserting the visualization of the linked object into the container. The container must have ways to allow the user to activate the link and to edit the data to which it is attached. Typically, containers will have views in which the structure of the data is exposed and can be edited, such as a formula bar or a field codes view. This view should be used to edit the data that is attached to the link, and should also permit the user to change a visual link to a hypertext link and vice versa. The normal view should interpret input actions as related to the link rather than the data, so that clicking on a word would open the linked object. Client-provided annotations Annotations are pieces of information associated with but not an intrinsic part of a document. Annotations may be suppressed or shown when printing and displaying the document. The content of the annotation may be shown, or a hypertext-like indication that an annotation exists and can be opened. Annotations should be able to hold any kind of information, just as the main body of the document can. Examples of annotations are hidden text, footnotes, side notes, end notes, voice annotations with an icon in the document, handwritten notes on a pop-up post-it note etc. Annotations of this kind must be managed by the container, in that it provides the user with the ability to create annotations, show/hide them on printer/display independently, move information between the main body and the annotation etc. User Interface The user interface described here is not definitive. This specification is preliminary, and will be superceded by a separate user interface specification document. The latter document will specify the user interface that will be implemented by Microsoft products and which is recommended for all Windows applications, in the interests of consistency. Terminology This document will be clearer to the reader if the following use of terminology is understood. When an object is put on the clipboard, it is represented by two formats, Native which contains the native data for the object, and OwnerLink, which describes the class of the object and identifies the part of the object that is to be displayed in the container. When a link is being copied or moved out of a container, it is represented just by the OwnerLink format. When a new link is being created (with the Paste Link command), the ObjectLink format is used. In all cases, if a class-specific rendering DLL is not available, some presentation format (Picture etc) will also be taken from the clipboard by the client library. When describing behavior in the client application or library, the term object, unless qualified, refers to either an embedded object or a link. Client A document that is a container of objects managed by other applications, or the application that manages such documents. The term container is also used where the usage is clear. Server An application that provides editing and rendering services to clients for linked or embedded objects. Source The document (and application) that provides data in a transfer operation; this will be the application where a Cut or Copy command is invoked. Destination The document (and application) that receives data in a transfer operation; the site of the paste command (or a variant). Owner The server for a linked or embedded object. This may be different from both source and destination in the case where an object is selected and transferred. Presentation Data sent from the server to the client so that the client can display and print the object in the containing document. Native The data that completely defines the object, whose format and interpretation is known only to the server (owner). This data is transferred between client and server in the case of embedded objects, where the client provides permanent storage (within the container document) and the server provides editing. Link A link between a container and another document. The linked object is visible in the container document (either the visualization of the object itself, or some other indication), and can be opened for editing, but is stored in another document. This term is also used to refer to the existing Link format transferred through DDE and the clipboard. ObjectLink A DDE and clipboard format carrying a descriptor for the source object. It is used to identify the class, document, and item that is the source of data for a linked object. An ObjectLink is represented internally as three null-terminated strings followed by a null string (i.e. a null character). OwnerLink A DDE and clipboard format carrying a descriptor for the owner of a linked or embedded object. This has the same representation as ObjectLink, and is used to communicate information about the owner of an object, which may be distinct from the source. ClassName Identifies the type of an object. This is used to identify the editor to be in- voked. DocumentName Identifies the object itself. For linked objects, this is the pathname of the file containing the object. For embedded objects, the DocumentName is only used when opening the editor, and is a name manufactured by the client to guarantee uniqueness of access to the server. ItemName Identifies the portion of the server document that is the object. The Item- Name is manufactured by the server and passed to the client as an uninterpreted identifier for latter use. The server must ensure persistence of the mapping from this identifier to the object. Commands for Embedding and Creating Links Applications support the embedding of objects and the creation of links through four commands (Cut, Copy, Paste and Paste Link) on their "Edit" menus. In addition there are two optional commands, Insert new Object, and Paste Special. Copy The "Edit-Copy" and command is used to transfer data, objects, and links out of documents. It places a copy of the selected item on the clipboard, and "marks" the current selection for subsequent use in paste-link operations. The Copy command offers formats to the clipboard in three groups: The first group consists of data formats that adequately describe the selection, ordered by the fidelity with which they describe it (most preferable is offered first-e.g., Word would offer RTF, then CF_TEXT); the second group consists of a complete, encapsulated description of the selection that can be used to create an embedded object in the destination container (expressed in Native and OwnerLink formats); and, the third group consists of presentation formats (minimally CF_METAFILEPICT) and other formats into which the selection can be rendered. It is not possible to link to an embedded object, only to its container; embedded objects are private to their containers. If the source can be a server for links and is not an open embedded object, it will also offer ObjectLink format, and Link format if compatibility with existing links is desired. The following table summarizes the ordering of formats placed on the clipboard by the copy command: Group Examples Descriptive Formats XLC, BIFF, RTF, CF_TEXT Encapsulated Object Native, OwnerLink Presentation Formats CF_METAFILE, CF_TEXT, RTF Mark ObjectLink, Link Note that the same format may be used in different groups under different circumstances (described in more detail in Part 3), but that any given format should only be listed once on the clipboard. Cut The "Edit-Cut" and command behaves exactly like the copy command, except that it never places Link on the clipboard. Otherwise, all of the rules described above for the copy command apply. Paste The "Edit-Paste" command pastes the object, data, or link on the clipboard at the current insertion point. If data is on the clipboard then the data is converted into a native data type of the container as it is pasted; if an object is on the clipboard it is embedded in the container; if a link is on the clipboard it is used to create a link in the container. The Paste enumerates the formats available on the clipboard in order, and takes the first format that is compatible with the target for the Paste command. If no suitable data format is found, a compound document client will make an embedded object from the Native and OwnerLink formats, and enumerate further formats to find and obtain a format for presentation. The destination application may have different preferences for formats depending on where the selection is in the destination document (e.g. pasting into a picture frame vs. pasting into a stream of text). After the paste operation is completed, containers should select the newly pasted item, unless the item has been converted to a container-native type. This behavior, though not widely implemented in existing applications, helps users gain quick access to the properties of a newly embedded or linked object. Paste Link The "Edit-Paste Link" command creates a link, at the current insertion point, to the item "marked" by the previous copy operation. This command should be disabled if link information is not available on the clipboard. The paste-link command behaves like the paste command in its enumeration and selection of data and presentation formats, but first checks for the existence of the ObjectLink format, and ignores the Native and OwnerLink formats. If ObjectLink and a useful format are found, the destination application uses them to create a link at the current insertion point. If ObjectLink is not found on the clipboard then the destination may look for a Link, to handle links to existing (non-object) applications. As with the paste operation, containers should select the new link. Insert New Object New objects are created in containers using the "Insert New Object..." command on the Edit menu, or alternatively a "New Object..." command on an Insert menu if the application has one. This command is not a required part of the user interface for compound documents, since the user can always create objects with the editor or copy an existing object, and embed the result into the container. Some applications may nevertheless wish to provide such a command, if for example it is a common scenario that they wish to accelerate. In that case, the user interface described here should be used. This command opens a modal dialog as shown below. The listbox is filled with the names of types of objects that support the required protocol. This list is obtained from the system registration service (see Implementor's Guide). If the user selects a typename the container application will launch the editor for the type. The editor creates a new blank object. This new object is inserted in the container the first time the user updates from the editor. Once the first update is completed, editing proceeds as for a normal embedded object. Insert New Object dialog Paste Special To be supplied Presentation in Containers Normal Display During normal display of an object (e.g., screen display and printing) only the object itself is visible. The user is not aware of any precedent parts of the object. The object s container determines the region in which the presentation is to be displayed; the presentation itself is provided by its owner. Similarly, during normal display of a link only the linked item is visible. The user does not see any other parts of the linked item s source. The link s container determines the region in which the presentation is to be displayed; the presentation is provided by its source. Section Boundaries Each object or link may have a three-pixel thick section boundary added to its presentation by its container. These boundaries are used to identify and manipulate the components of a compound document. They immediately circumscribe an item s presentation, and take one of two forms: PC VGA PC Other Macintosh Gray 50% gray pattern Concentric lines: 50% gray, white, 50% gray Boundaries are applied to an object or link whenever it is part of the current selection. Container applications may provide modes where section boundaries are displayed for all objects. Clicking on a visible boundary selects the entire object or link it circumscribes. In all other circumstances, section boundaries are absent. Selection Behavior Aside from the special result of selecting a section by clicking on its boundary, the selection behavior of objects and links is based entirely on their presentation. Containers should, however, prevent users from selecting items that they cannot edit in the container. Editing in Containers The container may allow the user to change any aspect of the presentation of an embedded object or link that is preserved when the presentation is updated to reflect changes to the content object. An attempt to change anything that is not preserved is not allowed. Opening When an object is opened for editing, the application responsible for maintaining its editing tools (its editor) is launched with at least one new window displaying the object. The editing application may present the object in additional views and windows; this is up to the editing application to determine, but should be consistent for each type of object the application edits. The titles for windows opened by an editor should correspond to the name of the object provided by the container. Any precedent portions of the object s owner may also be displayed, and may be directly edited; however, editors should size the initial display of objects so that they present only the object and not the parts of its owner on which it depends. While the editor has a window open for an embedded object, the object s presentation in the container is dimmed or grayed out by the container s application; its object properties dialog becomes unavailable and its container s " Properties..." command (see Displaying Properties, below) is dimmed when it is selected. The container s presentation of the object need not change to reflect changes being made in the object s editor until the user explicitly updates the container s presentation. When a link is opened, the entire document to which it refers is opened and displayed by its editor, with that document s name used in the displaying windows. Applications should display and select the linked portion of the document. Operations in Containers All containers must support a set of operations for all objects or links which they contain. Displaying Properties Applications that support this model must implement an " Properties..." command in their "Edit" menus; selecting this command produces an object properties dialog for the currently selected object or link. If no object or link is selected, the menu item is disabled, and should read "Properties...". Alt-double-clicking on the section boundary of any object or link also produces the object properties dialog for that item. All object properties dialogs have the following general components: Function UI component Description of object Text describing the type, name (if any) and nature (link, embedded object, etc.) of the object. Opening A button that opens the object or link for editing. The properties dialogs for links have the following additional components: Function UI component Select an update rule A flexible list of exclusive options (e.g., pop-up menu) presenting a list of container specific rules for updating the presentation with current information about the linked item s content. Manual updating A button that causes a link s presentation to be immediately updated, regardless of the currently specified update rule. Link repair Edit fields to permit the user to alter the link document name and optionally item name. Unlink from source A button that permanently disconnects a link from the item to which it refers, leaving only the presentation. The properties dialogs for objects have the following additional component: Function UI component Convert to only the presentation A button that freezes the object s presentation in its current state by discarding the native data associated with the object. The effect is to convert the object into the datatype being used for the presentation. In addition to the components listed above, each dialog may have components specific to the container s presentation of the object or link. These additional components appear in designated areas of the dialogs, but the details of their layout and function is determined by the container. In general, however, they should not dismiss the dialog of which they are a part, nor should they cause any changes in the container until the OK button is pressed. The following sections illustrate the behavior and appearance of the object properties dialogs. Properties Dialogs for Links When a link is selected, the " Properties..." command should be enabled as "Link Proper- ties..." and should produce the following link properties dialog: When this dialog appears, the class, item and document fields in the link s description should be filled with the appropriate information supplied by the link information. The latter two fields are made editable to permit users to repair broken links (e.g. because the file was renamed). The "Update" radio buttons should indicate the link s current update rule. Any container-specific controls should be added by expanding the dialog downward. The components of this dialog behave as follows: The Update radio buttons are used to select an update rule. New update rules do not take effect until the dialog is dismissed with the OK or Edit Source button. The Update button updates the link s presentation, but leaves the dialog open to allow the user to cancel the update. If the change can t be cancelled the text of the cancel button should be changed to "Close." The Edit Source button accepts all changes to the update rules and presentation, closes the dialog, and opens the linked item in its editor. The OK button accepts all changes and closes the dialog. The Cancel button cancels all changes and closes the dialog. The Unlink button discards the link information and keeps only the current presentation of the link. The link may not be opened after this operation. Properties Dialogs for Embedded Objects When an embedded object is selected, the " Properties..." command should be enabled, with replaced by the name of the object s class, and should produce a dialog similar to the above, with "Reference to" replaced by "Embedded", and without the Update radio buttons. The Update and Edit buttons retain their meaning. The dialog may contain an additional button labelled "Change to Picture" (or other data type e.g. text), to permit the object to be converted to data that can be manipulated within the container application. Any container-specific controls should be placed in the area beneath the object s description, or added by expanding the dialog downward. The components of this dialog behave as follows: The Edit button accepts all changes to the object s presentation, closes the dialog, and opens the embedded object in its editor. The OK button accepts all changes and closes the dialog. The Cancel button cancels all changes and closes the dialog. The Change to Picture button freezes the object s presentation in its current state by discarding the Native data associated with it, leaving behind only the picture used for the current presentation. This button leaves the dialog open to allow the user to cancel the update, and disables the "Edit" button to indicate that the object is no longer editable. If the change can t be cancelled the text of the cancel button should be changed to "Close." Opening Objects A contained object or link is opened for editing by pressing the edit button in its object properties dialog. It is simply opened (which implies executing the object's default action such as playing a voice message) by double-clicking anywhere on its boundary. Items with atomic presentations may also be opened by double-clicking on any part of the presentation. An attempt to open an object or link fails if its editor or object handler is unavailable; opening a link also fails if the document to which it refers is unavailable. No menu command is provided for these operations. Control of Updates for Links Changing Update Rules The update rules for a contained link may be changed at any time by selecting a new update rule from the list presented in a link s object properties dialog. Containers determine what update rules they support for the links they contain, and may support different update rules for different kinds of links based on the nature of the links (data or presentation link) or on the type of the linked item. Containers also determine what default update rule to assign to a link when it is created. All containers must support "manual" and "automatic" updates, and will typically support the same set of update rules for all links. No menu command is provided for this operation. Updating Presentations The presentation of a link may be updated to reflect the current content of the item to which it refers at any time, regardless of the currently specified update rule, by pressing the update button in the object s properties dialog. Containers should support an undo of this operation through the cancel button in the link properties dialog. No menu command is provided for this operation. "Disconnecting" Links A link may be "disconnected" from the item to which it refers in either of two ways: the link may be either unlinked from, or replaced by, that item. In the first case, all that remains of the link is its presentation, frozen in its state at the time it was unlinked or updated immediately before unlinking; in the second case, the link is replaced by a copy of the linked object, and its presentation is updated. This second case is essentially the same as an automated "Copy" followed by "Paste." Both operations are executed by choosing the appropriate option in the link s unlink dialog. No menu commands are provided for these operations. Repairing Broken Links It is possible for a link to be "broken" by deleting or renaming the document that is the target of the link. The user may repair the link in this case by editing the document name (and optionally item name) in the Link Properties dialog. "Freezing" Presentations of Objects The presentation of an object may be "frozen" in its current state by pressing the "Change to Picture" button in the object s properties dialog. As a result of this operation, the Native and OwnerLink information describing the object are discarded, leaving only its current presentation behind. Depending on the nature of the container and the presentation, this presentation may either be uneditable (e.g., a picture in a word processor) or useful as editable data (e.g., in a picture in a paint or draw application). In any case, the object is no longer editable by its original owner. No menu commands are provided for these operations. Displaying Section Boundaries The section boundaries of all objects and links in a container may be displayed simultaneously by executing a show section boundaries command. This command may be implemented differently, if at all, by different applications. Typically it should be implemented as part of any existing commands that show document structure and should thus not require a new menu command. Undoing Changes to Embedded Objects On return from an editor of an embedded object (see "Returning to Containers" below) the container of that object should enable its "Edit-Undo" command. This command should undo the entire editing session for the embedded object; executing this command restores the embedded object to its state when it was last opened for editing, and discards all changes made in its editor. Note that as a consequence of this behavior, returning to a container from an embedded object s editor commits the previous operation in its container-which need not have been opening the embedded object-in applications that support only a single level of "undo." Operations in Editors Applications that act as editors for linked or embedded objects need to make minor modifications to their behavior and user interfaces. Updating Presentations While an application is acting as an editor for an embedded object (i.e., while its active window contains such an object) it should replace its "File-Save" command with "File-Update." Executing this command updates the presentation of the object in the container. When a user closes the main editing window for an embedded object or quits the editing application, he is given an opportunity to update the presentation in the container. While an application is editing a new embedded object-one that was created as the result of an "Insert New..." operation, but which has not yet been inserted in a container-it should replace its "File-Save" command with "File-Insert." Executing this command copies the object to the container, at which point the command is replaced with "File-Update." When a user closes the main editing window for such an object or quits the editing application, he is given an opportunity to insert the object in the container. The "File-Save" command behaves normally for editors of linked objects: it saves the document of which the object is a part, but has no effect on the link in the client container, other than that specified by the link s update rules. Saving Copies of Objects While an application is acting as an editor for an embedded object, it should replace its "File-Save As..." menu item with "File-Save Copy As..." When the user executes this command while an embed- ded object is being edited, the application should save a copy of the object, with the name provided by the user, but should continue displaying the original object, and should not display the new copy. Applications that already have a "Save Copy As..." command should simply disable their "Save As..." commands while editing embedded objects. Returning to Containers When the user quits the editor for an embedded or linked object, the following behavior should result: State of Editor Result A single linked or embedded object is being edited. Other documents may also be open. Focus returns to the container for the linked or embedded object. Several linked or embedded objects are being edited. Other documents may also be open. or No linked or embedded objects are being edited. Focus returns to the layer immediately beneath the editor. (Current normal behavior.) Additionally, if a single linked or embedded object is being edited, and if no other documents are open in the editor, then when the object s main window is closed, the editor quits. Implementor's Guide Introduction The implementor s guide gives a description of the main commands related to linked and embedded documents, and the actions that clients and servers should take to provide the right results. Part 4 gives the specification of the library functions that applications call. The appendix gives details of the DDE messages that the library uses to implement these actions. The overall structure of the libraries is shown in the diagram below. A client deals with linked and embedded objects through opaque handles and API calls to the compound document library DLL. That DLL makes calls on system services (registration, DDE etc) and may also make use of additional DLLs that may be supplied to manage or render particular types of object. The client application is unaffected by this. Clipboard Conventions A major part of the compound document support required is concerned with creating objects and moving them around among containers. The majority of this will be done with the clipboard-based copy and paste commands. The effect of these commands depends on the nature of the selection that is Cut or Copied, and the target for the Paste command. The rules for how the Copy and Paste commands deal with the clipboard are relatively simple. The Copy command offers formats to the clipboard in order of their fidelity of description of the selection (most preferable is offered first). The clipboard preserves this ordering, and uses it as the order when another application enumerates the available formats. The source application will offer data formats that adequately describe the selection (e.g. RTF for a part of a structured document), then it will offer and embedded object (communicated by Native and OwnerLink formats), then presentation (e.g. Picture) and other formats into which the selection can be rendered. If the source can be a server for links, it will also offer Link format. If the source selection is an embedded object, or a link, which is not modified by the source container, then the appropriate formats to represent the object are the owner s Native and OwnerLink. If the source container has modified the object s presentation (e.g. recolored it), or if the selection is a range that includes such an object, then the source should offer descriptive formats if such exist (e.g. some enhanced RTF), and offer the source s Native and OwnerLink. The Paste command will enumerate the formats available on the clipboard in the order in which they were offered, and will take the first format that is compatible with the target for the Paste command. If no suitable data format is found, a compound document client will make an embedded object from the Native and OwnerLink formats, and enumerate further formats to find and obtain a data or presentation format. The destination application may have different preferences for formats depending on where the selection is in the destination document (e.g. pasting into a picture frame vs. pasting into a stream of text). The Paste Link command behaves like the Paste command in its enumeration and selection of data and presentation formats, but first checks for the existence of the ObjectLink format, and ignores the Native and OwnerLink formats. If ObjectLink and a useful format are found, the destination application makes a data link or a compound document link as appropriate. If ObjectLink is not available, the destination may look for a Link format and create a non-object link as in existing applications. Non-compound document applications that try to Paste from such a clipboard offering will simply ignore the Native, OwnerLink and ObjectLink formats, and behave as they do now. Non-compound document applications that Copy to the clipboard will not offer these formats, and a data transfer will result, as happens at present. It is possible that some existing applications do not follow the rules on offering preferred formats first, and that a compound document application following these Paste rules will end up with a different result than it would today. The following tables show the results of these rules in various representative scenarios. Source selection Clipboard contents, in order Pictorial data e.g. a chart in Excel or a CAD drawing or part of a presentation etc. Application or domain specific formats e.g. .XLC, DRW Native(src) OwnerLink(src) Picture ObjectLink, Link Structured data e.g. a range of a spreadsheet or a data table in a DBMS etc Structured data formats e.g. Biff Structured document formats e.g. SGML, RTF Native(src) OwnerLink(src) Picture, Text etc. ObjectLink, Link Range of structured document Structured document formats e.g. SGML, RTF Native(src) OwnerLink(src) Picture, Text etc. ObjectLink, Link Compound document link (unmodified by the container) OwnerLink(owner) Picture or other presentation format ObjectLink, Link Embedded object (unmodified by the container) Native(owner) OwnerLink(owner) Picture or other presentation format ObjectLink, Link Note that because of the ability to have object-specific handler libraries, it will be possible to have Native data in the set of presentation formats available in the above cases. For this reason the order of appearance of Native and OwnerLink is important to disambiguate an embedded object (Native first) and a link (OwnerLink first) which happens to use (a cached copy of) Native data for its presentation. Source selection Destination context Worksheet Structured document Picture frame Rich text frame Presentation graphics Draw program Pictorial data embed embed embed embed embed embed Structured data convert convert embed convert embed embed Structured document convert convert embed convert embed embed Compound document link link to owner link to owner link to owner link to owner link to owner link to owner Embedded object embed owner embed owner embed owner embed owner embed owner embed owner Notes: ObjectLink always describes the source class, document, and item. Paste Link always uses the ObjectLink format and some data or presentation format (or Link format for non-object sources). OwnerLink may describe the source or the owner, but always describes the owner ap- plication for the object. Paste will use Native, OwnerLink and some presentation format if no preferable data format is found. There are some cases where the user might legitimately want a different result than is given by these rules. There are a number of ways that these can be achieved, some are application-dependent and in- volve additional function in applications. Others involve an extra action by the user to achieve the in- tended result. The first case is where the Copy/Paste rules lead to a data conversion and the user wants to embed. For example, we have chosen to offer structured document formats in preference to Native for structured data, on the grounds that more often the conversion will be what is desired. To force embedding rather than conversion, the user should have ways to select the source material in an unambiguous way (in cases where the source application is rich in both data manipulation and presentation). Additionally, where a destination application is capable of converting document formats as well as embedding, it should offer the user a way to indicate the context into which the Paste is to happen, for example by inserting a picture frame and pasting into that, or through some Paste Special... command. Cases where these rules lead to undesired embedding are all dealing with pictures (either source or destination). One variant is that the user wants to take a picture that is the result of a computation (e.g. a chart), and import it into a drawing editor to change it. (The case of annotation is nicely handled by embedding it and adding drawing elements). Drawing editors might have some special command for this purpose, as it is specific to those applications and is a rare case. The other variant is where the user does not want to pay the storage cost for the Native data, and is prepared to lose the ability to change the picture (except with a drawing editor as above). For this case, command buttons in the property dialogs of the objects allow them to be unlinked or converted to static pictures after the Paste has taken place. If the user wants to convert an already linked or embedded object, he simply opens it first and selects the data he requires. An interesting case occurs where the selection is an embedded picture that the source container has modified (e.g. recolored). Following the rules above, Copy/Paste will cause the recolored object to be embedded in the destination: what the user sees in the source is what he gets in the destination. If the user wants the original picture, he need simply open it or otherwise select the unmodified object, and Copy/Paste that. Registration Clients must be able to locate servers for objects that they contain. This is achieved by servers registering the required information into the system registration database when the server is installed onto the system. The details of what must be registered are described in the implementor's guide. Applications that implemented the protocol prior to the availability of this library and the registration service used a different registration mechanism: they stored information in a special section in win.ini. Applications using this library will have access to those servers transparently, since the registration service will perform the mapping of the registration information. Similarly, older client applications which look in win.ini will find information about newer servers which were registered with the system since the registration service will store the old format information in win.ini for the purpose. Client A client is a container of other objects. A client application uses the services of other applications (servers) to carry out editing and rendering of the objects that the client document contains. The client application provides storage for the object, and contextual information about the target printer, where on the page the picture should be printed, etc., and provides the user with the means to open the object for editing using the correct server application. In order to be a client, or container, the application must provide ways to bring objects into the container and take them out again. The client must provide the permanent storage for the object within the container document s permanent storage (i.e. file). For embedded objects, the client library will store the native data for the object, some presentation data for the object (e.g. a metafile), and the link information which contains the ClassName, some client-supplied document name, and the item name associated with the object. Details of use of the link information are given in the protocol reference section later in this document. For links to other documents, the client library will store the link information as above, where the document name in this case will be the permanent name for the document (e.g. its pathname), and also the presentation data as above along with a timestamp recording when the presentation data was obtained. Certain operations (updating objects, launching and closing down servers etc.) are asynchronous operations. The library does not retain control during these operations, but marks the objects as busy, and returns to the client so that events can be processed. As long as the client is dispatching events, the library will process the transactions in a coroutine-like manner. The library will notify the client by a callback function when the operation completes. Protocol Checking A client must check that a server it wants to contact will support the desired protocol. For this specification the protocol is identified by the string "StdFileEditing". The check is performed by passing the protocol name to the library functions that create objects (from clipboard contents, from files etc). if( EcdCreateFromClip( "StdFileEditing", &clientstruct, &lpobj, renderopt, cfFormat ) == ECD_OK ) ... Open a Document When a client opens a document that contains a link or an embedded object, it should call the client library to load the object. The client should query the object to determine if it has changed since the document was last loaded and needs to be updated. If so, the client should accumulate a list of out-of- date objects and offer the user the opportunity to update them. Note that for embedded objects it is possible for the presentation data to be out of date, since the embedded object may itself contain links to other objects. load application data from file if found an object if( EcdLoadFromStream( &filestream, "StdFileEditing", &clientstruct, &lpobj) != ECD_OK ) return BADFILE if (EcdQueryOutOfDate( lpobj ) != ECD_OK) add object to list of out-of-date items when load completed, if out-of-date objects exist inform the user, offer to update selected objects Save or Close a Document When a document containing linked or embedded objects is saved or closed, the client should save the objects into the file by calling EcdSaveToStream. The library will save up-to-date versions of the relevant data for the objects (native, link, presentation as appropriate) in the client documents permanent storage (e.g. file). If some server is open, the client library will retrieve the data from the servers before saving. If the client launched the server as a slave to edit the object, the client library will close down the server. Since updates and closing down servers are asynchronous operations, the library may return indicating that the client application should not proceed until the library notifies the client that the operation is complete. case SAVE: if( document not saved) save client application data for each object if (EcdSaveToStream( lpobj, &filestream) == ECD_BUSY) while notification not received dispatch messages break; case CLOSE: for each object if( EcdDelete(lpobj ) == ECD_BUSY) add to list of objects in process of closing while busy objects remain dispatch messages Display and Print The client should set up the device context and bounding rectangle for rendering the object and call EcdDraw( lpobj, hDC, &bounds, hFormatDC ); The library will either call the class-specific rendering DLL to render the object if available, or will use the presentation data for the objects to display and print in the appropriate place. The library will periodically call back to the client callback function during drawing. The client function may check for interrupt etc, and should return zero if it wants to prematurely terminate the drawing. The EcdDraw function will then return immediately indicating that the drawing was interrupted. It is also possible for the client to take some actions within the callback function and return non-zero to indicate that drawing should continue, provided that those actions do not interfere with the drawing e.g. by scrolling the window. An example is that the client might give up focus during drawing to permit the user to switch to another window. Open an Object When the user requests the client to open the object for editing, the client should call EcdOpen(lpobj, fShow). The library will notify the client when the server is properly open or when something fails. The object may be displayed during this process, but should not otherwise be altered. FShow tells the server whether to show the window to the user (true, non-zero) or to keep it hidden (false, zero). The latter is useful for invisibly updating an object. Change Printer, Resize Objects are assumed to have a given size on the intended target device (printer etc). Sizes are all communicated in HIMETRIC units. The client should call EcdSetTargetDevice(lpobj, hTargetDevice) if the target output device is changed, and should call EcdSetBounds(lpobj, &newBounds) if the size of the rectangle is changed (e.g. by user action). See also EcdDraw. Cut and Copy Clients must provide support for transferring objects out of their documents through the cut and copy commands, as well as taking them in through paste and paste link commands. There is additional support required for being a server, which is used to create objects from data and to create links. It is likely that many applications will be able to act as both client and server, and it is convenient to describe both here. Applications that cannot act as servers for embedded objects would not offer their Native data or Own- erLink formats. Applications that cannot act as servers for links would not offer ObjectLink or Link format. In the case that an application can be a server for embedded objects, it should use the OwnerLink format to convey its name and item information to the receiving application. When an linked or embedded object is selected, clients must call EcdCopyToClipboard or EcdCutToClipboard as appropriate. The values assigned to each of the formats placed on the clipboard by the copy command will depend on the nature of the current selection. The following algorithm summarizes the rules containers use to assign values to the various formats placed on the clipboard by the copy command: if (selection is link or embedded object) EcdCopyToClipboard( lpobj ) // or EcdCutToClipboard... else offer any data formats that adequately describe the selection if (can be server for embedded objects) offer Native = source s native data for selection offer OwnerLink = source generated description of selection offer other formats that can be used to present the selection or into which it can be converted if (can serve links & source is not an open embedded object) offer ObjectLink = source generated description of location in source if( can serve old kind of links ) offer Link = appname/topicname/itemname as in existing applications Paste The "Edit-Paste" command pastes the object, data, or link on the clipboard at the current insertion point. If data is on the clipboard then the data is converted into a native data type of the container as it is pasted; if an object is on the clipboard it is embedded in the container; if a link is on the clipboard it is used to create a link in the container. The following algorithm summarizes the rules containers apply to the formats on the clipboard to determine how to execute a paste command: for each format on the clipboard in order if format is acceptable for target if format is not Native or OwnerLink convert the data and paste it in else EcdCreateFromClip( "StdFileEditing", &clientstruct, &lpobj, renderopt, cfFormat ) else continue searching if no format was found refuse paste After the paste operation is completed, clients should select the newly pasted item, unless the item has been converted to a container-native type. This will give the user quick access to the properties of the object. Paste Link The "Edit-Paste Link" command creates a link at the target identified by the current selection, to the item identified on the clipboard. This command should be disabled if link information is not available on the clipboard. The following algorithm summarizes the rules containers apply to the formats on the clipboard to determine how to execute a paste-link command: if ObjectLink format is available if( EcdCreateLinkFromClip( "StdFileEditing", &clientstruct, &lpobj renderopt, cfFormat) == ECD_OK ) //all done else if Link format is available do whatever link stuff you do today As with the paste operation, clients should select the new object, to give the user quick access to the properties. Undo Clients should save a copy of the embedded object when it is opened for editing, so that when the editor is closed and the object is updated, the user still has the chance to undo all of the changes made in the editor. This must be supported in the client, since the server has no way to revert to the prior state. Links A client that maintains links might offer functions to the user to manage those links, reconnect broken links to renamed documents etc. This is determined by the client. The library provides functions to query and set the link information for the object so that the client application can implement the user interface for these functions. Note: the item name may be null in which case the link refers to the whole of the server document. Properties Applications that support this model must implement a " Properties..." command in their "Edit" menus; selecting this command produces an object properties dialog for the currently selected object or link. If a client supports a variety of update rules, it should provide functions whereby the user can change the attributes of the link, change a link to an embedded object (which requires the client to launch the server and request the native data), unlink, leaving only the picture, and so on. Shutdown When a client or server shuts down while it is the clipboard owner, it should render all formats to the clipboard, subject to memory availability. The application should ensure that the clipboard presents a consistent state (e.g. there is no native data without corresponding owner link), and reflects the prefer- ence order of formats and the nature of the selection that was copied (e.g. not an owner link without native data for and embedded object). When shutting down, the client should delete all objects from memory. EcdDelete may return indicating that the client should not terminate yet, but should wait (dispatching messages) until a notification callback informs the client that it is safe to terminate. Server Server applications provide their service by allocating structures defined in Part 4 and registering them with the server library. The server library will implement the DDE execute commands and DDE data conventions described in the DDE protocol reference appendix. The library will call back to the server application to use the service. Servers should be passive, and should not make assumptions about ordering of callbacks. Server implementors will also need to refer to the Copy command described in the client section above. Opening When a client launches a server to edit a linked or embedded object, it passes a command line switch to the server("-Embedding", for historical reasons). The server should change some of its menu commands as listed below, and be prepared to be controlled partially by the client, through the server library. See Part 4 for details of the latter. The library will always launch a new instance of a server in order to edit an embedded or linked object, except in the case that the object is a link to a document that is already open. The intent is that separate instances of applications should be used to avoid interfering with the application s context information (e.g. current window, current selection etc). If a server application is unable to run multiple instances, a stub should be provided that will locate an existing instance if possible, and enable the client to communicate with that. The client should be unaware that it does not have a new instance. Shutdown For embedded objects, the client library will use DDE commands to instruct the server library to close documents, exit, show the window, etc. The server library will make callbacks to the server application to invoke these functions. Servers should comply with these commands without confirmation dialogs etc, and should exit when so instructed. The onus is on the client to provide the requisite confirmation dialogs. For linked objects, although the client will open the server it will not instruct it to close the document or exit (unless it is performing an invisible update). The linked object has an existence independent of the client and the user (through the server application) controls saving and closing the document. There is one case where the server for an embedded object must be more intelligent: if it is a multiple document application, and more than one client has established contact, or the user has opened additional documents, then the server should remain open until the user closes it. Exit commands from clients should be ignored. See also the Shutdown in the client section above for clipboard behavior. Copy The behavior of the copy command is described in the client section above. If a server cannot also act as a client, it follows that the selection will only ever be server data. The server should offer descriptive data formats first, then Native, OwnerLink, then presentation and other formats, and lastly ObjectLink (and possibly Link) formats. Save a Copy When editing an embedded object under control of a client, servers should change the Save as... menu command (if they have one) to be "Save a Copy As...". This allows the user to save a copy of an embed- ded object into its own file. The normal "Save As..." command has the additional effect of changing the association of the in-memory document to be the new file, whereas this specification requires that it still be associated with the client s embedded object. Update When editing an embedded object, the server should change its Save menu command to be "Update". This should notify the client (via the server library) of changes as described in the protocol reference section. Exit, Close The Exit command should be changed to "Exit and Update" or "Exit and return", and the main window close command should have the same effect. When a server that is editing an embedded object is closed, it should perform the same actions as Update, above, before closing. Similarly, a multiple document server that closes a window containing an object embedded in some client, it should perform the Update action as above before closing. Renaming a Document If a server of a link renames the document while a client has a conversation with the server (the server library creates an object structure when this happens), the server should notify the library of the change of name. The client will in turn be notified of change by the client-side library. Installation of Classes Installing a server class is simply a matter of registering the editor. See the registration specification in the API specification section. API specification All types, constant values and functions required by clients and servers are declared in a C header file "ecd.h". Additional types and functions required by class-specific handlers are declared in "objcreate.h". Introduction and general definitions A recurrent idiom in these structure definitions is the use of a vtbl, which is a table of function pointers, and a vptr, which is a pointer to a vtbl. The vptr is stored in a data structure whose address is used to identify and access the data structure. Extra instance-specific state information may be stored in the data structure that contains the vptr, initialized by and for the use of the object handler functions. The client for the particular object should not access this state information as its content is entirely determined by the implementor of the handler functions. In various occurrences of this idiom the creator may be the client application, the client library, and object handler library, the server library, or the server application. The convention for calling a function whose address is stored in a vtbl is to pass the address of the object as the first argument. This permits the function to access the state stored in the structure without use of global data and without use of void* parameters to pass the contextual information. This scheme allows multiple instances of the same type of object, and extension of the state information stored in the structures. Client API specification Types, Data structures and parameter definitions All functions return a status code to indicate success or some failure condition. Result values are returned through pointer parameters. Return codes are defined as follows: ECDSTATUS // return codes for ECD functions typedef enum { ECD_OK, // function operated correctly ECD_ERROR_MEMORY, // could not allocate or lock memory ECD_ERROR_FATAL, // only DEBUG version. normally fatal error ECD_ERROR_STREAM, // (ECDSTREAM) stream error ECD_ERROR_STATIC, // object is unexpectedly static ECD_ERROR_BLANK, // critical data missing ECD_ERROR_LAUNCH, //failed to launch server ECD_ERROR_COMM, //failed to establish communication with server ECD_ERROR_DRAW, //error or interrupt while drawing ECD_ERROR_CLIP, //failed to get/set clipboard data ECD_ERROR_FORMAT, // requested format is not available ECD_ERROR_ILLEGALOBJECT,// Not a valid object ECD_ERROR_OPTION, // invalid option (update or render) ECD_ERROR_PROTOCOL, // server not following protocol ECD_WAIT_FOR_RELEASE // client must dispatch until RELEASE callback before quit. } ECDSTATUS; Structures provided by the library for the client The object structure is an in-memory structure used to hold information about the embedded or linked object. It is created by the library when an object is read from a file, pasted from the clipboard, or duplicated. The client does not see the content of this structure, merely its pointer. Client programs directly call functions to manipulate these objects. These functions reside in a DLL, and use the vtbl structure to dispatch to the object-specific implementation. ECDOBJECT, LPECDOBJECT struct _ECDOBJECT /* opaque to clients */ typedef struct _ECDOBJECT ECDOBJECT, FAR* LPECDOBJECT; Server programs and class-specific libraries provide an implementation of the ECDOBJECT type. The set of methods that must be supplied is specified in the sections on object handlers and servers. Structures provided by the client for the library Object libraries require certain functionality from the client application in order to do their work. This functionality is made available to the object libraries through structures and callback functions that the client defines and passes as arguments to the libraries. In this way the client is given great flexibility in how the functions are implemented. ECDCLIENT is a structure allocated by the client and passed to the library when an in-memory object is being created. It is used to pass a callback function that the library uses to notify the client of various events, along with any state that the client wishes to associate with the object.. The pointer to the client structure and the pointer to the object are remembered by the passed to the callback function along with the reason for the notification. The client may add extra information associated with the object for its own purposes at the end of the client structure. The library stores the client pointer in the object structure so that it (the library) can locate it when needed. ECD_NOTIFICATION // Codes for CallBack events typedef enum { } ECD_NOTIFICATION; ECDCLIENT, LPECDCLIENT struct _ECDCLIENT; /*forward*/ typedef struct _ECDCLIENT FAR *LPECDCLIENT; struct _ECDCLIENTVTBL { BOOL (FAR PASCAL *CallBack) ( LPECDCLIENT lpclient, ECD_NOTIFICATION notification, LPECDOBJECT lpobject); }; typedef struct _ECDCLIENT { struct _ECDCLIENTVTBL FAR* vptr; /* any client supplied state goes here */ } ECDCLIENT; ECDCLIENT: CallBack BOOL (FAR PASCAL *CallBack)( lpclient, notification, lpobject ); Name Type Description lpclient LPECDCLIENT long pointer to the client structure associated with the object. The library retrieves this pointer from its object structure when a notification occurs, uses it to locate the callback function, and passes the pointer to the client structure for the client application's use. notification ECD_NOTIFICATION a value of an enumerated type which indicates the reason for the notification. Values are: ECD_CHANGED: object has changed and needs to be redrawn, will need to be saved etc. ECD_SAVED: a linked object has been saved in its server. ECD_CLOSED: object has been closed (in its server). ECD_RENAMED: a linked object has been renamed in its server. This variant is for information only, as the library takes care of updating its link information. No particular action is required. This notification implies ECD_CHANGED. ECD_QUERY_PAINT: This notification is made during lengthy drawing operations to allow interrupt. See return value, below. ECD_RELEASE: This notification informs the client that the object has finally been released and (when all such objects have been released) the client may safely quit. lpobject LPECDOBJECT a long pointer to the object that caused the notification to be sent. This pointer is not necessarily useful to the client application, depending on whether the application allocates a different client structure for each object. This argument is provided so that applications that wish to may use the same client structure for more than one object, and use the object pointer to distinguish notifications. return value BOOL this value is ignored except in the case of ECD_QUERY_PAINT. The client should return false (zero) if the painting should be aborted, and true (non- zero) if painting should continue. The client should act on these notifications at the next appropriate time (e.g. main event loop, closing the object etc). Update of objects may be deferred until the user requests update, if the client wishes to provide that functionality. The client may call the library from a notification callback function. The library will be properly re-entrant. There will be some things that the client may not do while some operations are in progress (opening etc). ECDSTREAM, LPECDSTREAM The ECDSTREAM structure is provided by the client application. It provides stream IO functions (read, write, seek) for the library to use when loading and saving objects. This permits the client to determine where the permanent storage is by providing variations on the IO procedures, e.g. to store the object in a database. // Stream definitions typedef struct _ECDSTREAM FAR * LPECDSTREAM; typedef struct _ECDSTREAMVTBL{ LONG (FAR PASCAL *Get) (LPECDSTREAM, LPSTR, LONG); LONG (FAR PASCAL *Put) (LPECDSTREAM, LPSTR, LONG); LONG (FAR PASCAL *Seek)(LPECDSTREAM, LONG, INT); //like _llseek } ECDSTREAMVTBL; typedef ECDSTREAMVTBL FAR *LPECDSTREAMVTBL; typedef struct _ECDSTREAM { LPECDSTREAMVTBL lpstbl; } ECDSTREAM; The stream need not be valid all the time while the object exists. The stream is only valid for the duration of the function to which it is passed. The library will obtain everything it needs. In event of an error reading or writing the stream, the library will indicate the existence of the error back to the client, but not its nature. The client-supplied stream object should store any needed indication of what the error condition was so that the client can take recovery action. ECDSTREAM: Get LONG (FAR PASCAL *Get)( lpstream, lpbuf, cbbuf ); Name Type Description lpstream LPECDSTREAM a long pointer to a stream structure allocated by the client lpbuf LPSTR a long pointer to a buffer to fill with data from the stream cbbuf LONG a long count of bytes to read into the buffer return value LONG a long count of bytes actually read into the buffer. A return value of zero implies end-of-file was encountered. A negative return value implies an error was encountered. ECDSTREAM: Put LONG (FAR PASCAL *Put)( lpstream, lpbuf, cbbuf ); Name Type Description lpstream LPECDSTREAM a long pointer to a stream structure allocated by the client lpbuf LPSTR a long pointer to a buffer from which to write data into the stream cbbuf LONG a long count of bytes to write into the stream return value LONG a long count of bytes actually written. A return value less than cbbuf implies an error occurred or insufficient space in the stream. ECDSTREAM: Seek LONG (FAR PASCAL *Seek)( lpstream, loffset, iorigin ); Name Type Description lpstream LPECDSTREAM a long pointer to a stream structure allocated by the client. loffset, iorigin and the return value are exactly as specified in the Windows _llseek function. Protocol naming and checking Protocols are definitions of API sets. This API set is the basic compound document protocol. Protocols are named with (null terminated) string names; this one is called StdFileEditing. The name of the protocol that the client requires (identifying the API functions he needs to call) is passed in to the function that create the object. The library checks that the object does in fact support that protocol and fails the request if not. Rendering Options The client may control the way the object will be rendered. The library provides support for handling all of the rendering, obtaining data for the client to handle the rendering, or doing nothing. ECDOPT_RENDER, ECDCLIPFORMAT // rendering options typedef enum { ecdrender_none, //library gets no data, will not draw ecdrender_draw, //client will call draw, lib manages data ecdrender_format //client will call getdata and render, // lib gets and stores data. } ECDOPT_RENDER; typedef WORD ECDCLIPFORMAT; // standard clipboard format type // tells lib what format to get for ecdrender_format API functions Functions that create objects rather than operating on existing objects return the object pointer through a pointer argument (LPECDOBJECT FAR *) rather than taking an object pointer as the first argument. Windows memory management is used to obtain storage for the object structures. Utility functions Some of the functions defined here are implemented in a library of utility functions. The real work is done by calling method functions on the objects. To get full flexibility in managing the objects a client can call the object methods directly. To get a simpler but less flexible interface, the utility functions are provided. Enabling Paste and Paste link commands The following functions check that the object on the clipboard supports the required protocol, and can be linked or embedded as appropriate. They are called when the client wants to check whether to enable a Paste or Paste Link command. The client should supply the protocol string name "StdFileEditing". EcdQueryCreateFromClip ECDSTATUS FAR PASCAL EcdQueryCreateFromClip ( protocol, renderopt, cfFormat ); Name Type Description protocol LPSTR the name of the protocol that the client wishes to use. Currently the library supports "StdFileEditing" which is the internal name of the object linking and embedding protocol, and "Static", which allows simple clients to use the library to manage static pictures for them. Static objects will fail if asked to open, and will generate no notifications. renderopt ECDOPT_RENDER an indication of how the client wants to have the object displayed and printed: ecdrender_none: the object is not to be shown at all. This option may be used to hypertext links etc. The library will not obtain any presentation data, will not draw ecdrender_draw: the client will call EcdDraw, the library will obtain and manage presentation data ecdrender_format: the client will call EcdGetData and do the rendering, the library will obtain and manager the data in the requested format (see below). cfFormat ECDCLIPFORMAT the clipboard format that the client will request through EcdGetData, only used with ecdrender_format above. EcdQueryLinkFromClip ECDSTATUS FAR PASCAL EcdQueryLinkFromClip( protocol, renderoption, cfFormat ); arguments are as above Executing Paste and Paste link commands The following functions check that the object on the clipboard supports the required protocol, and can be linked or embedded as appropriate, and perform the operation. They are called when the client wants to execute a Paste or Paste Link command. The client should supply the protocol string name "StdFileEditing", or "Static" if the object is a non-editable picture. EcdCreateFromClip ECDSTATUS FAR PASCAL EcdCreateFromClip ( protocol, lpclient, lplpobject , renderopt, cfFormat); Name Type Description protocol LPSTR as protocol above lpclient LPECDCLIENT a long pointer to an ECDCLIENT structure allocated and initialized by the client application. This pointer will be used to locate the CallBack function, and passed in CallBack notifications. lplpobject LPECDOBJECT FAR * a long pointer to a long pointer to an ECDOBJECT. The caller should pass the address of an LPECDOBJECT into which the library will store the address of the created object. renderopt ECDOPT_RENDER as renderopt above cfFormat ECDCLIPFORMAT as cfFormat above return value ECDSTATUS see ECDSTATUS type definition EcdCreateLinkFromClip ECDSTATUS FAR PASCAL EcdCreateLinkFromClip( protocol, lpclient, &lpobject , renderopt, cfFormat ); arguments and return value are as above. This function creates a link to an object rather than an embedded object. Copying or cutting an object to the clipboard EcdCopyToClipboard ECDSTATUS FAR PASCAL EcdCopyToClipboard( lpobject ); Name Type Description lpobject LPECDOBJECT a long pointer to the object to be copied to the clipboard return value ECDSTATUS see ECDSTATUS type definition Puts the object on the clipboard (Copy command). The client should open the clipboard, offer any data formats on the clipboard, call this function, offer any additional presentation formats, and close the clipboard. If the client wishes to support delayed rendering it should use EcdEnumObjectFormats to offer them to the clipboard, and either EcdGetData or EcdCopyToClipboard to actually render the data. Alternatively, a simple client may render the data immediately with the following functions and avoid deferred rendering. EcdCutToClipboard ECDSTATUS FAR PASCAL EcdCutToClipboard( lpobject ); Name Type Description lpobject LPECDOBJECT a long pointer to the object to be cut to the clipboard return value ECDSTATUS see ECDSTATUS type definition This function cuts the object to the clipboard (which may optimize compared to copy/delete). Usage is as above. Load from and Save to client's file The client should call these functions to load the object from the containing document and save it back after editing. The client does not need to know the class of the object, or whether it is linked or embedded (although it can find out using EcdEnumObjectFormats). The client simply needs to remember where objects are stored in the file. EcdLoadFromStream ECDSTATUS FAR PASCAL EcdLoadFromStream( lpstream, protocol, lpclient, lplpobject ); Name Type Description lpstream LPECDSTREAM a long pointer to an ECDSTREAM structure allocated and initialized by the client application. The library will call the Get method in the ECDSTREAM structure to obtain the data for the object. protocol LPSTR see protocol earlier lpclient LPECDCLIENT see lpclient earlier lplpobject LPECDOBJECT FAR * a long pointer to an LPECDOBJECT where the library will store the long pointer to the object return value ECDSTATUS see ECDSTATUS type definition EcdSaveToStream ECDSTATUS FAR PASCAL EcdSaveToStream( lpobject, lpstream ); Name Type Description lpobject LPECDOBJECT a long pointer to the object to be saved into the stream lpstream LPECDSTREAM a long pointer to an ECDSTREAM structure allocated and initialized by the client application. The library will call the Put method in the ECDSTREAM structure to store the data from the object. return value ECDSTATUS see ECDSTATUS type definition Object creation Creating new objects EcdCreate ECDSTATUS FAR PASCAL EcdCreate( protocol, lpclient,classname, lplpobject ,renderopt, cfFormat ); This function creates an object of a specified class. The server is opened to perform the initial editing. Name Type Description protocol LPSTR as protocol earlier lpclient LPECDCLIENT as lpclient earlier classname LPSTR null terminated string which is the registered name of the class of the object to be created. lplpobject LPECDOBJECT FAR * as lplpobject earlier renderopt ECDOPT_RENDER as renderopt earlier cfFormat ECDCLIPFORMAT as cfFormat earlier return value ECDSTATUS see ECDSTATUS type definition EcdCreateFromTemplate ECDSTATUS FAR PASCAL EcdCreateFromTemplate( protocol, lpclient, objectname, lplpobject, renderopt, cfFormat ); This function creates an object given the name of an object in a file to use as a template. The server is opened to perform the initial editing. This function creates an object of a specified class. The server is opened to perform the initial editing. Name Type Description protocol LPSTR as protocol earlier lpclient LPECDCLIENT as lpclient earlier objectname LPSTR null terminated string which is the pathname of an object to be used as a template for the new object. The server is opened for editing and loads the initial state of the new object from the named object lplpobject LPECDOBJECT FAR * as lplpobject earlier renderopt ECDOPT_RENDER as renderopt earlier cfFormat ECDCLIPFORMAT as cfFormat earlier return value ECDSTATUS see ECDSTATUS type definition Creating an object by converting an existing object EcdObjectConvert ECDSTATUS FAR PASCAL EcdObjectConvert( lpobject, protocol, lpclient,lplpobject ); This function may be used to request creation of a new object that supports a specified protocol from an existing object. Today, there are only two protocols: StdFileEditing which manages linked and embedded objects, and Static, which manages embedded pictures only. As of now, only converting linked or embedded objects to static objects will succeed. The original object is not deleted or replaced by this call. Name Type Description lpobject LPECDOBJECT a long pointer to the object to convert protocol LPSTR the name of the protocol required for the new object lpclient LPCLIENT a long pointer to a client structure for the new object lplpobject LPECDOBJECT FAR * a long pointer to an LPECDOBJECT where the library will store the long pointer to the new object return value ECDSTATUS see ECDSTATUS type definition Copying and comparing objects EcdClone ECDSTATUS FAR PASCAL EcdClone( lpobject, lpclient, lplpobject ); This function makes a duplicate copy of an object. A new client context may be supplied. Name Type Description lpobject LPECDOBJECT a long pointer to the object to be copied lpclient LPECDCLIENT a long pointer to the client structure for the new object lplpobject LPECDOBJECT FAR * a long pointer to an LPECDOBJECT where the library will store the long pointer to the new object return value ECDSTATUS see ECDSTATUS type definition EcdEqual ECDSTATUS FAR PASCAL EcdEqual( lpobject1, lpobject2 ); Also a function to compare two objects for equality. The latter can be used to save storage. Embedded objects are equal if their class, item and Native data are identical. Linked objects are equal if their class, document, and item are identical. Name Type Description lpobject1, lpobject2 LPECDOBJECT long pointers to the objects to be compared return value ECDSTATUS see ECDSTATUS type definition. Returns ECD_OK if the two objects are equal as described above. Making a local copy of a linked object EcdCopyFromLink ECDSTATUS FAR PASCAL EcdCopyFromLink( lpobject, protocol, lpclient, lplpobject ); This function makes a local embedded copy of a linked object. This may involve launching the server application. Name Type Description lpobject LPECDOBJECT a long pointer to the linked object that is to be embedded protocol LPSTR the name of the protocol required for the new embedded object lpclient LPECDCLIENT a long pointer to a client structure for the new object lplpobject LPECDOBJECT FAR * as lplpobject earlier return value ECDSTATUS see ECDSTATUS type definition. Object method functions Protocol extensibility EcdQueryProtocol LPVOID FAR PASCAL *EcdQueryProtocol( lpobj, lpprotocol ); The design of the object protocol allows for additional protocols to be defined at future times. It will be necessary for clients to perform a run-time check that an object supports a desired protocol, either at creation time (suitable for protocols on which the client insists) or after the object has been created, to test whether an object supports an optional protocol that the client can exploit if it is available. For this purpose we define a method on the object that can be called to simultaneously query if the protocol is supported and return a modified object pointer giving access to the method table for the extra protocol. The pointer returned has the same form as the LPECDOBJECT pointer, in that it points to a pointer to a table of functions, and additional state information may be stored by the object handler following the vtable pointer. This secondary pointer is not considered to point to a different object however; if the object is deleted (with EcdDelete), secondary pointers become invalid. A protocol may elect to include delete methods, and calling any delete method will invalidate all pointers to that object. Name Type Description lpobj LPECDOBJECT a long pointer to the object to check for an additional protocol lpprotocol LPSTR the (null-terminated) string name of the desired protocol. Currently only the name StdFileEditing is defined. return value LPVOID a long pointer to an object structure (defined as having a long pointer to a table of methods as the first entry). The definition of the functions is entirely determined by the protocol definition. This function returns NULL if the object does not support the requested protocol. Destroying an object EcdDelete ECDSTATUS FAR PASCAL EcdDelete( lpobject ); Delete and object and reclaim storage. Closes the object if it is open. Name Type Description lpobject LPECDOBJECT a long pointer to the object to be deleted. return value ECDSTATUS see ECDSTATUS type definition. In particular, this function will return ECD_WAIT_FOR_RELEASE if the object is still in the process of closing down, which means that the client application must wait (dispatching messages) for a CallBack notification with the ECD_RELEASE argument before it can safely quit. This notification must be awaited for each object that returns ECD_WAIT_FOR_RELEASE, though the order is not significant. Finding the display size of an object EcdQueryBounds ECDSTATUS FAR PASCAL EcdQueryBounds( lpobject, lpBounds ); This function returns the geometric bounding rectangle (on the target device) of the object in MM_HIMETRIC units. Name Type Description lpobject LPECDOBJECT a long pointer to the object whose bounds are requested. lpBounds LPRECT a long pointer to a RECT structure that will be filled with the bounding rectangle for the object. return value ECDSTATUS see ECDSTATUS type description Formatting an object EcdSetTargetDevice ECDSTATUS FAR PASCAL EcdSetTargetDevice( lpobject, hTargetDevice ); Name Type Description lpobject LPECDOBJECT a long pointer to the object that should be formatted for the specified target device hTargetDevice HANDLE a handle to a memory structure that describes the target device for the object. The format of this structure is described in the appendix under StdTargetDevice return value ECDSTATUS see ECDSTATUS type description Specify the target device for output so that the object may format appropriately for that device even when rendering on a different device (e.g. a window). This function should be called whenever the target device is changed, so that servers can be notified and re-render the picture if necessary. The client should call the library to redraw the object if it receives a notification that the object has changed. See the appendix for details of the StdTargetDevice structure. EcdSetBounds ECDSTATUS FAR PASCAL EcdSetBounds( lpobject, lpBounds ); Name Type Description lpobject LPECDOBJECT a long pointer to the object that should be formatted for the specified size on the target device lpBounds LPRECT a long pointer to a RECT structure containing the required bounds for the object. return value ECDSTATUS see ECDSTATUS type description Specify the rectangle to be used as the target size of the object. This is not necessarily the same as will be used in the EcdDraw call, depending on the view scaling that the container application is using. This call can be used to cause the server to reformat the picture to fit the rectangle better. The bounds are specified in MM_HIMETRIC units. This call is ignored for linked objects as their size is determined by the document of which they are a part. EcdSetHostNames ECDSTATUS FAR PASCAL EcdSetHostNames( lpobject, hostname, hostobjectname ); Name Type Description lpobject LPECDOBJECT a long pointer to the object that should be formatted for the specified size on the target device hostname LPSTR the string name of the container application hostobjectname LPSTR the container's string name for the object. return value ECDSTATUS see ECDSTATUS type description Specify the name of the container application and the container's name for the object, to be used in window titles when editing in the server Rendering an object EcdDraw ECDSTATUS FAR PASCAL EcdDraw( lpobject, hDC, lpBounds, hFormatDC ); Name Type Description lpobject LPECDOBJECT a long pointer to the object to be drawn hDC HDC a handle to the drawing context in which the object should be drawn. lpBounds LPRECT a long pointer to a RECT structure containing the bounding rectangle (in the units required by the mapping mode for HDC) into which the object should be drawn.. hFormatDC HDC a handle to a device context that describes the target device for which the object should be formatted. return value ECDSTATUS see ECDSTATUS type description. This function will return ECD_ERROR_DRAW if the CallBack function returns false (zero) during drawing. Draw the object mapped into the specified rectangle on device hDC. The object should be formatted as if it were to be drawn at the size specified by the EcdSetBounds call on the device context specified by hFormatDC. In many cases this formatting will already have been done by the server and the library will simply play a metafile with suitable scaling for the required lpBounds. The hDC argument may include a clipping region smaller than the LPRECT, for cropping or banding purposes. The DC of the target device is required for this call, since the library may be using an object-specific DLL to render the object instead of keeping a metafile. In this case, the DLL may need the information about the target device. The LPRECT argument identifies the rectangle on the hDC (relative to its current mapping mode) that the object should be mapped onto. This may involve scaling the picture, and can be used by client applications to impose a view scaling between the displayed view and the final printed image. This function will periodically call the client CallBack function during drawing, with the notification argument ECD_QUERY_PAINT. The client may check for input or other reason to interrupt the drawing process in this function, and return false (zero) if the drawing should be interrupted. The client may also take action in this callback provided it does not interfere with the state of the object or where it should be drawn, and return true (non-zero) to indicate that the drawing should continue. This allows the client to (for example) give up focus if requested while a lengthy drawing operation is in progress. Initializing and retrieving data Clients may retrieve data in a specified format from the object with the EcdGetData function. The client must have requested this format when creating the object, using the ecdrender_format option. Clients may also provide data to the object with the EcdSetData function. The server should be active when this call is made, in which case the library will send the data to the server. This scenario requires that the client know what format to send to the object, and that it will be meaningful. The intent is to support embedded objects such as charts, and allow the client to provide the data to be graphed. The Get and SetData functions are modelled on the Windows Get/SetClipboardData functions. Objects managed by the standard library (i.e. for which there is no rendering DLL) will not provide conversions: only native, link, and presentation data formats will be offered. EcdEnumObjectFormats ECDCLIPFORMAT EcdEnumObjectFormats( lpobject, cfFormat ); The client may enumerate the formats that the object can render using EcdEnumObjectFormats, which is modelled after the windows EnumClipboardFormats function: passing in a null format returns the first available format. Passing in one that was returned returns the next in sequence. When no more formats are available, null is returned. Name Type Description lpobject LPECDOBJECT a long pointer to the object to be queried cfFormat ECDCLIPFORMAT previous format returned from this call, or null for first call return value ECDCLIPFORMAT next format available, or null if no more EcdGetData HANDLE FAR PASCAL EcdGetData(lpobject, cfFormat); This function retrieves data in the requested format from the object. If the object cannot provide the data, a null handle is returned. Name Type Description lpobject LPECDOBJECT a long pointer to the object from which to retrieve data cfFormat ECDCLIPFORMAT format in which the data should be returned return value HANDLE handle to a memory object containing the data in the requested format, or null if cannot satisfy the request. EcdSetData ECDSTATUS FAR PASCAL EcdSetData(lpobject, cfFormat, hData); This function sends in the specified format to the object. If the object cannot accept the data, an error status is returned. Name Type Description lpobject LPECDOBJECT a long pointer to the object to which data is to be sent. cfFormat ECDCLIPFORMAT format of the data. hData HANDLE handle to a memory object containing the data in the specified format. return value ECDSTATUS see ECDSTATUS type description Repairing broken links The representation of the link information is a buffer containing three null-terminated strings consecutively, followed by a null byte. These strings are the classname, documentname, and itemname. The client may retrieve the link information using EcdGetData with the ObjectLink format. The call will fail if the object is not a link (i.e. is embedded). Class information may be obtained through the OwnerLink format. The client may let the user edit the link information and store it into the object with the EcdSetData function, specifying the ObjectLink format. Update control The client may set and query the update rules for links. The options are update always (i.e. hot link, try to keep the link up to date at all times), update when the target object is saved, and update only when the client requests (typically on user request). ECDOPT_UPDATE typedef enum { ecdupdate_always, ecdupdate_onsave, ecdupdate_oncall } ECDOPT_UPDATE; EcdGetLinkUpdateOptions ECDSTATUS FAR PASCAL EcdGetLinkUpdateOptions( lpobject, lpupdateopt ); This function returns the update options for the specified object. Name Type Description lpobject LPECDOBJECT a long pointer to the object to be queried lpupdateopt ECDOPT_UPDATE FAR * a long pointer to an ECDOPT_UPDATE where the current option setting will be stored. return value ECDSTATUS see ECDSTATUS type description. EcdSetLinkUpdateOptions ECDSTATUS FAR PASCAL EcdSetLinkUpdateOptions( lpobject, updateopt ); This function sets the update options for the specified object. Name Type Description lpobject LPECDOBJECT a long pointer to the object to be changed lpupdateopt ECDOPT_UPDATE the requested update option value return value ECDSTATUS see ECDSTATUS type description. Opening and updating EcdOpen ECDSTATUS FAR PASCAL EcdOpen( lpobject, fShow, hwnd, lpBounds ); This function opens the object. Normally a server will be launched in a separate window, and editing proceeds asynchronously with changes being notified to the client through the CallBack function. The hwnd and lpBounds parameters identify the window and the rectangle within it where the object is displayed in the client. They are used for placement hints for the server's editing window, and possibly for "exploding rectangle" feedback to the user. Name Type Description lpobject LPECDOBJECT a long pointer to the object to be opened fShow BOOL indicates whether to show the window (true, non-zero) or not (false, zero). The latter is useful in conjunction with EcdSetData, so that a client can keep a server active calculating new pictures, but not visible on screen. hwnd HWND the window handle where he object is displayed in the container (may be null). lpBounds LPRECT a long pointer to a RECT structure which contains the coordinates of the bounding rectangle where the object is displayed in the container. May be null. Coordinates are pixels, relative to the window. return value ECDSTATUS see ECDSTATUS type description. EcdQueryOpen ECDSTATUS FAR PASCAL EcdQueryOpen( lpobject ); This function queries whether the object is open. Name Type Description lpobject LPECDOBJECT a long pointer to the object to be queried return value ECDSTATUS see ECDSTATUS type description. returns ECD_OK if the object is open. EcdUpdate ECDSTATUS FAR PASCAL EcdUpdate( lpobject ); This function updates the object so that the presentation is up to date and the object itself is up to date with respect to any other objects it depends on. Name Type Description lpobject LPECDOBJECT a long pointer to the object to be updated return value ECDSTATUS see ECDSTATUS type description. EcdReconnect ECDSTATUS FAR PASCAL EcdReconnect( lpobject ); This function re-establishes the link to a linked object (if it is open) so that the presentation will be kept up to date. If the target object is not open, this call will not open it. Name Type Description lpobject LPECDOBJECT a long pointer to the object to be connected return value ECDSTATUS see ECDSTATUS type description. EcdQueryOutOfDate ECDSTATUS FAR PASCAL EcdQueryOutOfDate( lpobject ); This function queries whether an object (e.g. a linked object) is out of date with respect to some other object. Name Type Description lpobject LPECDOBJECT a long pointer to the object to be queried return value ECDSTATUS see ECDSTATUS type description. EcdClose ECDSTATUS FAR PASCAL EcdClose( lpobject ); This function closes the object if it was open. Name Type Description lpobject LPECDOBJECT a long pointer to the object to be closed return value ECDSTATUS see ECDSTATUS type description. Object handler API specification Overview When an memory object structure is being created, the client library uses the class name of the object to try to locate an object handler for that class. If one is found, the client library loads the handler and calls it to create the object. The handler may create an object where all of the creation functions and methods are defined by the handler, or call default object creation functions in the client library. Using this feature a class may provide special implementation for some or all of the object methods, and defer to the default implementation in cases where that is appropriate. On Windows, creation functions and method functions must be exported and declared "_loadds". Object creation and initialization Library functions which create objects are: EcdLoadFromStream EcdCreateFromClip EcdCreateLinkFromClip EcdCreate EcdCreateFromTemplate Each of these first locates the classname, and looks in the registration service (under the keyword "Handler") for the name of a DLL that contains a handler. If not found, the default creation code in the library is invoked. If a handler is found, the DLL is loaded and entry points for the above creation functions are located (using string names as above with prefix "Ecd" replaced by the prefix "Dll"). These are saved in a table, and the appropriate creation function is called. The handler should declare a table of type ECDOBJECTVTBL (defined below), copy the table from the object returned by the default creation function, and replace pointers to those methods that the handler wishes to preempt in the new method table. Finally, the handler should assign the address of the new method table into the object's pointer. Calls to the client library API are dispatched through the method table, and will be routed either to the client library (if the handler has not overridden that entry) or to the handler-supplied version. The handler may save (on creation) the pointer to the overridden function, and call it from the handler's version if desired. The library exports the default creation functions under the same names but with the prefix "Def" instead of "Ecd". The handler may import and call these. Argument types and semantics are the same for the "Def" functions as for the "Dll" functions. Arguments types and semantics for the latter are the same as for the "Ecd" functions, with the following exceptions: Dll/DefCreateFromClip ECDSTATUS FAR PASCAL DllCreateFromClip ( protocol, lpclient, lplpobject , renderopt, cfFormat, objtype); ECDSTATUS FAR PASCAL DllCreateFromClip ( protocol, lpclient, lplpobject , renderopt, cfFormat, objtype); EcdCreateFromClip calls DllCreateFromClip with an additional argument to tell the library what is being created (object or link) depending on what was found on the clipboard. DllCreateFromClip should pass this and other arguments on to DefCreateFromClip if that is being called, possibly modified as described below. Name Type Description protocol LPSTR the name of the protocol. The handler should verify that it understands this protocol by comparing this argument against the protocol names known to the handler. Currently only the name "StdFileEditing" is defined. This argument should be passed on to DefCreateFromclip. lpclient LPECDCLIENT long pointer to the client structure for the object. lplpobject LPECDOBJECT FAR * long pointer to an LPECDOBJECT variable where the address of the created object should be returned. This can be used in the call to DefCreateFromClip. renderopt ECDOPT_RENDER indicates whether the client requires no rendering, will call the handler to draw the object, or will call GetData to retrieve a rendering in the format selected by the following argument. The handler may give a different value for this argument in calling DefCreateFromClip: for example if the client calls this function with ecdrender_draw, the handler may call DefCreateFromClip with ecdrender_none if the handler will do the drawing based on Native data, or ecdrender_format if the handler will call GetData and do the drawing based on some class-specific format. cfFormat ECDCLIPFORMAT the clipboard format to be retrieved with GetData. The handler may call DefCreateFromClip with some format that the handler wishes to use for rendering. The client library will take care of obtaining the data in the first place, and getting updates from the server. objtype LONG an indication of what is on the clipboard: OT_LINK a link is to be created OT_EMBEDDED an embedded object is to be created. return value ECDSTATUS as for EcdCreateFromClip Dll/DefLoadFromStream EcdLoadFromStream calls DllLoadFromStream with three additional parameters. The handler function should pass these on to DefLoadFromStream if that function is to be called, or may modify them as described below. ECDSTATUS FAR PASCAL DllLoadFromStream( lpstream, protocol, lpclient, lplpobject, objtype, aClass, cfFormat ); ECDSTATUS FAR PASCAL DllLoadFromStream( lpstream, protocol, lpclient, lplpobject, objtype, aClass, cfFormat ); Name Type Description lpstream LPECDSTREAM a long pointer to an ECDSTREAM structure allocated and initialized by the client application. The library will call the Get method in the ECDSTREAM structure to obtain the data for the object. protocol LPSTR see protocol earlier lpclient LPECDCLIENT see lpclient earlier lplpobject LPECDOBJECT FAR * a long pointer to an LPECDOBJECT where the library will store the long pointer to the object objtype LONG as objtype above, except here the client library obtains the nature of the object from the containing stream data. aClass ATOM an atom containing the class name for the object. This should be passed on to DefLoadFromStream. cfFormat ECDCLIPFORMAT The handler may elect to call DefLoadFromStream with a private format that it will use for rendering; the client library will take care of loading and saving this data as well as getting updates from the server. If the handler does not use a special format, it should call DefLoadFromStream with the default value that the handler was called with. return value ECDSTATUS see ECDSTATUS type definition Object methods Object method functions implement the bulk of the library functionality. Arguments and functionality are as defined for the corresponding API function, which has the same name as the method but prefixed by "Ecd". A handler may override any of the method functions, but must supply a semantically equivalent function in order that clients work correctly. ECDOBJECT, ECDOBJECTVTBL, LPECDOBJECT typedef struct _ECDOBJECTVTBL { LPVOID (FAR PASCAL *QueryProtocol)( LPECDOBJECT lpobj, LPSTR lpprotocol ); ECDSTATUS (FAR PASCAL *Delete) ( LPECDOBJECT lpobj ); ECDSTATUS (FAR PASCAL *Show) ( LPECDOBJECT lpobj ); ECDSTATUS (FAR PASCAL *GetData)( LPECDOBJECT lpobj, ECDCLIPFORMAT clipFormat, LPHANDLE lpdata ); ECDSTATUS (FAR PASCAL *SetData ( LPECDOBJECT lpobj, ECDCLIPFORMAT clipFormat, HANDLE hdata ); ECDSTATUS (FAR PASCAL *SetHostNames)( LPECDOBJECT lpobj, LPSTR. LPSTR ); ECDSTATUS (FAR PASCAL *SetTargetDevice) ( LPECDOBJECT lpobj, HANDLE hdata ); ECDSTATUS (FAR PASCAL *SetBounds)( LPECDOBJECT lpobj, LPRECT ); ECDSTATUS (FAR PASCAL *EnumFormats) (LPECDOBJECT lpobj, ECDCLIPFORMAT clipFormat); ECDSTATUS (FAR PASCAL *SaveToStream)(LPECDOBJECT, LPECDSTREAM); ECDSTATUS (FAR PASCAL *Clone)(LPECDOBJECT,LPECDCLIENT, LPECDOBJECT FAR * ); ECDSTATUS (FAR PASCAL *CopyFromLink)( LPECDOBJECT, LPECDCLIENT, LPECDOBJECT FAR * ); ECDSTATUS (FAR PASCAL *Equal) (LPECDOBJECT lpobj) ECDSTATUS (FAR PASCAL *CopyToClipboard) (LPECDOBJECT lpobj); ECDSTATUS (FAR PASCAL *CutToClipboard) (LPECDOBJECT lpobj); ECDSTATUS (FAR PASCAL *QueryBounds) (LPECDOBJECT lpobj, LPRECT lpbounds); ECDSTATUS (FAR PASCAL *Draw) (LPECDOBJECT lpobj, HDC hdc, LPRECT bounds, HDC hFormatDC); BOOL (FAR PASCAL *QueryOpen ) (LPECDOBJECT lpobj); ECDSTATUS (FAR PASCAL *Open) (LPECDOBJECT lpobj, BOOL fShow, HWND hwnd, LPRECT lpbounds); ECDSTATUS (FAR PASCAL *Close )( LPECDOBJECT lpobj); ECDSTATUS (FAR PASCAL *Update) (LPECDOBJECT lpobj, BOOL fShow); ECDSTATUS (FAR PASCAL *Reconnect )( LPECDOBJECT lpobj); ECDSTATUS (FAR PASCAL *QueryOutOfDate) (LPECDOBJECT lpobj); ECDSTATUS (FAR PASCAL *ObjectConvert) (LPECDOBJECT lpobj, LPSTR lpprotocol, LPECDCLIENT lpclient, LPECDOBJECT FAR * lplpobject); } ECDOBJECTVTBL typedef struct _ECDOBJECT{ struct _ECDOBJECTVTBL FAR *vptr; /* server supplied object state goes here */ } ECDOBJECT; Object release The Delete method is used to free the object. Handlers may override this method in order to perform any class-specific termination actions for this object, free any additional resources etc. The handler should call the library-supplied version of Delete from its version if it overrides, and return the status that the library returns. Server API specification Types, Data structures and parameter definitions The server library requires a number of different services from the server application. These are packaged into different structures that the server application creates and makes available to the library. See the client API specification for a description of the general way that these structures are built and used. Structures provided by the server for the library The server application creates memory structures of several types in order to give the library access to the objects that clients know about. These structures model the concepts of server, document, object. At startup, the server application creates a structure of type ECDSERVER and registers it with the library. When a document is opened or created (either by the user or on request from the library), a structure of type ECDDOCUMENT is created and registered (or returned if the library requested it). Since each document may have many links, the library requests creation of a structure of type ECDOBJECT for each, and requests functions based on those. Detailed specification of the methods that must be supplied for server, document and object types are given in the sections following. The library also maintains information for each of these types, which the server applications sees and identifies through opaque (long) handles. The overall model is one of mutual courtesy: the server library maintains the association between its internal structure and that of the server application, and passes both handle (to library info) and pointer (to the application's data structure) in calls to the application. The application in turn is required to remember the library's handle, and pass that in the appropriate calls. LHSERVER, LHDOCUMENT /* definition of handles passed back to the server application from server lib */ typedef LONG LHSERVER; typedef LONG LHDOCUMENT; typedef struct _ECDSERVER FAR *LPECDSERVER; typedef struct _ECDDOCUMENT FAR *LPECDDOCUMENT; /* LPECDOBJECT is defined to be opaque in the client api specification */ /* we give a proper object definition here for servers to implement. */ typedef struct _ECDOBJECT FAR *LPECDOBJECT; API functions and callbacks (methods) Startup and registration If the server application is started normally, it should proceed with its normal default document creation or whatever. If the server is launched with "-Embedding" on the command line, it should not create a document or show a window, but should register with the library (see below) and enter a message dispatch loop and wait for calls from the library to create documents etc. EcdRegisterServer ECDSTATUS FAR PASCAL EcdRegisterServer( classname, lpsrvr , lplhserver, hInst ); At startup, the server application should create a struct ECDSERVER and call this function to register it with the library together with the classname that the server supports. Server that support several classnames may allocate a structure for each or may reuse the same structure as they desire. The classname is passed back to server application functions invoked through the library, so that multi-class servers can distinguish which class is being requested. Name Type Description classname LPSTR the name of the class being registered lpserver LPECDSERVER a long pointer to an ECDSERVER structure allocated and initialized by the server application lplhserver LHSERVER FAR * a long pointer to an LHSERVER where the library will store the handle for its information. The server application should remember this handle and use it for further calls to the library (e.g. EcdRevokeServer) to identify the class/server. hInst HANDLE the instance handle of the server application. This is used to ensure clients connect to the right instance of a server application. return value ECDSTATUS see ECDSTATUS type description. Server Methods The server library will listen for requests from clients, and invoke methods on the server object to create or open documents, etc. These methods must be supplied by the server application and are declared as follows: ECDSERVER, LPECDSERVER struct _ECDSERVERVTBL { ECDSTATUS (FAR PASCAL *Open)( LPECDSERVER lpsrvr, LHDOCUMENT lhdoc, LPSTR documentname, LPECDDOCUMENT FAR * lpdoc ); ECDSTATUS (FAR PASCAL *Create)( LPECDSERVER lpsrvr, LHDOCUMENT lhdoc, LPSTR classname, LPSTR documentname, LPECDDOCUMENT FAR * lpdoc ); ECDSTATUS (FAR PASCAL *CreateFromTemplate)(LPECDSERVER lpsrvr, LHDOCUMENT lhdoc, LPSTR classname, LPSTR documentname, LPSTR templatename, LPECDDOCUMENT FAR * lpdoc ); ECDSTATUS (FAR PASCAL *Edit)( LPECDSERVER lpsrvr, LHDOCUMENT lhdoc, LPSTR classname, LPSTR documentname, LPECDDOCUMENT FAR * lpdoc ); ECDSTATUS (FAR PASCAL *Exit)( LPECDSERVER lpsrvr ); ECDSTATUS (FAR PASCAL *Release)(LPECDSERVER lpsrvr); /*ok to quit */ }; struct _ECDSERVER{ struct _ECDSERVERVTBL FAR* vptr; /* any server supplied state goes here */ }; Open is used to open an existing file and prepare to edit the contents. Save commands should save the changed object back to the original file. Create is used to make a new object of the given classname which is to be embedded in the client application. The documentname parameter will be used to identify the object, but should not be used to create a file for the object. CreateFromTemplate is used to create a new document initialized with the data in the file identified by templatename. As with Create, the document should be treated as untitled, and will be embedded in the client application. Edit is used to create a document to be initialized with the data in a subsequent SetData call. The object is embedded in the client application. In each of these functions, the created document should not be shown to the user for editing until instructed by the library (see below). The Exit function is used to instruct the server application to close documents and shut down. The server should normally comply with this without prompting (e.g. to save modified documents) since this is the client's responsibility. In the case that the server application has opened other documents on request by the user, the server should ignore the request to exit. ECDSERVER: Open ECDSTATUS (FAR PASCAL *Open)( lpsrvr, lhdoc, documentname, lplpdoc ); This function requests the server application to open a named document, allocate and initialize an ECDDOCUMENT structure, associate the library's handle with it, and return the address of the structure in lplpdoc. Name Type Description lpsrvr LPECDSERVER a long pointer to an ECDSERVER structure that was registered by the server application. lhdoc LHDOCUMENT a long handle that the library will use to identify the document internally. documentname LPSTR a null-terminated string containing the permanent name of the document to be opened (normally a pathname, but for some applications this might be further qualified, e.g. a table in a database). lplpdoc LPECDDOCUMENT FAR * a long pointer to an LPECDDOCUMENT where the server application should return a long pointer to the created ECDDOCUMENT structure. return value ECDSTATUS the server should return ECD_OK if all is well. ECDSERVER: Create ECDSTATUS (FAR PASCAL *Create)( lpsrvr,lhdoc,classname,documentname,lplpdoc ); This function requests the server application to create a new document of the specified class, allocate and initialize an ECDDOCUMENT structure, associate the library's handle with it, and return the address of the structure in lplpdoc. The created document is opened for editing by this call and will be embedded in the client when it is closed. Name Type Description lpsrvr LPECDSERVER a long pointer to an ECDSERVER structure that was registered by the server application. lhdoc LHDOCUMENT a long handle that the library will use to identify the document internally. classname LPSTR the string name of the class of document to create documentname LPSTR a null-terminated string containing a name for the document to be created. This name need not be used by the server application, but may be used in window titles etc. lplpdoc LPECDDOCUMENT FAR * a long pointer to an LPECDDOCUMENT where the server application should return a long pointer to the created ECDDOCUMENT structure. return value ECDSTATUS the server should return ECD_OK if all is well. ECDSERVER: CreateFromTemplate ECDSTATUS (FAR PASCAL *CreateFromTemplate)( lpsrvr, lhdoc, classname, documentname, templatename, lplpdoc ); This function requests the server application to create a new document of the specified class, initialized from the content of the document named in "templatename", allocate and initialize an ECDDOCUMENT structure, associate the library's handle with it, and return the address of the structure in lplpdoc. The created document is opened for editing by this call and will be embedded in the client when it is closed. Name Type Description lpsrvr LPECDSERVER a long pointer to an ECDSERVER structure that was registered by the server application. lhdoc LHDOCUMENT a long handle that the library will use to identify the document internally. classname LPSTR the string name of the class of document to create documentname LPSTR a null-terminated string containing a name for the document to be created. This name need not be used by the server application, but may be used in window titles etc. templatename LPSTR the permanent name of the document to use to initialize the new document. Normally a pathname, but may be further qualified. See Open, above. lplpdoc LPECDDOCUMENT FAR * a long pointer to an LPECDDOCUMENT where the server application should return a long pointer to the created ECDDOCUMENT structure. return value ECDSTATUS the server should return ECD_OK if all is well. ECDSERVER: Edit ECDSTATUS (FAR PASCAL *Edit)( lpsrvr,lhdoc, classname, documentname, lplpdoc ); This function requests the server application to create a new document of the specified class, allocate and initialize an ECDDOCUMENT structure, associate the library's handle with it, and return the address of the structure in lplpdoc. The created document will be given its initial data from the client in a following SetData call. Subsequently, the document is opened for editing. Name Type Description lpsrvr LPECDSERVER a long pointer to an ECDSERVER structure that was registered by the server application. lhdoc LHDOCUMENT a long handle that the library will use to identify the document internally. classname LPSTR the string name of the class of document to create documentname LPSTR a null-terminated string containing a name for the document to be created. This name need not be used by the server application, but may be used in window titles etc. lplpdoc LPECDDOCUMENT FAR * a long pointer to an LPECDDOCUMENT where the server application should return a long pointer to the created ECDDOCUMENT structure. return value ECDSTATUS the server should return ECD_OK if all is well. ECDSERVER: Exit ECDSTATUS (FAR PASCAL *Exit)( lpsrvr ); This function is used to instruct the server to exit. The server should close any open documents. If a multiple document server has documents opened by other clients or by user command, it should ignore this call. Name Type Description lpsrvr LPECDSERVER a long pointer to an ECDSERVER structure that was registered by the server application. return value ECDSTATUS see ECDSTATUS type description ECDSERVER: Release ECDSTATUS (FAR PASCAL *Release)( lpsrvr ); This function is used to notify the server application when all connections to the server have closed down and it will be safe to terminate. All registered server structures must be released before the server application can terminate. Shutdown Before exiting, the server application should close all documents (see below) and de-register all server classes by calling the following function. EcdRevokeServer ECDSTATUS FAR PASCAL EcdRevokeServer( lhsrvr ); This function may be called by the application when (e.g.) the user asks the application to exit. The library will close any documents that it opened on behalf of clients, and terminate conversations with them. The library may return ECD_WAIT_FOR_RELEASE if conversations are still in the process of termination, in which case the application should not free the ECDSERVER structure or exit, but should wait (dispatching messages) until a Release call from the library is received. Name Type Description lhsrvr LHSERVER a long handle obtained by calling EcdRegisterServer, indicates which server to revoke. return value ECDSTATUS may be ECD_WAIT_FOR_RELEASE or ECD_OK or some error. Document creation EcdRegisterDocument ECDSTATUS FAR PASCAL EcdRegisterDocument( lhsrvr, documentname,lplhdoc,lpdoc ); When the server application creates or opens a document other than on request from the library, it should register the document with the library in case other clients have links to it. This function is used for this. If the document were created or opened in response to request from the library, it should not be registered through this function but instead the pointer to the document struct should be returned through the parameter to the relevant call. Name Type Description lhsrvr LHSERVER a long handle obtained by calling EcdRegisterServer, indicates which server to revoke. documentname LPSTR the permanent name for the document. Normally a pathname. lplhdoc LHDOCUMENT FAR * a long pointer to a long handle where the library will return the handle by which it identifies the document internally. lpdoc LPECDDOCUMENT a long pointer to an ECDDOCUMENT structure allocated and initialized by the server application. return value ECDSTATUS may be ECD_WAIT_FOR_RELEASE or ECD_OK or some error. Document methods ECDDOCUMENT, LPECDDOCUMENT struct _ECDDOCUMENTVTBL{ ECDSTATUS (FAR PASCAL *Save)( LPECDDOCUMENT lpdoc ); ECDSTATUS (FAR PASCAL *Close)( LPECDDOCUMENT lpdoc ); ECDSTATUS (FAR PASCAL *SetHostNames) (LPECDOBJECT lpobj, LPSTR, LPSTR); ECDSTATUS (FAR PASCAL *SetDocDimensions) (LPECDOBJECT lpobj, LPRECT lpbounds); ECDSTATUS (FAR PASCAL *GetObject)( LPECDDOCUMENT lpdoc, LPSTR itemname, LPECDOBJECT FAR* lpobj, LPECDCLIENT lpclient); ECDSTATUS (FAR PASCAL *Release)(LPECDDOCUMENT lpdoc); /*Finished with document */ }; struct _ECDDOCUMENT{ struct _ECDDOCUMENTVTBL FAR *vptr; /* server supplied document state goes here */ }; Once a document has been created, the library may make calls to it to save it (if it was opened rather than created as an embedded object) or close it. Save should save the state into the file associated with the document. Close should simply close the document without saving or prompting. The document structure and associated resources should be freed. The library will call GetObject to associate a client with the part of the document identified by itemname, where a null itemname (i.e. a null string) means the whole document. Once a client has been connected by this call, the server should be prepared to send notifications as described below. Note that documents opened or created on request from the library should not be shown to the user for editing until the library requests it as described below. ECDDOCUMENT: Save ECDSTATUS (FAR PASCAL *Save)( lpdoc ); This function is used to instruct the server to save the document. Name Type Description lpdoc LPECDDOCUMENT a long pointer to an ECDDOCUMENT that was returned by a method function of a registered server, and which should be saved. return value ECDSTATUS the server application should return ECD_OK if all is well. ECDDOCUMENT: Close ECDSTATUS (FAR PASCAL *Close)( lpdoc ); This function is used to instruct the server application to unconditionally close the document. The server application should not prompt the user to save etc., as that is the responsibility of the client. Name Type Description lpdoc LPECDDOCUMENT a long pointer to an ECDDOCUMENT that was returned by a method function of a registered server, and which should be closed. return value ECDSTATUS the server application should return ECD_OK if all is well. ECDDOCUMENT: SetHostNames ECDSTATUS (FAR PASCAL *SetHostNames)( lpdoc, lpclientname, lpdocname ); This function is used to set names that should be used for window titles etc. These names are only used for embedded objects, as linked objects have their own titles. This call is only used for documents that are embedded objects. Name Type Description lpdoc LPECDDOCUMENT a long pointer to the ECDDOCUMENT that is the embedded object for which names are being specified. lpclientname LPSTR the name of the client lpdocname LPSTR the client's name for the object. return value ECDSTATUS see ECDSTATUS type description lpclientname LPSTR the name of the client lpdocname LPSTR the client's name for the object. return value ECDSTATUS see ECDSTATUS type description ECDDOCUMENT: SetDocDimensions ECDSTATUS (FAR PASCAL *SetDocDimensions)( lpdoc, lpbounds ); This function is used to communicate to the server the size on the target device to which the object should be formatted. The bounds are specified in MM_HIMETRIC units. This call is only relevant for documents that are embedded objects. Name Type Description lpdoc LPECDDOCUMENT a long pointer to the ECDDOCUMENT that is the embedded object for which the target size is being specified. lpbounds LPRECT a long pointer to a RECT structure containing the target size of the object in MM_HIMETRIC units. return value ECDSTATUS see ECDSTATUS type description ECDDOCUMENT: GetObject ECDSTATUS (FAR PASCAL *GetObject)( lpdoc, itemname, lplpobj, lpclient ); This function is used by the library to request an object structure on behalf of a client. The server application should allocate and initialize an ECDOBJECT structure, associate the lpclient pointer with it, and return the pointer through the lplpobj argument. Name Type Description lpdoc LPECDDOCUMENT a long pointer to an ECDDOCUMENT that was returned by a method function of a registered server itemname LPSTR the string name of an item in the specified document for which an object structure is requested. A null item name (i.e. and empty string) implies the entire document, and is the normal case for objects embedded in clients. lplpobj LPECDOBJECT FAR * a long pointer to an LPECDOBJECT where the server application should return a long pointer to the allocated ECDOBJECT structure. lpclient LPECDCLIENT a long pointer to an ECDCLIENT structure allocated by the library, which should be associated with the object and used to notify changes etc. to the library. return value ECDSTATUS the server application should return ECD_OK if all is well. ECDDOCUMENT: Release ECDSTATUS (FAR PASCAL *Release)( lpdoc ); This function is used by the library to notify the server application when a revoked document (see below) has finally terminated conversations and may be destroyed. Name Type Description lpdoc LPECDDOCUMENT a long pointer to an ECDDOCUMENT whose associated LHDOCUMENT was revoked and which may now be released. return value ECDSTATUS the server application should return ECD_OK if all is well. Closing documents When closing a document other than on request from the library, the server application should first de- register all object structures that have been registered with the library, and then de-register the document with the following call: EcdRevokeDocument ECDSTATUS FAR PASCAL EcdRevokeDocument( lhdoc ); This function should be called when a registered document is being closed or otherwise made unavailable for clients. Name Type Description lhdoc LHDOCUMENT a long handle to a document that was returned from EcdRegisterDocument or was associated with a document through one of the server methods that create documents. return value ECDSTATUS may return ECD_WAIT_FOR_RELEASE indicating that the server application should not terminate or free the ECDDOCUMENT structure until a Release notification occurs. This library will return ECD_OK if the document may be freed immediately. Object creation Object structures should be created only on request from the library and should be returned through the parameter to the relevant call. Server Object methods The object structure in the server library is the same as for the object handler, but only the first few methods are called by the server library, and only these need be implemented by the server application. LPVOID (FAR PASCAL *QueryProtocol)( LPECDOBJECT lpobj, LPSTR lpprotocol ); ECDSTATUS (FAR PASCAL *Delete) ( LPECDOBJECT lpobj ); /* Delete is just Release in server, doesn't tell server to destroy data, just free the structure */ ECDSTATUS (FAR PASCAL *Show)( LPECDOBJECT lpobj ); ECDSTATUS (FAR PASCAL *GetData)( LPECDOBJECT lpobj, ECDCLIPFORMAT clipFormat, LPHANDLE lpdata ); ECDSTATUS (FAR PASCAL *SetData ( LPECDOBJECT lpobj, ECDCLIPFORMAT clipFormat, HANDLE hdata ); ECDSTATUS (FAR PASCAL *SetHostNames)( LPECDOBJECT lpobj, LPSTR. LPSTR ); ECDSTATUS (FAR PASCAL *SetTargetDevice) ( LPECDOBJECT lpobj, HANDLE hdata ); ECDSTATUS (FAR PASCAL *SetBounds)( LPECDOBJECT lpobj, LPRECT ); ECDSTATUS (FAR PASCAL *EnumFormats) (LPECDOBJECT lpobj, ECDCLIPFORMAT clipFormat); The library will call Show when the server application should show the document to the user for editing, or to request the server to scroll the document to bring the object into view (if the document is already open). The library will call Delete when no clients are connected to the object. The object structure and associated resources should be freed. ECDOBJECT: Delete ECDSTATUS (FAR PASCAL *Delete)( lpobject ); This function tells the server to free the resources associated with the object structure since no clients are currently connected. It does not tell the server to destroy any data. Name Type Description lpobject LPECDOBJECT a long pointer to the ECDOBJECT to be released return value ECDSTATUS the server should return ECD_OK if all is well. ECDOBJECT: Show ECDSTATUS (FAR PASCAL *Show)( lpobject ); This function tells the server to show the object, showing its window and scrolling if necessary to bring it into view. Name Type Description lpobject LPECDOBJECT a long pointer to the ECDOBJECT to be shown return value ECDSTATUS the server should return ECD_OK if all is well. ECDOBJECT: GetData ECDSTATUS (FAR PASCAL *GetData)( lpobject, cfFormat, lphdata ); This function is used to retrieve data from the object in a specified format. The server application should allocate a memory object of adequate size, fill it with the data, and return it through the lphdata argument. Name Type Description lpobject LPECDOBJECT a long pointer to the ECDOBJECT from which data is requested cfFormat ECDCLIPFORMAT the format in which the data is requested lphdata HANDLE FAR * a long pointer to a memory handle where the server application should return the handle to the allocated memory. The library will free the memory when it is no longer needed. return value ECDSTATUS the server should return ECD_OK if all is well. ECDOBJECT: SetData ECDSTATUS (FAR PASCAL *SetData( lpobject, cfFormat, hdata ); This function is used to store data into the object in a specified format. This function is called (with format Native) when a client opens an embedded object for editing (after a document has been created with the server's Edit method). It is also used if the client calls EcdSetData with some other format. Name Type Description lpobject LPECDOBJECT a long pointer to the ECDOBJECT into which data is to be stored cfFormat ECDCLIPFORMAT the format of the data. hdata HANDLE a memory handle from which the server application should extract the data return value ECDSTATUS the server should return ECD_OK if all is well. ECDOBJECT: SetTargetDevice ECDSTATUS (FAR PASCAL *SetTargetDevice)( lpobject, hdata ); This function is used to communicate information about the client's target device for the object, which can be used by the server to generate a picture formatted for best results on that device. Name Type Description lpobject LPECDOBJECT a long pointer to the ECDOBJECT for which the target device is being specified. hdata HANDLE a handle to a memory object containing a StdTargetDevice structure (see appendix for details under StdTargetDevice) return value ECDSTATUS see ECDSTATUS type description Object release Revoking a document will cause the library to release each object associated with that document. Objects may be explicitly revoked by the server application. EcdRevokeObject ECDSTATUS FAR PASCAL EcdRevokeObject( lpclient ); The server application can call this function to revoke access to an object, for example if the user destroys it. Name Type Description lpclient LPECDCLIENT a long pointer to the ECDCLIENT structure associated with the object which is being revoked. return value ECDSTATUS will be ECD_OK unless the server application passes a bad pointer. Notification The client should notify the library of certain changes to the document. The library may call the object to retrieve new data either immediately (during the notification call) or at a later time (e.g. on request from a client application). Notifications are required when an object changes state, or when certain actions happen to the containing document. The latter actions are saving, closing, renaming. Notification is done through the CallBack function pointer found through the ECDCLIENT structure that is passed to the server when an object structure is created. See the client API section for details of notification function syntax. Note that the library will make callbacks to objects (particularly for rendering data with GetData) from inside the notification call from the server application. Registration Servers that support the compound document protocol register their classes in the system registry. This is a general-purpose system registry that is described in the Registration API section of the Windows SDK documentation. This registry stores key-value pairs, where keys and values are null-terminated strings. Keys are hierarchically structured, with component names separated by "\" characters. To make a server available, the following key-value pairs must be registered during installation of the server. Applications should register the information described in the shell section of the integration guide, which includes extension-classname pairs, a human-readable form for the classname, and associated actions. For this protocol, installing a server application requires that for each class supported by the server, register the classname and server application name resulting in the key-value pairs below. If the class hasa handler, it should be registered with the "Handler" keyword. .classes\.ext = .classes\ = .classes\\protocol\StdFileEditing\Server = .classes\\protocol\StdFileEditing\Handler = Clients check that a class supports this protocol, and retrieve the command line for launching the server, by querying the registry for the last entry above. Pre-release note: As of this version of the specification and pre-release code, the registration database is not in use. In the interim win.ini is used as the registration database. The interim registration scheme described below will be replaced before the product version is released. The relevant parts of the registration API specification are attached to this spec for information. For this interim release, two sections of win.ini are used to store registration information: [StdFileEditing] \Server = \Handler = //optional, handlers only ... [Embedding] =,,,Picture,1 Servers must be registered in the [StdFileEditing] section above. In addition, if powerpoint 2.0 is to be used as a client, the servers must also be registered in the [Embedding] section as described. The keyword Picture indicates to Powerpoint that the server can produce metafiles for the rendering. The magic value 1 indicates that the server supports the StdFileEditing protocol, and is ignored by Powerpoint. Powerpoint Graph supports an earlier, slightly different, version of the protocol and should not have the magic value in the [Embedding] section. Powerpoint 2.0 is compatible with both. Appendix: DDE-based protocol specification Implementation of the compound document protocol requires implementation of the underlying DDE protocol, as specified in the Windows and Presentation Manager documentation. Launching the Server Application When opening a link or an embedded document, the client application should look up the class name in the system registry as above. The client should unconditionally launch the application, passing "- Embedding" as a command line argument. For the interim cases of MDI or single instance applications, the launched program should locate the other instance if available, and send the appropriate command (StdNewDocument, etc). Where necessary for performance, the launched program would be a stub which loads the real application if it must. This approach is adopted rather than putting the burden on the client, to avoid establishing a practice that we may want to change when we move to multiple instances in different workspaces. When the server is given the "-Embedding" parameter, it should not create a new default document, but wait until the client sends the StdOpenDocument (or the StdEditDocument command followed by the Native data) and then instructs the server to show the window. The server may optionally use the StdHostNames item (q.v.) to display the client s name in the window title. When the user closes the document in the server, the client should be re-activated. DDE Conventions This protocol is a set of conventions for use of DDE. All of the standard DDE rules and facilities apply. Applications that conform to this proposal must also conform to the DDE specification. Conforming to this specification implies supporting the System topic, and the standard items in that topic (Topics, SysTopics, etc). Conversations Document operations will be performed in conversation with the application s system topic. The docu- ment ClassName is used to establish conversation. Data transfer and negotiation operations will be performed in conversation with the document (i.e. topic). The document name is used to establish the conversation. Note that the topic name is only use in initiating conversations and is not fixed for the life of the conversation; permitting the document to be renamed (see DocumentName item, below) does not mean that there will be two names. It is therefore reasonable to tie the topic name to the document name. Formats Applications supporting extended DDE use four clipboard formats in addition to the regular data and picture formats: Format Name Structure ObjectLink szClassname,szDocument,szItem,0 OwnerLink szClassname,szDocument,szItem,0 Native Stream of bytes,only parsed by application rendering it, must be self-contained, i.e. the application must be able to completely reconstruct the item from the bytes in the Native format. Binary A stream of bytes whose interpretation is implicit in the item; see StdHostNames, StdTargetDevice, and EditEnvItems items. System Topic Items Topics returns a list of DDE topic names that the server application has open. Where topics correspond to documents, the topic name will be the permanent document name. Protocols returns a list of protocols supported by the application. The list is returned in text format, tab separated. A protocol is a defined set of execute strings and item/format conventions that the application understands. Currently defined is: Protocol: StdFileEditing Commands/items/formats: as in this document. For compatibility with older client applications which do not use the library, server applications written directly to the DDE protocol should also list the name "Embedding" in the list of protocols. Status is a text item which returns "Ready" if the server is prepared to respond to DDE requests, and "Busy" otherwise. This item can be queried to determine if there is any point in offering functions such as "Update link" to the user. It is possible for the server to reject or defer a request even if this item returned "Ready", so client applications should be prepared for this. Standard Item Names and Notification Control New items available on each topic other than the system topic are defined for this protocol. These are: StdDocumentName contains the permanent document name associated with the topic. If no permanent storage is associated with the topic, this item is empty. The item supports both request and advise transactions, and may be used to detect renaming of open documents. EditEnvItems returns a tab-separated list (in text format) of the items carrying envi- ronmental information that the server supports for its documents. Currently defined are StdHostNames, StdDocDimensions and StdTargetDevice. Applications can de- clare other items (and define the interpretations if Binary is to be used) to permit clients that know of them to provide richer information. Servers that cannot use particular items should omit their names from this item. Clients should REQUEST this item to determine which items the server can use, and should supply the data through a DDE POKE message. StdHostNames accepts information about the client application, in Binary format in- terpreted as the following structure: struct { WORD clientNameOffset; WORD documentNameOffset; BYTE data[]; } StdHostNames; The offsets indicate the starting point for the appropriate information in the data array (relative to the start of the data array). StdTargetDevice accepts information about the target device that the client is using. This information is in Binary format, interpreted as the following structure. Offsets are relative to the start of the data array. struct { WORD deviceNameOffset; WORD driverNameOffset; WORD portNameOffset; WORD extDevModeOffset; WORD extDevModeSize; WORD environmentOffset; WORD environmentSize; BYTE data[]; } StdTargetDevice; StdDocDimensions accepts information about the sizes of document that the client is interested in. This information is in Binary format, interpreted as the following structure. struct { WORD defaultWidth; WORD defaultHeight; WORD maxWidth; WORD maxHeight; } StdDocDimensions; The default fields indicate a suggested size for newly created pictures, and the max fields indicate the maximum allowable size (i.e. the page size of the client docu- ment). These measurements are specified in MM_HIMETRICS units. StdColorScheme returns the colors that the server is currently using, and accepts information about the colors that client wants the server to use. This information is in Binary format, interpreted as a Windows LOGPALETTE structure. null is zero length ItemName that specifies a request/advise on the entire data contained in the topic. The update method used for Advises on items follows a convention of appending an update specifier to the actual item name. The item is encoded as follows: / For backward compatibility, omission of the update type results in the same as specifying /Change. may be one of: Change notify each change Save notify when topic is saved Close notify when file closed DDE server applications are required to remember each occurrence of an Advise that specifies a unique tuple . Notifications are disabled by a DDE UnAdvise message with corresponding parameters. Standard Commands in DDE Execute Strings The syntax for standard commands sent in execute strings is as defined in the DDE manual: [command(argument1,argument2,..)][command2(arg1,arg2)] Commands without arguments do not require (). String arguments must be enclosed in double quotes Commands that must be supported by server applications are defined in the following sections. StdNewDocument(ClassName,DocumentName) Creates a new, empty document of the given class, with the given name, but does not save it. The server should not show the window until a StdShowItem command is received. The server should return an error if the DocumentName is already in use, and the client should generate another name and try again. StdNewFromTemplate(ClassName,DocumentName,TemplateName) Creates a new document of the given class with the given DocumentName from the template with the given permanent name (i.e. filename). StdEditDocument(DocumentName) Creates a document with the given name, and gets ready to accept data to be poked into it using WM_DDE_POKE. The server should not show the window until a StdShowItem command is received. The server should return an error if the DocumentName is already in use, and the client should generate another name and try again. StdOpenDocument(DocumentName) Sent to system topic. Opens an existing document with the given name. The server should not show the window until a StdShowItem command is received. The above three commands all make the document available for DDE conversations with the name DocumentName. They do not show any window associated with the document; the client must send a StdShowItem command to make the window visible. This enables the client to negotiate additional parameters (e.g. StdTargetDevice) with the server without causing extraneous repaints. StdCloseDocument(DocumentName) Sent to the system topic. Closes down the window associated with the document. Following acknowl- edgement, the server terminates any conversations associated with the document. The server should not activate the window in the process of closing it. StdSaveDocument(DocumentName) Sent to System conversation. Saves the named document. Preserves the same name. The server should not activate the window in the process of saving it. StdShowItem(DocumentName,ItemName [, fTakeFocus] ) Sent to the system topic, this command makes the window containing the named document visible, and scrolls to show the named item if it is not null. The optional third argument indicates whether the server should take focus and bring itself to the front or not. The value of this argument shouldbe the literal TRUE indicating take focus or FALSE indicating not. If the argument is not present, TRUE is assumed. StdExit Shuts down the server application. This command should only be used by the client application that launched the server. This command is available in the system topic only. The following variants of the above commands may be sent to the document topic rather than the system topic, so that the client does not have to open an additional conversation to the system if it already has a conversation with the document. The document name is omitted from these commands because it is implied by the conversation topic, and because it may have been changed by the server. This kind of name change does not invalidate the conversation, and the client should not be forced to track the change to the name unnecessarily. The implication is that the server must be able to identify the document to be operated on from the conversation information. StdCloseDocument Sent to document conversation. Closes the document associated with the conversation without activating it. This command causes a DDE terminate to be posted by the server window following the acknowledgement. StdSaveDocument Sent to document conversation. Saves the document associated with the conversation. Preserves the same name. Should not activate the window or show any confirmation dialog. StdShowItem(ItemName [, fTakeFocus] ) Sent to document conversation. Shows the document window, scrolling if necessary to bring the item into view. A null item name does not cause scrolling. The optional third argument indicates whether the server should take focus and bring itself to the front or not. The value of this argument shouldbe the literal TRUE indicating take focus or FALSE indicating not. If the argument is not present, TRUE is assumed. An example: opening an object for editing When the client application calls the client library to open the object, the library behaves (asynchronously) as follows. Note that the ClassName, DocumentName and item name are components of the link descriptor. Note also that in the case of a link, the client first attempts to locate the document in case it is already open in another application. if (already open) return if (item is a link) Attempt to initiate conversation with ClassName, DocumentName pair if (connected) ADVISE on StdDocumentName ADVISE on item, desired format, update type else query system registry for ClassName to identify editor application if (item is link to another document) launch the editor with -Embedding argument establish conversation with ClassName, System send StdOpenDocument( DocumentName ) establish conversation with the document topic for each of StdTargetDevice, StdDocDimensions that are listed in EditEnvItems item POKE relevant values ADVISE on StdDocumentName item in case server renames the document ADVISE on item, desired format, update type as specified in link send ShowItem command else // item is embedded object launch the editor with -Embedding command line option establish a DDE conversation with system topic send StdEditDocument command with client-supplied unique name for the document if edit command fails, try to make another non-conflicting name. //The server s Topics item can be of help. establish conversation with the new document POKE the native data for each of StdHostNames, StdTargetDevice, StdDocDimensions that are listed in EditEnvItems item POKE relevant values ADVISE on item, desired format, update on close. send ShowItem command remember server was started by this client "Convert" is a word we have used in our discussions to describe the process of making a "non-object" from an object, usually by extracting the objects content (data) without preserving any of its behavior or presentation. Note that the model described here is not intended to replace conversion as a way of moving data from one application to another. The term "convert" is also used to describe the process of transforming an object of one type into an object of another type. Users exercise control over this delay through "update rules" associated with the reference. (See Part 2.) An object s presentation may be supplied by the object (e.g., a metafile or bitmap) only when the object is changed; or it may be generated by interaction between the object and the container (e.g., the container executes display code provided by the object, usually as a DLL or other non-application code resource) each time the object s presentation is redrawn. I.e., all tables in a given word processor exhibit exactly the same selection behavior, regardless of whether they are presentations of data links to spreadsheets. E.g., in a table that is the presentation of a spreadsheet range, users may select individual cells, but not the text within the cell. For example, changing the format of an entry in a table that presents a spreadsheet is allowed, changing the value in the cell is not. I.e., editors should initially hide the portions of an object that are not displayed in the container. is replaced by text that describes the selected item. This dialog will evolve into an object property sheet in future interfaces. Currently, however, this dialog displays only those properties related to the linked- or embedded-ness of the object or reference, and to its presentation in the container. A link in a document to a spreadsheet range would, for example, have a link properties dialog with the word processor s usual formatting controls while an embedded graph in a presentation might have an object properties dialog with additional controls for recoloring, sizing, and cropping. Note that this requires that containers maintain the original copy of an embedded object throughout the entire editing session; specifically, containers must preserve this information through updates from the editor. Note that in order to make the changes to the object persistent, the container must be saved. The new object is, of course, inserted at the location that was the current selection at the time the "Insert New Object..." command was executed. Note, however, that this may no longer be the current selection in the container at the time the "File- Update" command is executed in the editor. This strangeness is forced by the nature of DDE and its use here to communicate with server applications. "Devotees of object-oriented programming will realize what is going on here" (stolen from David Rosenthal). This technique can be fully understood (and will be implemented) in terms of C language features and conventions. Compound Document Protocol Extensible Application Protocols Printed: 12/3/90 61 12/2/90 Compound Document Protocol Extensible Application Protocols Printed: 12/3/90 73 12/2/90