 Microsoft Window's - WLO








 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
                         Microsoft(R) Window's - WLO

                                 Version 3.0
 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ




  Information in this document is subject to change without notice and does
 not represent a commitment on the part of Microsoft Corporation. The
 software and/or databases described in this document are furnished under a
 license agreement or nondisclosure agreement. The software and/or databases
 may be used or copied only in accordance with the terms of the
 agreement. The purchaser may make one copy of the software for backup
 purposes. No part of this manual and/or database may be reproduced or
 transmitted in any form or by any means, electronic or mechanical,
 including photocopying, recording, or information storage and retrieval
 systems, for any purpose other than the purchaser's personal use, without
 the written permission of Microsoft Corporation.


 (C) Copyright Microsoft Corporation, 1990. All rights reserved.

 Printed in the United States of America.


 Patent #4,825,358

 Patent #4,779,187


 Microsoft(R), MS(R), MS-DOS(R), the Microsoft logo, and InPort(R)
 are registered trademarks, and Windows(tm) is a trademark, of Microsoft
 Corporation.


 SideKick(R) is a registered trademark of Borland International, Inc.


 IBM(R), PC/AT(R), and PS/2(R) are registered trademarks of
 International Business Machines Corporation.






 Chapter 1  Overview and Installation

      1.1   Introduction
      1.2   System Requirements
      1.3   Software Requirements
      1.4   Disk Contents
      1.5   WLO Development Kit Installation
      1.6   Conversion Tools

 Chapter 2  Converting Applications

      2.1   Introduction
      2.2   The WLO Mapping Layer
      2.3   Building Converted Applications
      2.4   Building Converted Dynamic-Link Libraries
      2.5   Debugging
      2.6   Adding OS/2 Features
      2.7   Shipping a Converted Application

 Chapter 3  Limitations on Converted Applications

      3.1   Overview
      3.2   Mixed OS/2 and Windows Graphics
      3.3   Differences in Windows Graphics Functions
      3.4   Windows Sound and Profile Functions
      3.5   EMS and XMS Support
      3.6   Exported Selectors and Port Input and Output
      3.7   Multiple Instances of the Same Application
      3.8   Hook Procedures for System Hooks
      3.9   Windows Debugging Features
      3.10  File Access and Compatibility Mode in OS/2
      3.11  OpenFile Return Value
      3.12  Menus in OS/2
      3.13  TextOut Limitations
      3.14  SetMessageQueue and Code Pages
      3.15  Unsupported Windows Functions
      3.16  BIOS/DOS Interrupts
      3.17  Real-Mode C Run-time Functions



 Chapter 1  Overview and Installation
 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ




 1.1  Introduction

 The Microsoft(R) Windows(tm) Libraries for OS/2 Development Kit (the WLO
 Development Kit) provides a set of software tools you can use to build
 Operating System/2 Presentation Manager applications from Microsoft Windows
 version-3.0-compatible source code. The WLO Development Kit offers a fast
 and easy conversion path from Windows to OS/2 Presentation Manager. It also
 enables you to enhance Windows applications with OS/2 features.

 This manual, the Microsoft Windows Libraries for OS/2 Programmer's Guide,
 describes the WLO Development Kit, provides instructions for installing the
 WLO Development Kit software, and briefly explains the conversion process.
 In addition, the manual discusses limitations on converting applications and
 describes the WLO Development Kit sample applications and dynamic-link
 libraries.

 Typically, converting an application from Windows to OS/2 requires
 significant changes throughout the source code, including function-name
 alterations and parameter and message reordering. The WLO Development Kit
 simplifies this process, enabling you to produce a Presentation Manager
 version of your application quickly and with minimal development effort. In
 some cases, all you need to do is relink your application with the WLO
 import libraries and then bind the Windows version 3.0 resources to the
 newly relinked executable file, using the Windows version 3.0 Resource
 Compiler. Usually, you will not have to recompile the source code or
 resource file.

 Applications converted with the WLO Development Kit will run as Presentation
 Manager applications with OS/2 versions 1.21 and later. After using the WLO
 Development Kit, you will have two versions of your application: the
 original Windows version and the converted version that runs with OS/2.

 This WLO Development Kit provides libraries and mapping-layer dynamic-link
 libraries for use with OS/2 version 1.21. These libraries map Windows
 functions into their corresponding OS/2 functions, allowing your Windows
 application to run as a Presentation Manager application. Although relinking
 your application is the simplest conversion method, you can also change your
 application source code to take advantage of OS/2-specific features such as
 multitasking and improved memory management.

 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
 Note

 This WLO Development Kit provides a stable mapping layer on which to base
 released products. However, since the product is not yet in its final form,
 it may still contain some inconsistencies with Windows version 3.0. It is
 strongly recommended that, before releasing your relinked WLO application,
 you thoroughly test it on the target OS/2 system, using the dynamic-link
 libraries in the WLO mapping layer. If you encounter few or no problems, you
 may decide to work around the problems or wait for a subsequent release of
 the WLO Development Kit. In either case, please report any difficulties or
 problem areas by means of your Microsoft OnLine account.
 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ




 1.2  System Requirements

 To run the WLO Development Kit software, you must have the following minimum
 system-hardware configuration. You may use either the DOS or the OS/2
 development environment.

 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
 Note

 Microsoft documentation uses the term "OS/2" to refer to the OS/2 systems
 developed jointly by Microsoft and IBMÄMicrosoft Operating System/2 (MS(R)
 OS/2) and IBM OS/2. Similarly, the term "DOS" refers to the MS-DOS(R) and
 IBM PC-DOS operating systems. The name of a specific operating system is
 used when it is necessary to note features that are unique to that system.
 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ



 DOS Development Environment


   ž   An Industry Standard Architecture (ISA) computer such as the IBM PC/AT
       and compatible computers; a Micro Channel Architecture (MCA) computer
       such as the IBM PS/2 and compatible computers; or an Extended Industry
       Standard Architecture (EISA) computer

   ž   At least 640 kilobytes of memory

   ž   A hard disk (30 megabytes or greater)

   ž   A disk drive capable of using 5.25-inch 1.2-megabyte disks or 3.5-inch
       1.44-megabyte disks



 OS/2 Development Environment


   ž   An Industry Standard Architecture (ISA) computer such as the IBM PC/AT
       and compatible computers; a Micro Channel Architecture (MCA) computer
       such as the IBM PS/2 and compatible computers; or an Extended Industry
       Standard Architecture (EISA) computer

   ž   At least 4 megabytes of memory

   ž   A hard disk (40 megabytes or greater)

   ž   A disk drive capable of using 5.25-inch 1.2-megabyte disks or 3.5-inch
       1.44-megabyte disks




 1.3  Software Requirements

 To run the WLO Development Kit software, you must have the following
 additional software. You may use either the DOS or the OS/2 development
 environment.

 DOS Development Environment


   ž   DOS version 3.0 or later

   ž   Microsoft Windows Software Development Kit (SDK) version 3.0

   ž   Microsoft(R) C Optimizing Compiler version 5.1 or 6.0



 OS/2 Development Environment


   ž   Microsoft Windows Software Development Kit (SDK) version 3.0

   ž   Microsoft C Optimizing Compiler version 5.1 or 6.0

   ž   OS/2 version 1.21 or later

   ž   Microsoft OS/2 Presentation Manager Toolkit version 1.2 (strongly
       recommended)




 1.4  Disk Contents

 The complete set of WLO tools, libraries, and sample code is included in
 both 5.25-inch and 3.5-inch disk formats. For a list of all the WLO
 Development Kit files and their exact descriptions and locations, see the
 PACKING.LST file on Disk 1.


 1.5  WLO Development Kit Installation

 To install the WLO Development Kit, you use the Setup program found on Disk
 1. The Setup program, which runs with either DOS or OS/2, installs the WLO
 Development Kit on your hard disk.

 The WLO Development Kit is designed to work in tandem with the Windows
 Software Development Kit version 3.0 and the C compiler tools and libraries.
 In Windows, real-mode versions of the C run-time libraries are used; WLO
 applications rely on equivalent protected-mode libraries. The Setup program
 builds and installs the appropriate memory models of the WLO C run-time
 libraries that you require. You may rerun Setup at any time to build
 additional memory-model WLO C run-time libraries without reinstalling the
 entire WLO Development Kit. Setup also provides an option for library
 installation only.

 Various system setups are possible and affect the installation of the WLO
 Development Kit. Since you can convert your application in either a DOS or
 an OS/2 development environment, your installation choice depends on your
 development plans. If you are interested in doing a simple conversionÄwith
 no additional OS/2 featuresÄfollow the instructions in Section 1.5.1, "DOS
 Installation." If you currently do your Windows version 3.0 development on
 an OS/2 system or plan to add OS/2-specific features, follow the
 instructions in Section 1.5.2, "OS/2 Installation."


 1.5.1  DOS Installation

 To install the WLO Development Kit on a DOS system, follow these steps:

   1.  Be sure that the Windows Software Development Kit version 3.0 and the
       Microsoft C Optimizing Compiler (version 5.1 or 6.0) are installed.

   2.  Insert Disk 1 in drive A.

   3.  Move to drive A by typing the following, and then press the ENTER key:

 a:


   4.  Type the following, and then press ENTER:

 setup

       Follow the directions provided in the Setup program for building the
       WLO import and C run-time libraries.

   5.  Modify the LIB and BIN environment variables in the CONFIG.SYS file so
       that they reference the directories \eWLO\eLIB and \eWLO\eBIN,
       respectivelyÄas in the following example:

 set LIB=c:\wlo\lib;...
 set BIN=c:\wlo\bin;...



 After Setup is finished installing the WLO Development Kit on the DOS
 system, rerun Setup on the target OS/2 system to install only the WLO
 mapping-layer dynamic-link libraries. (Setup provides an option for doing
 this.) Then follow the instructions provided in Setup.

 After relinking the Windows application with the WLO import and C run-time
 libraries on the DOS system, test it on the destination OS/2 system.


 1.5.2  OS/2 Installation

 It is common to develop Windows applications with OS/2. The advantage of
 using the WLO Development Kit with OS/2 is that you can do the normal
 edit-compile-debug cycle on the same system, which is useful if you are
 planning to enhance your Windows application by adding calls to OS/2
 functions.

 The Microsoft C Optimizing Compiler provides tools that function in both DOS
 and OS/2. (The Windows Software Development Kit version 3.0 also provides
 such tools.) Only Windows Dialog Editor, Icon Editor, and Font Editor
 require that Windows be present. If you must use these tools, then you must
 run Windows either in the DOS session of OS/2, in DOS itself (as started
 from dual boot), or on another system. The Presentation Manager versions of
 these tools do not create Windows-compatible resources.

 To install the WLO Development Kit on an OS/2 system, follow these steps:

   1.  Be sure that the Windows SDK version 3.0 and the Microsoft C
       Optimizing Compiler (version 5.1 or 6.0) are installed.

   2.  Insert Disk 1 in drive A.

   3.  Move to drive A by typing the following, and then press the ENTER key:

 a:



   4.  Type the following, and then press ENTER:

 setup

       Follow the directions presented in the Setup program for building the
       WLO import and C run-time libraries.

   5.  Modify the LIB and BIN environment variables in the CONFIG.SYS file so
       that they reference the directories \eWLO\eLIB and \eWLO\eBIN,
       respectivelyÄas in the following example:

 set LIB=c:\wlo\lib;...
 set BIN=c:\wlo\bin;...



   6.  Modify the LIBPATH variable in CONFIG.SYS to include the directory
       \eWLO\eDLL\eDEBUG. Alternatively, copy the contents of this
       dynamic-link library directory into the directory \eOS2\eDLL on drive
       C.

   7.  Before running the relinked application, use OS/2 Control Panel to
       install the WLO fonts located in the directory \eWLO\eBIN on the
       destination OS/2 system.




 1.6  Conversion Tools

 The WLO Development Kit provides several tools to assist in the conversion
 of Windows applications. The following sections describe these tools and how
 they are used.


 1.6.1  The Convicon Tool

 The Convicon tool converts a Windows icon to a Presentation Manager icon. It
 takes an icon file  CREATED BY WINDOWS ICON EDITOR AND PRODUCES A
 resource file (.RES) that is compatible with Presentation Manager. This
 capability is useful for WLO applications for which you want to display
 icons in OS/2 Desktop Manager group windows and in OS/2 File Manager.
 Windows icons are not compatible with Presentation Manager icons, therefore
 OS/2 displays the default application icon for any WLO application that has
 Windows icons.

 There are two ways to add a Presentation Manager icon to your WLO
 application. If you have the MS OS/2 Presentation Manager Toolkit version
 1.2, you can create a Presentation Manager icon resource by using MS OS/2
 Icon Editor. Alternatively, you can create an icon with the Windows Icon
 Editor and convert it to Presentation Manager format with Convicon. Both
 methods produce an icon file compatible with Presentation Manager.

 Once you have converted the icon file, you attach it to the WLO executable
 file (.EXE file) as an  ON ATTRIBUTE, ONE OF MANY OS/2 EXTENDED
 ATTRIBUTES

 (EA). There are two ways to accomplish this:

 Method 1

 Use MS OS/2 File Manager. Follow these steps:

   1.  Start File Manager.

   2.  Select the WLO application file to attach the icon to.

   3.  Choose the Properties command in the File menu. The command displays a
       dialog box.

   4.  Click the Icon button.

   5.  Type the full path and filename of the converted icon file in the text
       box.

   6.  Click the OK button. The command attaches the icon as an extended
       attribute to the selected application.



 Method 2

 Use Wloinst, a stand-alone utility provided with the WLO Development Kit.
 The Wloinst utility attaches the icon, producing the same result as would
 using File Manager, but it can be "bundled" in your application's
 installation program. Wloinst, which consists of several installation helper
 routines, can also install the WLO mapping-layer dynamic-link libraries. For
 more information about installing these libraries, see Chapter 2,
 "Converting Applications."

 The following example shows how to use Wloinst to attach a Presentation
 Manager icon file to an executable file. For this example, assume that the
 executable file, APPNAME.EXE, and the icon file, APPNAME  ®O, HAVE ALREADYÆ

 been copied to the APPS directory on drive C.

 wloinst -i c:\apps\appname


 Note that the -i switch takes only a drive name and path (C:\eAPPS) and a
 root filename (APPNAME). The root filename must consist of 1 to 8 characters
 and must be the same for both the application's executable file and its icon
 file.

 Wloinst attaches APPNAME  O AS AN EXTENDED ATTRIBUTE TO APPNAME.EXE. NOW,
 when you add the application to a Desktop Manager group window, OS/2
 displays the icon.

 Once you attach a converted icon to the WLO application file, use the OS/2
 copy command to make copies of the application file. This command copies the
 icon as well as the file, so each new file has its own icon. In the
 installation program for the application, use the OS/2 API function DosCopy
 to ensure that the attached icon is copied with the application file during
 installation. It is also possible to use Wloinst to attach an
 extended-attribute icon after the application's .EXE file has been copied to
 the hard disk.

 The following example shows how to convert a Windows icon file WINICON  O
 to a Presentation Manager icon file PMICON  O:

 convicon winicon.ico pmicon.ico



 This command creates a new icon file in the Presentation Manager format. You
 can then attach the new icon file to an application file.


 1.6.2  The Convfont Tool

 Windows and OS/2 use different font-file formats. The Convfont tool takes a
 Windows OS/2 Control Panel to install the new Presentation Manager
 application, including applications converted with the WLO Development Kit.
 Convfont is provided for those Windows applications that depend on specific
 custom Windows fonts.

 In addition to converting Windows can generate with the MS OS/2 Presentation
 Manager Toolkit version 1.2).

 To convert a Windows font, use a command of the following form:

 convfont Windows-file.fon Presentation_Manager_fontname

 For example, the following command line generates a Presentation Manager

 convfont tmsre.fon times.

 --------------------------------->>> MISSING TEXT???
 OS/2 requires that the module name (which is set internally by Convfont) in
 the font file be the same as the base name of the font file. You cannot
 rename the
 --------------------------------->>> MISSING TEXT???

 To generate the component -f switch:

 convfont -f tmsre.fon times



 This command generates TIMESTIMES00included in the TMSREtaking the first
 five characters of the font name and adding a two-digit number to them.

 Convfont may issue the following warnings:

 Message                           Meaning
 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

 FACE NAME TOO LONG                The face name will be truncated.

 FONT TOO LARGE                    The font will not be converted.

 STRANGE FONT CHARACTERISTICS      Some font characteristics are
                                   contradictory or too large. These
                                   characteristics will be converted, but
                                   the resulting font may be corrupted.



 1.6.3  The Convdll Tool

 The Convdll tool helps convert Windows dynamic-link libraries to
 dynamic-link libraries compatible with OS/2. Convdll adds code to your
 Windows dynamic-link library so that the WLO Development Kit can keep track
 of links and "unlinks" to the dynamic-link library. Convdll also rearranges
 registers so that the library is initialized correctly. For more details on
 how to use Convdll, see Chapter 2, "Converting Applications."





 Chapter 2  Converting Applications
 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ




 2.1  Introduction

 This chapter explains the Windows Libraries for OS/2 mapping layer and
 describes the process of converting a Windows application or dynamic-link
 library so that it will run with OS/2.


 2.2  The WLO Mapping Layer

 The WLO Development Kit provides a run-time translation layer, called the
 mapping layer, which maps Windows functions into OS/2 functions. Internally,
 the application operates as if it were running with Windows, while
 externally, it looks, feels, and operates like a Presentation Manager
 application.

 Windows and OS/2 share architectural design characteristics that make it
 possible to map Windows functionality into OS/2. (You need not rely on
 virtualization or emulation.) Windows and OS/2 rely on similar concepts of
 dynamic linking, resource management, and windowing. Specifically, Windows
 and OS/2 share an executable file format known as the "new" executable file
 format (new as compared with the DOS executable file format).

 The Windows and OS/2 loaders operate similarly in the way they dynamically
 fix up references to routines in dynamic-link libraries (such as system
 functions). The way the loaders manipulate resources is also similar.
 Because OS/2 directly supports the mechanics of loading Windows executable
 files, the mapping layer need only translate Windows functions into their
 OS/2 equivalent operations.

 By using the WLO Development Kit, you can create (by linking) 16-bit OS/2
 applications that rely on OS/2 dynamic-link-library counterparts to the
 Windows system dynamic-link libraries: GDI, KERNEL, USER, KEYBOARD, SYSTEM,
 and SOUND. Some Windows functions can be mapped one-to-one with their direct
 OS/2 equivalents. Other functions are simply "stubbed out," as is the case
 for the sound functions, which have no OS/2 equivalents. For a complete list
 of unsupported functions, see Chapter 3, "Limitations on Converted
 Applications." For the remaining functions, the mapping layer retains
 context information across multiple Windows functions. Window handles,
 device contexts, resources, and so forth, are managed by the mapping layer
 in such a way that the relinked application behaves as if it were running
 with Windows even though it is running with OS/2.


 2.2.1  Interrupt Support

 Presentation Manager applications cannot call system interrupts directly.
 WLO applications must also follow this rule. During the WLO conversion
 process, you must replace all such direct interrupt calls with their
 equivalent system functions. You should change all direct Interrupt 21H
 calls or other direct system interrupts to their equivalent C run-time or
 OS/2 functions, or to the new Windows version 3.0 function Dos3Call. You
 should also use the Windows version 3.0 function NetBiosCall instead of
 using network-related interrupts. For an example of how to use the Dos3Call
 function to replace direct interrupt calls, see the sample Clock application
 provided with the WLO Development Kit.

 The WLO relinking process uses the WLO customized protected-mode C run-time
 libraries instead of the real-mode Windows versions. These libraries use
 appropriate OS/2 functions for operating-system services. Windows version
 3.0 also provides system functions such as _lopen, _lclose, _lread, _lwrite,
 as well as the new function, Dos3Call. These functions are also remapped to
 their OS/2 equivalents in the WLO mapping layer and in protected-mode
 libraries. This remapping means that the new Windows functions and the
 operating-system-level functions in the C run-time libraries are safe to use
 in OS/2 versions 1.21 and later.

 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
 Note

 Be wary of third-party libraries that may make direct system-interrupt
 calls: with OS/2 version 1.21, applications (running at protection ring 3)
 generate a general protection fault if they attempt to make software
 interrupts.
 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ




 2.2.2  Windows Resources

 The WLO mapping layer can correctly load and display Windows resources, so
 no changes are required for an application's resources. After relinking the
 Windows application with the libraries in the WLO Development Kit, use
 Windows Resource Compiler to bind any resources used by the application.

 Presentation Manager and Windows resources are incompatible; neither the
 Windows nor the OS/2 resource compiler can use the other system's resource
 definitions. You must use Windows Resource Compiler to create Windows
 resources.


 2.2.3  Windows Font Support

 OS/2 provides three type faces (Helv, Tms Rmn, and Courier) in various
 raster sizes, as well as scalable vector fonts (also known as outline
 fonts). The system font (used in menus, title bars, etc.) is proportional,
 as it is in Windows version 3.0. The WLO Development Kit provides two
 Windows fonts that have been converted into OS/2-compatible fonts. Both
 fonts are located in the \eWLO\eBIN directory and are described in the
 following list:

   ž   WINMONO  dependent on the fixed-pitch-font support in earlier releases
       of Windows. You may find this font a useful alternative to the OS/2
       Courier font.

   ž   WINPRO  boxes. The WLO mapping layer automatically uses this font for
       dialog boxes of converted applications.


 The user must install these fonts (by using OS/2 Control Panel) on the OS/2
 system that will run the converted application. For more information about
 installing fonts with Control Panel, see the Microsoft Operating System/2
 User's Guide.

 The WLO Development Kit provides the Convfont tool to convert other Windows
 fonts to OS/2-compatible fonts. If your Windows application uses special
 fonts, you can convert them to the OS/2 format. The Windows function
 AddFontResource must refer to an OS/2 font when used in a converted
 application running with OS/2.


 2.2.4  Windows Help Support

 Windows Help Manager, WINHELP.EXE, has been converted to run with OS/2. It
 is included with this release of the WLO Development Kit in the directory
 \eWLO\eHELP. To use Help Manager, your application can call the normal
 Windows Help functions. You must ship a copy of WINHELP.EXE with your
 product.


 2.2.5  Global-Memory Support

 Windows global-memory-allocation functions (GlobalAlloc, GlobalRealloc,
 etc.) are mapped to OS/2 functions such as DosAllocSeg and DosAllocHuge.
 Your converted application thus has access to the full memory resources of
 OS/2.

 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
 Note

 The Windows 32-bit memory manager WINMEM32.DLL is not supported by the WLO
 Development Kit.
 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ




 2.2.6  Task-Switching Support

 A Windows version 3.0 application is expected to relinquish control of the
 CPU only when its message queue is empty when the application calls the
 GetMessage or PeekMessage function. This controlled, or cooperative,
 nonpreemptive multitasking enables Windows applications to ignore certain
 synchronization and resource conflicts that can occur in a preemptive
 multitasking system such as OS/2. For example, consider a Windows
 application that shares access to a dynamic-link library with other Windows
 applications running with the Windows (DOS) environment. You can assume that
 when the first application accesses the shared library, all other
 applications have given up control of the CPU (and the resources of the
 shared dynamic-link library) voluntarily by calling GetMessage or
 PeekMessage. You can also assume that the dynamic-link library will be able
 to complete the function request and return control to the calling
 application before control is given to any other application. Therefore,
 there is no need to guard shared resources with semaphores in Windows
 version 3.0.

 In OS/2, however, a task switch can occur at any time, so there is no
 guarantee that the dynamic-link library will be able to complete the first
 request before another application gains control and makes a new request.
 Clearly, this can cause problems within the dynamic-link library.

 Since a native OS/2 application or dynamic-link library can lose control of
 the CPU at any time, it is especially important to maintain some sort of
 synchronization control within a shared dynamic-link libraryÄfor example, by
 setting a semaphore when beginning to service a request and ignoring all
 other requests until the original request is completed.

 To protect converted Windows applications, the WLO mapping layer will
 preemptively suspend only one WLO application to schedule another WLO
 application when one of the applications calls the GetMessage or PeekMessage
 function. This means that a converted Windows application will lose control
 of the CPU just as it would when running with Windows. Thus, you typically
 do not have to add any OS/2-specific synchronization code to your Windows
 application or dynamic-link library.


 2.2.7  Floating-Point Support

 Windows provides floating-point support with the WIN87EM.DLL dynamic-link
 library. OS/2 handles floating-point calculations differently than Windows
 does. The protected-mode C run-time libraries provide emulation when the
 relinked Windows application is run on an OS/2 version 1.21 system that does
 not have a coprocessor installed.


 2.2.8  Clipboard and Dynamic-Data-Exchange Support

 The WLO mapping layer provides full clipboard data transfer between
 converted Windows applications and OS/2 applications, including two-way
 metafile conversion between the Windows and OS/2 metafile formats. (For
 metafiles, the mapping layer automatically converts a metafile when the
 application copies it from the clipboard.) The mapping layer also supports
 dynamic data exchange (DDE) between WLO applications and between an WLO
 application and a native OS/2 application. Be aware, however, that OS/2
 supports fewer predefined DDE data formats than Windows does.

 WLO applications can exchange text information with Presentation Manager
 applications through the clipboard and DDE. To prevent conflicts between
 character sets and code pages, the mapping layer automatically translates
 text information between the Windows ANSI (1004) code page and the active
 Presentation Manager code page. For more details about using different code
 pages, see Section 2.6.6, "Using Different Code Pages." .ET


 2.2.9  Printing Support

 The mapping layer uses the OS/2 printer drivers to support printing. To a
 Windows application, an OS/2 printer driver looks just like a Windows
 printer driver. A converted application can print on all printers available
 to OS/2, but since OS/2 currently supports fewer printers than Windows
 version 3.0 does, the application cannot necessarily print on all printers
 available to Windows. Neither OS/2 nor the WLO Development Kit supports
 installing or emulating Windows printer drivers.


 2.2.10  Device-Driver Support

 Windows supports several types of device drivers. In general, OS/2 does not
 support these drivers, since the device-driver models in DOS and Windows are
 incompatible with those in OS/2. The WLO Development Kit cannot convert
 device drivers. You need to replace most device drivers with their
 equivalent OS/2 device drivers. In some cases, you can use an existing OS/2
 driver, but for more specialized services, you may need to write your own.
 For information about writing OS/2 device drivers, consult the Microsoft
 OS/2 Device Driver Development Kit. .RT


 2.2.10.1  Display and Printer Device Drivers

 Windows display and printer device drivers are implemented as dynamic-link
 libraries (although they may have a .DRV extension). The WLO Development Kit
 does not support dynamic-link libraries that are drivers; therefore, when
 using the WLO Development Kit, you cannot install Windows display drivers
 (nor should you rely on them). Instead, the WLO mapping layer maps all
 output to the equivalent OS/2 display and printer drivers.

 In many situations, an existing OS/2 device driver providing similar
 functionality is all that is required for an application to be converted
 successfully. OS/2 provides equivalent hardware device-driver functionality
 for standard Windows requirements, including printer (PostScript, PCL),
 display (CGA, EGA, VGA, 8514/A), and keyboard (101 US, 102 foreign) support.
 The WLO mapping layer handles the proper mapping between these standard
 device drivers, so that, to the converted applications, they are the Windows
 drivers.


 2.2.10.2  Device-Context Device Drivers

 Device drivers for device contexts are display and printer drivers, and
 sometimes drivers used for other purposes, that work through the Windows
 graphics device interface (GDI). The WLO Development Kit does not support
 this type of GDI driver. To convert this type of driver, you must implement
 the equivalent functionality by using OS/2 functions.


 2.2.10.3  DOS Device Drivers and Terminate-and-Stay-Resident Routines

 The WLO Development Kit does not support Windows applications that use DOS
 device drivers, which are usually installed by the CONFIG.SYS file or by a
 terminate-and-stay-resident (TSR) routine loaded before running Windows. You
 must use an equivalent OS/2 device driver.


 2.2.10.4  Windows Device Drivers

 In general, OS/2 does not support Windows dynamic-link libraries that read
 or write directly to hardware addresses or ports. At a minimum, to operate
 with the WLO mapping layer, a Windows dynamic-link library must be
 compatible with Windows version 3.0 protected mode. OS/2 runs applications
 and dynamic-link libraries at rings 2 and 3 (ring 3 is the default); OS/2
 requires code that reads or writes from hardware ports to run at ring 2 (in
 an IOPL segment). In addition, these Windows dynamic-link libraries cannot
 install hardware (or software) interrupt handlers. Interrupts can be handled
 only at ring 0 by an OS/2 device driver. This is not an issue in Windows
 version 3.0, since Windows applications and dynamic-link libraries run at
 ring 0.


 2.3  Building Converted Applications

 A converted Windows application remains, essentially, a Windows application.
 Specifically, the object files and resources are all built using the tools
 and include files in the Windows Software Development Kit version 3.0. The
 linking process adds some static mapping information from the WLO import
 libraries as well as specific references to the OS/2 versions of GDI.DLL,
 USER.DLL, and KERNEL.DLL, where most of the WLO mapping layer is located.
 The result is a Windows application that runs only with OS/2.

 Your development environment is straightforward if you use only the Windows
 SDK version 3.0 and the WLO Development Kit to convert Windows applications
 into OS/2 executable files. If you have installed the MS OS/2 Presentation
 Manager Toolkit version 1.2 in addition to the Windows SDK version 3.0, take
 care when setting up paths to tools, include files, and libraries.

 If you will be using the WLO Development Kit only to relink a Windows
 executable file and do not plan to add OS/2 functions to the file, you
 should add the paths to the WLO files (libraries and binaries) to your
 current Windows version 3.0 development-environment variables. If you are
 using a system with the MS OS/2 Presentation Manager Toolkit version 1.2,
 either use separate environment variables or place Windows SDK and WLO paths
 ahead of the Toolkit directories when building WLO applications.

 For information about the build process and how to use environment variables
 when developing applications that mix Windows and OS/2 functions, see
 Section 2.6, "Adding OS/2 Features."


 2.3.1  Linking Applications

 For simple relinking of application object modules, two tools are required:
 Microsoft(R) Segmented-Executable Linker (LINK), for relinking the object
 modules; and Windows Resource Compiler, for rebinding the resources. An
 appropriate linker is supplied with various products: MS OS/2 Presentation
 Manager Toolkit version 1.2, Microsoft C Optimizing Compiler version 5.1 or
 6.0, and OS/2 version 1.21. Use the latest version of the linker that you
 have.

 Windows applications are normally linked with the library xLIBCyW, where x
 represents the library's memory model (S, M, C, or L, for small, medium,
 compact, or large) and y represents the math package (E or A, for emulation
 or alternate). Windows version 3.0 also supports the
 memory-model-independent library LIBW. You should replace these Windows
 library references with references to LIBMK_B and xLIBCyMK, where x is the
 appropriate memory model and y is the appropriate math package. The LIBMK_B
 library replaces the Windows library LIBW; xLIBCyMK is the WLO Development
 Kit's customized protected-mode C run-time library that replaces the
 real-mode run-time library xLIBCyW.

 You must also use the /NOD linker switch to override default library
 searches. This is important if both WLO import libraries and Windows SDK
 libraries are in your LIB path. Not using the /NOD switch would result in
 incorrect linking to the Windows libraries instead of to the WLO
 replacements, creating an application that would cause a general protection
 fault when run with OS/2.

 The library OS2.LIB is required to resolve direct OS/2 function references
 and internal WLO and C run-time library references to OS/2 functions. A copy
 of OS2.LIB from the MS OS/2 Presentation Manager Toolkit version 1.2 is
 provided in the directory \eWLO\eLIB. You must include a reference to
 OS2.LIB when you start the linker.

 To ensure correct linking, each WLO sample application or dynamic-link
 library includes the necessary make-file changes. The Generic application, a
 sample provided with the Windows SDK version 3.0, is provided in a modified
 form in the WLO Development Kit. The only changes made were to the make
 file. The LINK command line for the application in the Windows SDK is as
 follows:

 link /NOD generic,,,libw slibcew,generic.def


 To build an OS/2 executable file, change the make file to substitute the WLO
 import, C run-time, and OS/2 libraries, as follows:

 link /NOD generic,,,libmk_b slibcemk os2,generic.def


 If you have not added the line EXETYPE WINDOWS to your .DEF file for Windows
 version 3.0, you should do so before attempting to link and build a WLO
 application.


 2.3.2  Changing Application Source Code

 The goal of the WLO Development Kit is to provide an easy conversion path
 for Windows applications so that no source-code changes are necessary in
 most applications. You may need to change your Windows application source
 code if it uses Windows functions that are not supported in the WLO mapping
 layer. For a list of unsupported Windows functions, see Chapter 3,
 "Limitations on Converted Applications."

 In most cases, you must recode your application so that is does not call any
 unsupported Windows functions. These unsupported functions are "stubbed
 out," however, which means that when called they simply return to the caller
 without doing anything. If your application does not depend on any specific
 result from an unsupported Windows function, you need not change it. The
 unsupported function will behave like an assembly NOP instruction.

 If your Windows application uses system interrupts (BIOS or DOS), you must
 change and recompile the modules that contain these calls. The WLO
 Development Kit does not support BIOS calls, except for Interrupt 21H. For a
 description of DOS interrupts that are supported by the Windows version 3.0
 function Dos3Call, see Chapter 3, "Limitations on Converted Applications."
 .ET

 If you attempt to call a system interrupt in a converted application running
 with OS/2 version 1.21, a general protection fault will result. Converting
 system interrupts may involve using OS/2 functions and may require that you
 significantly recode and redesign your application. To ease conversion of
 system-interrupt calls, use the Windows version 3.0 Dos3Call or NetBiosCall
 function. These functions are mapped to appropriate OS/2 functions by the
 WLO import libraries and mapping layer. If your application requires an
 interrupt that is not supported in the WLO Development Kit by the Dos3Call
 or NetBiosCall function provided with this release, please notify Microsoft
 through your OnLine account.

 Source-code changes may also be necessary to handle certain exceptional
 interactions between Windows code and the WLO mapping layer. For information
 about specific problems that might require code modification, see Chapter 3,
 "Limitations on Converted Applications."


 2.4  Building Converted Dynamic-Link Libraries

 Windows dynamic-link libraries can be converted to run with OS/2. Like
 Windows applications, dynamic-link libraries must be relinked with the WLO
 import .RT libraries to be compatible with OS/2. You must also make minor
 source-code changes in all converted dynamic-link libraries so that they
 will run correctly with OS/2. Once converted, a Windows dynamic-link library
 provides the same sort of services in OS/2 as it did in Windows.


 2.4.1  Linking Dynamic-Link Libraries

 If your application relies on dynamic-link libraries, you must relink these
 libraries with WLO import libraries to create an OS/2 dynamic-link library.
 Dynamic-link libraries, like applications, can contain Windows resources
 that are compiled by using Windows Resource Compiler.

 Windows dynamic-link libraries are typically linked with the libraries LIBW
 and xDLLCyW, where x represents the library's memory model (S, M, C, or L,
 for small, medium, compact, or large) and y represents the math package (E
 or A, for emulation or alternate). You should replace these Windows library
 references with references to the WLO import libraries LIBMK_B and xDLCCyMK,
 where x is the appropriate memory model and y is the appropriate math
 package. You must also use the /NOD linker switch to override default
 library searches.

 Just as it is required for linking applications, the library OS2.LIB is
 required to resolve direct OS/2 function references and internal WLO import
 and C run-time library references to OS/2 functions. A copy of OS2.LIB from
 the MS OS/2 Presentation Manager Toolkit version 1.2 is provided in the
 directory \eWLO\eLIB. You must include a reference to OS2.LIB when you start
 the linker.

 To ensure correct linking, the WLO sample application Windll includes the
 necessary changes to the make file. This sample is based on a Windows
 Software Development Kit version 3.0 sample application named Select. The
 LINK command line in the Windows SDK version is as follows:

 link /NOD select libentry,select.dll,,sdllcew libw,select.def


 To build an OS/2 dynamic-link library, you must modify the make file,
 substituting the WLO import libraries, as follows:

 link /NOD select libentry,select.dll,,sdllcemk libmk_b os2,select.def


 In the .DEF file for the dynamic-link library, you must define a name for
 the dynamic-link-library module by using the LIBRARY statement, as in the
 following example:

 LIBRARY  mywinlib


 Be sure that the module name specified in the LIBRARY statement of the .DEF
 file is the same as the base name for the dynamic-link library that is
 eventually created. For example, if the LIBRARY statement uses the name
 MYWINLIB, the dynamic-link library should be named MYWINLIB.DLL.

 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
 Note

 Simply relinking your Windows dynamic-link library is not sufficient to
 enable it to run with OS/2. You must also make small source-code changes in
 the initialization function for your dynamic-link library to compensate for
 differences in initializing Windows and OS/2 dynamic-link libraries. For
 information about the necessary changes to a Windows dynamic-link library,
 see the following section.
 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ




 2.4.2  Changing Dynamic-Link-Library Source Code

 Although you may be able to convert an application without making any
 source-code changes, all Windows dynamic-link libraries require changes in
 order to run with OS/2. In addition to relinking the Windows dynamic-link
 library with the WLO import libraries, you must also modify the
 initialization routine for the dynamic-link library.

 The system loads the converted dynamic-link library just as it would any
 other OS/2 dynamic-link library; that is, the converted Windows dynamic-link
 library is not loaded by any intermediate routines in the WLO mapping layer.
 Windows dynamic-link libraries require an assembly-language initialization
 routine. The Windows Software Development Kit version 3.0 provides examples
 that use a routine named LibEntry in the file LIBENTRY.ASM, which provides
 an entry point for the dynamic-link library that is called when the library
 is loaded. One-time initialization of the dynamic-link library is typically
 done at this timeÄfor example, initialization of the library's heap (if it
 has one), plus additional initialization specific to the library.

 Like Windows applications, WLO applications running with OS/2 permit
 dynamic-link libraries to be referenced by many processes. However, the WLO
 Development Kit does not support the WEP (Windows exit procedure) routine,
 which Windows calls when the dynamic-link library is unlinked.


 2.4.2.1  Register Use in a Dynamic-Link Library

 Windows and OS/2 dynamic-link libraries receive different sets of
 initialized registers when the system calls the dynamic-link-library entry
 point. After loading a dynamic-link library, Windows calls the entry point
 with the following registers initialized:

 Value                             Description
 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

 CS:IP                             Contains the entry-point address of the
                                   library initialization function.

 SS:SP                             Contains the address of the current
                                   system stack. The initialization
                                   function can use the stack to define
                                   local variables and call other functions,
                                   but it must restore the stack to its
                                   previous state before returning.

 DS                                Contains the segment selector of the
                                   library's automatic data segment (if it
                                   has one), or contains the selector for
                                   the data-segment application or system
                                   library that called the Windows
                                   LoadModule function to load the library.

 DI                                Identifies the instance handle of the
                                   Windows dynamic-link library.

 ES:SI                             Points to the application command line
                                   that is loading the dynamic-link library.

 CX                                Contains the size (in bytes) of the heap
                                   as defined in the .DEF file.



 All other register values are undefined.

 After loading an OS/2 dynamic-link library (or converted Windows
 dynamic-link library), OS/2 calls the library's entry point with the
 following registers initialized:

 Value                             Description
 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

 CS:IP                             Contains the entry-point address of the
                                   library initialization function.

 SS:SP                             Contains the address of the current
                                   system stack. The initialization
                                   function can use the stack to define
                                   local variables and call other functions,
                                   but it must restore the stack to its
                                   previous state before returning.

 DS                                Contains the segment selector of the
                                   library's automatic data segment (if it
                                   has one), or contains the selector for
                                   the data-segment application or system
                                   library that called the OS/2
                                   DosLoadModule function to load the
                                   library.

 AX                                Identifies the module handle of the
                                   dynamic-link library.



 All other register values are undefined.

 Note that the dynamic-link-library module handle passed in the AX register
 in OS/2 is not equivalent to the dynamic-link-library instance handle that
 Windows passes in the DI register. Therefore, AX cannot be used as a module
 handle with Windows functions. You must include the CONVDLL.INC macro file
 to convert the registers and obtain the mapped module handle in DI. The OS/2
 module handle in AX is preserved and can be used by the dynamic-link library
 to call OS/2 functions such as DosGetResource and DosGetModName. For
 information about the Convdll tool, see Section 2.4.2.2, "The Convdll Tool."



 2.4.2.2  The Convdll Tool

 To assist in converting a Windows dynamic-link library to an OS/2 library,
 the WLO Development Kit provides the Convdll tool. This tool adds code to
 the beginning of the dynamic-link library to manipulate register contents so
 that, even after the conversion, the contents of the registers appear to the
 library just as they would in Windows. Convdll also inserts code in the
 dynamic-link library to handle unlinking the library after all its WLO
 clients terminate.

 Because Convdll must insert code into the library's initialization code, you
 must reserve space for the inserted code by including the file CONVDLL.INC
 just before the entry point for the dynamic-link library, as follows:

 INIT_TEXT segment byte public 'CODE'
      assume cs:INIT_TEXT

 INCLUDE convdll.inc

 LibEntry proc far
     push   di     ; handle of the module instance
     push   ds     ; library data segment
     push   cx     ; heap size
     push   es     ; command line segment


 If Cmacros are used in the dynamic-link library's initialization code (as
 shown in LIBENTRY.ASM of the Windll sample), then CONVDLL.INC should be
 included as follows:

 cProc   LibEntry, <PUBLIC,FAR>   ; entry point into DLL

 INCLUDE convdll.inc
 cBegin
         push    di               ; handle of the module instance
         push    ds               ; library data segment
         push    cx               ; heap size
         push    es               ; command-line segment
         push    si               ; command-line offset


 Incorrectly placing the INCLUDE convdll.inc statement will result in errors
 from the Convdll tool. If you have problems with converted dynamic-link
 libraries, verify that Convdll does not report any errors and that the
 position of the include statement is correct.

 The macros in CONVDLL.INC insert code and WLO signature bytes into the
 dynamic-link library. After reassembling and relinking the library with the
 WLO import libraries, you then run Convdll, as in the following example:

 convdll example.dll


 In addition to manipulating registers and tracking dynamic-link-library use,
 the code inserted by Convdll also ensures, before returning, that the WLO
 dynamic-link libraries are loaded and initialized. This allows the
 dynamic-link library's initialization routine to freely call Windows
 functions without having to determine whether the WLO dynamic-link libraries
 are loaded and initialized. With OS/2, there is no guarantee in what order
 dynamic-link libraries will be loaded when several such libraries are
 referenced by an application. With Windows, the system dynamic-link
 libraries (GDI, KERNEL, USER, etc.) are loaded when Windows itself is
 loaded. Therefore, a Windows dynamic-link library may freely call Windows
 functions within the dynamic-link library's initialization routine without
 having to determine whether the system dynamic-link libraries are loaded and
 initialized. With OS/2, the WLO dynamic-link libraries are loaded when the
 application is loaded, but, because there is no guarantee that the WLO
 dynamic-link libraries will be initialized first, an application-defined
 dynamic-link library should not call Windows functions during its
 initialization routine until after the INCLUDE convdll.inc statement.

 The WLO Development Kit provides the sample application Windll, which is
 based on the sample application Select in the Windows Software Development
 Kit version 3.0. In addition to modifying the make files to relink with the
 WLO import libraries and run the Convdll tool on the dynamic-link library,
 this sample shows how to change the LIBENTRY.ASM file to include
 CONVDLL.INC.


 2.5  Debugging

 Your development system may be either DOS or OS/2, but you must do any
 testing and debugging with an OS/2 system. Therefore, the dynamic-link
 libraries in the WLO Development Kit must be present on the destination OS/2
 system and referenced in the LIBPATH statement. (These libraries should have
 been installed correctly by the Wloinst utility during the installation of
 the WLO Development Kit.)

 If OS/2 cannot find the WLO dynamic-link libraries when it attempts to run
 the application, it displays the following error message:

 SYS1804: The system cannot find the file .


 Note that OS/2 does not indicate the dynamic-link library that it "cannot
 find." You can determine the name of this library by using the OS/2 Detach
 utility. If you detach the same application, the error message may then
 appear as follows:

 SYS1804: The system cannot find the file USER.


 This message indicates that the USER.DLL library is not in the path
 specified in the LIBPATH environment variable. Once you have corrected this
 problem, you can correctly run the relinked application.

 When using OS/2 version 1.21, you can use the Microsoft(R) CodeView(R)
 debugger (CVP.EXE) provided with the Microsoft C Optimizing Compiler version
 5.1. This debugger is an early version of the protected-mode CodeView
 (version 2.2). While you can use CodeView version 2.2, it is recommended
 that you use a more recent version. The MS OS/2 Presentation Manager Toolkit
 version 1.2 provides a copy of CodeView version 2.3; Microsoft C version 6.0
 provides CodeView version 3.0. These later versions provide better support
 for debugging dynamic-link libraries and child processes.

 If you want to debug at source level, CodeView must be running the
 executable file and any converted dynamic-link libraries and must also have
 access to the source modules. Therefore, the source code should also be on
 the destination OS/2 system (typically in the same directory as the
 application being tested).

 When you first start CodeView on an application, it displays the entry point
 to the application in assembly-language format, since the entry point is in
 a library module and not in the application's source code. To display the
 source code for the application, use a CodeView command, such as the v
 (view) command, to advance to one of the functions within the code, as in
 the following example:

 v WinMain


 You can then set breakpoints in the source code and proceed with debugging.

 For information about how to use the CodeView debugger, see the
 documentation provided with the Microsoft C Optimizing Compiler or with the
 appropriate Toolkit or SDK.

 You may also use third-party OS/2 debuggers, such as the Logitech MultiScope
 Debugger, to debug converted applications. A converted application behaves
 and appears to the system and debugger as a normal 16-bit OS/2 executable
 file. Contact the vendor of your debugger to verify that the debugger
 supports OS/2 version 1.21 or later.


 2.5.1  Dynamic-Link Libraries for Debugging

 The WLO dynamic-link libraries for debugging provide a built-in debugging
 aid. The mapping-layer dynamic-link libraries located in the
 \eWLO\eDLL\eDEBUG directory are debugging-enabled versions for application
 developers. These libraries serve the same purpose as those provided with
 the Windows Software Development Kit version 3.0 and MS OS/2 Presentation
 Manager Toolkit version 1.2.

 The debugging libraries provide additional internal consistency checking.
 Any errors encountered are displayed on a separate debugging terminal. The
 system uses a symbol file (.SYM) to provide symbolic addresses during stack
 dumps. To be used, a symbol file must be in the same directory as its
 matching dynamic-link library. You can also provide symbolic information for
 your own application by using the Mapsym utility to create a .SYM file from
 the .MAP file generated by the linker.

 For more information about setting up an OS/2 system with debugging
 dynamic-link libraries, see Disk 2 of the MS OS/2 Presentation Manager
 Toolkit version 1.2, which contains a README file (in the DLL directory).

 For developing and testing the converted application, use the debugging
 versions of the dynamic-link libraries. For final shipment, use the retail
 versions of the libraries located in the directory \eWLO\eDLL\eRETAIL.


 2.6  Adding OS/2 Features

 For many applications (especially those intended to run with both Windows
 and OS/2), relinking with the WLO import libraries will be sufficient. But
 if you want your applications to take advantage of some of OS/2's unique
 features, the WLO Development Kit allows limited mixing of Windows and OS/2
 API functions. The following list shows key areas where you can add OS/2
 functionality to your applications:

   ž   Long file names and extended attributes for files

   ž   Threads for multitasking

   ž   Interprocess communication



 2.6.1  Using Windows and OS/2 Include Files Together

 If it were not for conflicts between the Windows and OS/2 include files,
 adding OS/2 functions directly to the Windows source code would be easy.
 OS/2 and Windows share many definitions that use the same names but that
 specify different structures, types, or values. Therefore, it is not
 possible to include both Windows and OS/2 include files directly in one
 source-code module. If an OS/2 function is referenced from a source module
 that includes the WINDOWS.H file, you must "hand prototype" the OS/2
 function and any of its parameters. This would be a laborious process if
 many OS/2 functions were involved.

 Rather than hand-prototype OS/2 functions, a better solution is to separate
 them into their own source-code modules. Each source module can include
 either WINDOWS.H or the OS/2 include files, but not both. The C compiler
 switch -I allows for overriding default include-file searches. In this way,
 you can use the INCLUDE environment variable to handle normal compiling,
 perhaps referencing the location of WINDOWS.H. You can then use the -I
 compiler switch to compile the OS/2 modules so that the OS/2 include files
 are referenced.

 One issue remains a concern: Windows source modules require function
 prototypes for the functions in OS/2 modules or OS/2 dynamic-link libraries.
 Windows programmers rely on Windows definitions such as WORD, DWORD, LPSTR,
 and so on. OS/2 provides its own set of standard definitions, such as
 USHORT, ULONG, and PSZ. Since it is not possible to reference the OS/2
 include file OS2DEF.H (which defines these OS/2 type definitions, or
 typedefs) and WINDOWS.H in the same source module, you should create a
 WINDEF.H include file that converts OS/2 definitions into forms recognizable
 in the Windows modules, as in the following example:

 #define PSZ    LPSTR
 #define USHORT WORD
 #define ULONG  DWORD


 Including this WINDEF.H file in your Windows source modules allows you to
 use standard OS/2 definitions in the function prototypes used to reference
 functions in the separate OS/2 source module or OS/2 dynamic-link library.

 Note that the Windows and OS/2 header files are subtly different; for
 example, they contain typedefs with the same names, such as HWND, HDC, HRGN,
 HBITMAP, and so on. Handles are typically 32 bits long in OS/2 but 16 bits
 long in Windows. Inadvertently using one of these preceding typedefs in a
 function prototype would result in a stack overflow or underflow and an OS/2
 general protection fault.

 Once you have compiled the application, you must link the object files.
 Unlike the include files, the Windows and OS/2 libraries do not conflict.
 All OS/2 functions are resolved in OS2.LIB, and the Windows and C run-time
 library references are resolved in the WLO import libraries. There are no
 naming conflicts among Windows, C run-time, and OS/2 libraries.


 2.6.2  Creating an OS/2 Dynamic-Link Library

 It is often useful to add OS/2 functions to your converted Windows
 application by creating a special OS/2 dynamic-link library. This library
 will contain only OS/2 functions, which the original Windows application can
 then use. The Windows application can access these features by calling
 exported routines from the OS/2 dynamic-link library.

 To build an OS/2 dynamic-link library, you compile and link your code,
 exporting the functions that you want to be visible and using the LIBRARY
 keyword in the .DEF file to tell the linker to create a dynamic-link
 library. Once the library is created, you run the Implib tool to create a
 library file that you can link with your application. The library file
 created by Implib contains short functions that reference the exported
 functions in the dynamic-link-library file. You must reference the path of
 this file somewhere in the LIBPATH setting so that OS/2 can find it. For an
 example of an OS/2 dynamic-link library created to work with a Windows
 application, see the sample WLO application OS2DLL.


 2.6.3  Using Long Filenames and Extended Attributes

 The ability to use long filenames and extended attributes is a key OS/2
 feature you may want to add to your Windows application. Extended attributes
 are available on all systems running OS/2 version 1.21 or later. Long
 filenames are available only on OS/2 systems that have the high-performance
 file system (HPFS) installed. (OS/2 version 1.21 includes HPFS, which you
 may optionally install in one or more hard-disk partitions.)

 The default OS/2 file system is based on the file allocation table (FAT)
 model used in DOS. FAT filenames are limited to eight characters plus a
 three-character extension (for example, WLODOC10.TXT), often referred to as
 the 8.3 format. HPFS filenames, by comparison, can contain up to 260
 characters, including embedded spaces.

 When converting a Windows application to OS/2, you may want the application
 to handle long filenames. A common problem in existing Windows applications
 is that they allocate filename buffers just large enough to hold FAT 8.3
 filenames and path buffers just large enough to hold the maximum
 64-character path length. When using HPFS, however, you can use the OS/2
 DosQFileInfo function to determine the maximum length of a path in the
 current system and allocate file and path buffers accordingly.

 If the application includes filename-parsing code that depends on the 8.3
 format, you should modify the code so that it can handle long
 filenamesÄspecifically, filenames that contain embedded spaces and multiple
 dot delimiters (.). A useful technique when searching for a filename
 extension is to parse the name from the end rather than the beginning.

 Extended attributes allow you to attach additional information, such as
 version history or file type, to a file. Extended attributes are available
 in OS/2 versions 1.21 and later in both the FAT and HPFS file systems. There
 are two types of extended attributes, critical and noncritical. Critical
 extended attributes are considered vital to the meaning of a file;
 noncritical extended attributes contain only supplementary information. The
 creator of the extended attribute sets a flag to specify whether the
 extended attribute is critical.

 Your converted Windows application must support existing extended attributes
 for the files that it manipulates. For example, it is common to create a
 temporary file for editing and then copy the temporary file over the
 original file when the user asks to save changes. The OS/2 function DosCopy
 copies all extended attributes of the source file along with the contents of
 the file. The OS/2 functions DosQFileInfo and DosSetFileInfo allow you to
 get and set specific extended attributes for a file or directory.

 If your application can handle long filenames, you must set the long-name
 flag in the header of the executable file in order to notify the operating
 system of the application's capability. If this flag is not set, the
 application cannot access any files with names longer than the 8.3 FAT
 format, regardless of the filename format. To set this flag, use one of the
 following methods:

   ž   Add the LONGNAMES modifier to the NAME directive in your .DEF file, as
       follows:

 NAME MyProg LONGNAMES



   ž   Add the NEWFILES directive to your .DEF file, as follows:

 NAME MyProg
 NEWFILES



   ž   Use the Markexe tool with the LFNS switch. Markexe is provided in the
       MS OS/2 Presentation Manager Toolkit version 1.2.


 The WLO sample application Editfile shows how to add extended-attribute
 capability and handle long filenames in a converted Windows application. For
 more information about using extended attributes and long filenames, see the
 Microsoft Operating System/2 Programmer's Reference.


 2.6.4  Managing Threads

 Another key feature of OS/2 is the ability to create separate threads of
 execution within a process. Threads are particularly useful when long
 calculations are involved, where there is a need to block a thread for an
 indefinite period of time to wait for a specific event, or when large
 amounts of information must be transferred. Examples of these three cases
 are spreadsheet recalculation, blocking on a semaphore used for interprocess
 communication (IPC), and large-file manipulation or serial data exchange.

 Threads run within the context of the process that creates them. This
 creates a problem for applications that manipulate buffers, handle file
 input and output, or require global data for other reasons. Multiple threads
 could call related functions when the threads are time-sliced by the OS/2
 scheduler, but without proper synchronization, one thread can corrupt
 another thread's buffers. To assist programmers in writing multiple-threaded
 applications, OS/2 provides semaphore API functions and the ability to enter
 critical sections.

 As discussed in Section 2.2.6, "Task-Switching Support," Windows
 applications are not designed for preemptive multitasking. Task scheduling
 occurs when the message queue is checked. The WLO mapping layer recreates
 this scheduling design so that WLO applications need not be redesigned to
 run in OS/2. However, this affects how threads can be added and used in WLO
 applications.

 A WLO process consists of a primary thread, Thread 1, that contains all the
 Windows API functions. A typical WLO application also calls the C run-time
 functions. Any additional threads created within the application code must
 operate under the following restrictions:

   1.  Secondary threads must not call any Windows API functions, with the
       exception of the PostMessage function.

   2.  A secondary thread must not call any C run-time functions that are in
       the same application code as the thread. You must restrict
       secondary-thread calls to OS/2 API functions such as DosCreateThread,
       DosOpen, DosRead, and DosWrite. You should place secondary threads in
       a separate OS/2 dynamic-link library where C run-time functions can be
       used.


 An application may use the PostMessage function in secondary threads as an
 asynchronous notification mechanismÄfor example, using the background thread
 to alert the primary WLO thread to the completion of an operation. This
 method is preferable to having the primary WLO thread polling background
 threads for status information. If global variables, shared memory, or both
 are used to communicate between the WLO thread and background threads, you
 should use semaphores to protect any critical sections. Your application
 should not block the primary WLO thread by making it wait indefinitely for a
 semaphore, nor should the primary thread fail to check its message queue in
 a timely fashion; otherwise, other WLO applications will not be scheduled
 and will receive no CPU time. This recommendation is as important in WLO
 applications as it is in Windows itself.

 To elaborate on the second restriction, the WLO libraries are derived from
 the single-thread Microsoft C version 6.0 protected-mode libraries.
 Therefore, application code used by secondary threads must be restricted to
 using OS/2 API equivalents of the C run-time functions. If the threads are
 managed in a separate dynamic-link library, you can use the multiple-thread
 C run-time libraries, such as LLIBCDLL.LIB.

 For more information about the multiple-thread C run-time libraries, see the
 C version 5.1 file MTDYNA.DOC or the information about advanced programming
 techniques in the C version 6.0 documentation.


 2.6.5  Managing Memory

 Since the WLO mapping layer translates Windows memory-management functions
 into corresponding OS/2 functions, it is not usually necessary to make any
 adjustments to memory management in a converted application.

 For efficiency in virtual-memory environments (such as Windows version 3.0
 enhanced mode), you should not use the Windows GlobalAlloc function for
 small objects (that is, less than 4K). Instead, minimize the number of
 global objects by using the Windows LocalAlloc function to allocate small
 objects on the local heap or by combining small requests into larger
 requests for global memory. You should observe the following guidelines on
 memory use:

   ž   Do not rely on the 4K page size.

   ž   Do not assume the object size will be rounded to paragraphs.

   ž   Do not expect the GlobalLock function to return a pointer with a zero
       offset.

   ž   Do not expect the GlobalAlloc function for a FIXED object to return a
       selector.

   ž   Do not expect GlobalLock to return the same value each time the
       function is used to lock a particular global memory block.


 By default, the GlobalAlloc function allocates private memory that cannot be
 shared between processes. If a WLO application must share memory with
 another WLO or OS/2 process, it must allocate shared memory using the
 GlobalAlloc function with the GMEM_DDESHARE option.


 2.6.6  Using Different Code Pages

 Windows and OS/2 have different default code pages (character sets). The two
 code pages, 850 and 1004, differ in their upper-128 character ranges. Both
 character sets contain the same national (accented) characters, but in
 different physical locations. In addition, the ANSI character set contains
 some special characters (such as the copyright symbol) that are not
 available in code page 850. Another aspect of the ANSI character set is that
 the order of international characters makes sorting much easier than with
 code page 850.

 The WLO mapping layer automatically converts text when a converted
 application exchanges data with an OS/2 application by using the clipboard
 or dynamic data exchange (DDE). That is, if an application uses the ANSI
 code page and writes text to the clipboard or uses DDE, the mapping layer
 translates the text to code page 850 (or the current code page for
 Presentation Manager). Similarly, when a converted ANSI application reads
 text from the clipboard or through DDE, the mapping layer converts the text
 to ANSI. This automatic translation greatly simplifies the exchange of data
 with OS/2 applications.

 By default, WLO applications use the Windows ANSI code page (1004), just as
 they do with Windows. OS/2 does provide code page management functions, so
 WLO application can change the code page if needed.

 If the WLO mapping layer detects that the WLO application has set its code
 page (by using the OS/2 WinSetCp or DosSetProcCp function), the automatic
 character translations for the clipboard and DDE strings are not enabled.
 Otherwise, the application is assumed to be running in ANSI and the mapping
 layer performs the correct translations.

 Note that you must do your own character conversion when reading or writing
 binary text files. The mapping layer converts text automatically only for
 the clipboard and DDE. In OS/2, you can use the functions WinCpTranslateChar
 and WinCpTranslateString to convert characters between two different code
 pages.

 A call to the OS/2 function WinSetCp during the application's initialization
 will set the message-queue code page for that application. You can pass the
 constant HMQ_CURRENT (found in PMWIN.H) in the hmq parameter and the number
 of the code page that you want to use (for example, 850) in the idcp
 parameter. If you convert your Windows application to use code page 850, no
 text conversion will be necessary when the application exchanges data with
 other OS/2 applications, although you may have a problem when data files are
 shared with the original Windows version of the application, which will
 still be using the ANSI character set in its files.

 Note that, as implemented in the WLO mapping-layer dynamic-link libraries,
 the Windows function SetMessageQueue also automatically sets the code page
 to the ANSI code page (1004) usually used by Windows applications. This will
 be a problem only if your application calls SetMessageQueue after setting
 the code page to something other than the ANSI code page. .ET


 2.7  Shipping a Converted Application

 The following sections discuss what is necessary to deliver and install a
 converted application to a user.


 2.7.1  Naming Conventions for WLO Dynamic-Link Libraries

 The dynamic-link libraries shipped with this release of the WLO Development
 Kit contain version-specific characters embedded in their filenamesÄfor
 example, USER_B.DLL, GDI_B.DLL, and KERNEL_B.DLL. Since the mapping layer
 will continue to be enhanced in future releases of the WLO Development Kit,
 the WLO dynamic-link libraries will contain release-dependent features.
 Applications converted with later WLO releases will reference dynamic-link
 libraries with different names, thus avoiding installation conflicts.


 2.7.2  Library Installation

 You must ship the WLO dynamic-link libraries with your converted application
 and install them on the destination OS/2 system. The WLO Development Kit
 includes the Wloinst utility for this purpose. Wloinst checks for the
 existence of previously installed WLO dynamic-link libraries and copies more
 recent libraries if available. Use Wloinst in a batch program or from within
 your application's installation program. .RT

 The Wloinst utility takes the following command-line switches:

   ž   The -q switch suppresses all screen messages; this is useful if you
       call Wloinst from another program and do not wish to see extra screen
       messages.

   ž   The -s switch specifies the source directory containing the WLO
       dynamic-link libraries to copy. Wloinst copies libraries from one
       directory only, so make sure all WLO dynamic-link libraries are in the
       same directory on the same installation disk. The dynamic-link
       libraries are then copied to the location of PMWIN.DLL, which is
       typically located in the directory \eOS2\eDLL on drive C. It is
       important to copy WLO dynamic-link libraries to a single location to
       prevent multiple sets of WLO dynamic-link libraries at different
       locations on the same hard disk.


 The following example shows how to use Wloinst to install a set of WLO
 dynamic-link libraries located in the DLL directory on the disk in drive A:

 wloinst -q -s a:\dll


 Be sure that in your final product shipment you use the retail version of
 the WLO dynamic-link libraries rather than the debugging version. For the
 location of the retail libraries, see the PACKING.LST file located on Disk 1
 of the WLO Development Kit. These files have filename exensions of .DL@,
 rather than .DLL. The Wloinst utility automatically renames the extensions
 to .DLL after copying them to the hard disk. For information about the
 retail and debugging versions of the WLO dynamic-link libraries, see Section
 2.5.1, "Dynamic-Link Libraries for Debugging."


 2.7.3  Installation Programs

 If you use an installation program (or batch file) designed to work with
 DOS, you must change it to work with OS/2. If your installation program
 modifies the AUTOEXEC.BAT or CONFIG.SYS file, it is likely that such
 modifications are no longer applicable to OS/2. Additional subtle
 differences could exist if your installation program depends on the
 existence of specific Windows files or directory structures.

 If your application requires private dynamic-link libraries of its own, your
 installation program should copy these libraries into the directory
 \eOS2\eDLL on drive C (the same directory as the WLO dynamic-link
 libraries). By copying the private libraries into this directory, the
 installation program does not have to modify the LIBPATH statement in the
 CONFIG.SYS file. This method also does not require the user to shut down and
 reboot the system to complete the installation.


 2.7.4  Help Manager

 The WLO Development Kit includes a version of Windows Help Manager,
 WINHELP.EXE, that has been converted to run with OS/2. If your converted
 application uses Windows Help Manager, you must ship the WLO version of
 WINHELP.EXE with the application. The WLO Development Kit includes several
 foreign-language (localized) versions of Help Manager. Be sure that you ship
 the correct version for your application. If the WLO Development Kit does
 not include the localized version of Help Manager that you need for your
 application, please contact your local Microsoft subsidiary for assistance.
 The localized Windows Help Manager is available only in the languages into
 which Windows version 3.0 has been localized.

 Windows Help Manager is called WINHELP.EXE in all localized versions of
 Windows version 3.0. The SMK provides these versions with different names,
 such as WINHELPD.EXE for German. Before shipping these localized versions
 with your localized applications, be sure to rename them to the proper name
 of WINHELP.EXE.


 2.7.5  WIN.INI and OS2.INI

 The WIN.INI file is an ASCII text file that contains configuration
 information for the Windows system and Windows applications. You can modify
 WIN.INI by using standard text editors. OS/2 uses the binary-encoded files
 OS2.INI and OS2SYS.INI to store similar information.

 In Windows, system-configuration information is contained in separate
 sections of WIN.INI. These sections are [windows], [intl], [ports], and
 [colors]. Some of the keys included in the [windows] section are Beep,
 Device, NullPort, Spooler, and SwapMouse.

 Windows applications typically read and write configuration information by
 using the functions GetProfileString, WriteProfileString, and GetProfileInt.
 The WLO mapping layer intercepts these three functions and maps system
 values (noted in the preceding paragraph) to OS2.INI. The mapping layer
 treats all other values as application-specific and maps them to WIN.INI.

 Note that the Windows private profile functions (GetPrivateProfileString,
 etc.) do not check for a file named WIN.INI and do not do any mapping to
 OS2.INI.

 An application should use a private (application-specific) initialization
 file to record information that affects only that application. By reducing
 the amount of information the WLO Development Kit must read when accessing
 the initialization file, this method improves both the performance of the
 WLO Development Kit and the performance of the application. An application
 should record information in WIN.INI only if it affects either the WLO
 environment or other WLO applications; in such cases, the application should
 send all top-level windows a WM_WININICHANGE message.

 This recommendation may affect any installation programs or scripts that you
 ship with your application. For example, if your current installation
 program runs with DOS and modifies the system-related sections of WIN.INI
 directly, you must create an OS/2 version of your installation program that
 uses standard OS/2 functions such as PrfWriteProfileString to make proper
 OS2.INI entries for the system-configuration information. Your OS/2
 installation program can then use other functions to place
 application-specific information directly in WIN.INI.

 A better solution is to write a small Windows program to install your
 Windows application. The installation program can use Windows functions (for
 example, GetProfileString and WriteProfileString) to modify the Windows
 configuration file. With this method, the information is automatically
 placed in either OS2.INI or WIN.INI, depending on whether it is
 system-related or application-specific.

 Note that this method requires that the WLO dynamic-link libraries be
 installed. Copy the WLO dynamic-link libraries first, using a
 character-based OS/2 program such as Wloinst. Make sure the libraries are
 copied to a directory referenced by the LIBPATH environment variable;
 otherwise, the system must be rebooted before the installation can be
 completed.


 2.7.6  Sample Shipping List

 Shipping an application converted by the WLO Development Kit also involves
 shipping various files provided with the WLO Development Kit. These include,
 at a minimum, the WLO mapping-layer dynamic-link libraries. It is necessary
 to ship the retail WLO dynamic-link libraries, the appropriate language
 version of Help Manager (if the application requires it), the relinked WLO
 application, and any data files. It is also necessary to install these files
 on behalf of the user, which means you must create an OS/2 installation
 program.

 If your installation program is a Windows program, you must first use a
 character-based initial program (or a .CMD batch program) to install the WLO
 dynamic-link libraries on the destination OS/2 system, before attempting to
 run your Windows installation program.

 In addition to the WLO dynamic-link libraries, which Wloinst installs, the
 following files would be shipped with an English version of the sample WLO
 application Reversi:

 \0 WLO file                       Recommended installation location
 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

 \eWLO\eSAMPLES\eREVERSI\eREVERSI.  x:\eREVERSI
 EXE

 \eWLO\eSAMPLES\eREVERSI\eREVERSI.  x:\eREVERSI
 HLP

 \eWLO\eBIN\eWINHELP.EXE           x:\eREVERSI


 Note that the letter x is an arbitrary drive letter used for installation
 purposes.



 Chapter 3  Limitations on Converted Applications
 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ




 3.1  Overview

 This chapter discusses limitations on converted applications running with
 OS/2. Most limitations reflect fundamental differences between OS/2 and
 Windows. You should be aware of the following limitations:

   ž   Private device drivers (DOS, Windows, GDI, TSR)

   ž   Direct interrupt calls (for example, Interrupt 21H, 2FH)

   ž   Palette management

   ž   Windows 32-bit memory-management API functions (WINMEM32.DLL)

   ž   Direct port input/output

   ž   Application setup modifications

   ž   Imperfect graphic pixel (pel) emulation

   ž   Dependencies on a common LDT (local descriptor table)

   ž   Exported segment selectors (for example, __0040H, __B800H)

   ž   Extended-memory and expanded-memory dependencies

   ž   Sound API functions

   ž   Debug API functions

   ž   Some bitmap and region API functions

   ž   Critical-execution sections (assembly code bounded by CLI/STI)


 Depending upon whether your WLO application requires a particular service,
 you may need to develop code to overcome one or more limitations. The
 following sections describe the limitations in detail.


 3.2  Mixed OS/2 and Windows Graphics

 When a Windows application is running in OS/2, it still behaves as though it
 were running in Windows. The WLO mapping layer maps Windows functions,
 messages, handles, and structures into their appropriate Presentation
 Manager counterparts. Therefore, Windows objects such as device contexts,
 window handles, bitmap handles, and accelerator-table handles cannot be used
 interchangeably between OS/2 functions and Windows functions. For example,
 it is not possible to use the OS/2 function GpiPolySpline to draw a spline
 in a Windows device context.


 3.3  Differences in Windows Graphics Functions

 The palette-management functions of Windows version 3.0 are not implemented
 in the WLO mapping layer. All calls to palette-management functions simply
 return without doing anything. Similarly, the Windows function FloodFill
 does nothing in a converted WLO application.

 You may also notice slight differences at the pixel level when your
 converted application draws paths by using Windows graphics functions. These
 differences, which are due to rounding errors, are most noticeable in
 drawing applications. In Windows, pixels lie between points in the
 coordinate system, but in Presentation Manager, pixels lie exactly on
 points. This difference affects the number of pixels in a path. A path
 consists of all pixels through which the path passes as well as the pixels
 "inside" the path. Since pixels in Windows lie between points, a Windows
 path does not include pixels on the path; it includes only pixels inside the
 path. A Presentation Manager path, however, includes the pixels both on and
 inside the path. This means Presentation Manager paths typically contain
 more pixels than identical Windows paths. For example, a filled 4-by-3
 rectangle in Windows contains 6 pixels; the same rectangle in Presentation
 Manager contains 12 pixels.

 Because of the differences in graphic-measurement coordinates between
 Windows and Presentation Manager, some imperfect graphic emulation may
 result. Although the WLO mapping layer corrects the differences for
 rectangular objects and straight line segments, slight discrepancies or
 "off-by-one" errors may occur when an application attempts to draw polygons
 by using a fill operation or line segments. A typical example of this occurs
 when an application draws a filled polygon by using a NULL pen. In Windows,
 the outer edge of the polygon would be invisible, even in places where two
 edges of the polygon were identical (on top of each other) on the screen. In
 Windows, only the filled regions would appear; in Presentation Manager, both
 the filled regions and the edges would appear. This can result in unwanted
 line segments in the polygon. The solution, in this case, is to "pick up"
 the pen in between filled regions.

 The only raster operations the WLO mapping layer supports are the overpaint
 and XOR operations. This is a problem with styled lines, since in
 Presentation Manager there is no concept of a styled-line background. The
 WLO mapping layer attempts to simulate a styled line by drawing the line
 twice, but this method does not provide the same appearance or color as
 styled lines do in Windows.


 3.4  Windows Sound and Profile Functions

 The mapping layer does not support two categories of functions: the sound
 functions and the debug profile functions. Currently, OS/2 offers no
 equivalent to the Windows sound functions. However, the Windows sound model
 is dated and generally unused in current Windows applications.

 OS/2 version 1.21 currently offers no support for the profile functions
 available in Windows.


 3.5  EMS and XMS Support

 Windows version 3.0 supports the Lotus/Intel/Microsoft Enhanced Memory
 Specification (LIM EMS) and Lotus/Intel/Microsoft Expanded Memory
 Specification (LIM XMS), allowing Windows applications to access memory
 beyond the DOS 640K boundary. The WLO mapping layer does not provide EMS or
 XMS emulation. Typically, Windows applications running in protected mode do
 not require expanded or extended memory, since most applications written for
 Windows version 3.0 use Windows protected-mode memory-allocation functions.
 In OS/2, there is no equivalent to Windows real mode, since OS/2 runs only
 in protected mode. Therefore, if any of your applications require EMS or XMS
 support, you must modify them to use Windows protected-mode
 memory-management functions, standard C run-time memory functions, or direct
 OS/2 memory-management functions.

 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
 Note

 The WLO mapping layer does respond to EMS query calls. When an application
 queries whether EMS support is available, the WLO mapping layer responds
 with the proper return code, indicating support is not available. The
 mapping layer does not support XMS availability calls.
 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ


 3.6  Exported Selectors and Port Input and Output

 The WLO mapping layer does not support the use of memory selectors exported
 from the kernel to access the BIOS data segment or video memory (for
 example, __0040H, __B800H). You need an OS/2 device driver to access memory
 in this way. Similarly, WLO applications cannot directly access I/O ports
 but must use an OS/2 device driver or add an IOPL segment to do so.


 3.7  Multiple Instances of the Same Application

 The previous instance handle passed to the WinMain function of a WLO
 application will always be zero. This may cause problems for an application
 that uses a nonzero value. If necessary, a WLO application can use the
 FindWindow function to detect a previous instance.


 3.8  Hook Procedures for System Hooks

 To be accessible to multiple processes, hook procedures for system hooks
 must be in a dynamic-link library. The same rule applies to subclassing
 Windows procedures for different processes.


 3.9  Windows Debugging Features

 Windows provides various debugging aids, which are generally enabled by
 entries in the WIN.INI file. These debugging aids apply to the Windows
 environment only and do not have counterparts in OS/2. The Windows debugging
 features EnableHeapChecking, EnableSegmentChecksum, EnableFreeChecking and
 FreezeGlobalMotion are not available in OS/2.


 3.10  File Access and Compatibility Mode in OS/2

 OS/2 does not support compatibility mode. This is true for the Windows
 functions OpenFile and _lopen as well as for the Interrupt 21H functions
 called by the Windows version 3.0 function Dos3Call. The mapping layer uses
 a conservative approach, mapping these functions to the OS/2 function
 DosOpen and replacing them with the constant OPEN_SHARE_DENYREADWRITE.


 3.11  OpenFile Return Value

 The return value for the Windows OpenFile function is -1 if an error occurs;
 this means that zero is a valid file handle. Some older Windows applications
 use only nonzero file handles because zero was an error value in earlier
 releases of Windows. The WLO mapping layer attempts to compensate for this
 behavior, but if you want your application to run with OS/2Äas well as with
 Windows version 3.0Äyou will have to modify the application so that it
 accepts zero as a valid file handle.


 3.12  Menus in OS/2

 Windows provides the option of performing menu-item operations (add, delete,
 modify) by position as well as by item identifier. OS/2 version 1.21 cannot
 identify menu items by position in this way. Therefore, you must be careful
 not to have duplicate menu-item identifiers when performing menu-item
 operations. This problem commonly occurs when you have more than one
 separator item in a menu. Separator items are typically all given the same
 identifier (-1), but it is possible to give each separator a unique
 identifier. If you plan to manipulate individual items in a menu, be sure
 that all items, including separators, have unique identifiers.

 Avoid menu-item identifiers of 0xFFFF and 0xF000 through 0xF040. In
 particular, 0xFFFF is an error indication in OS/2.

 An application receiving an INIT_MENUPOPUP message for a pop-up menu item
 must not remove that item while processing the message. This is a limitation
 of OS/2 version 1.21.

 When a state change in the application would require a different menu to
 drop down from a particular menu item, the application should change the
 menu at the time of the state change, not while processing the
 INIT_MENUPOPUP message.


 3.13  TextOut Limitations

 OS/2 version 1.21 has a limit of 512 characters for any sort of text-output
 functions. For the WLO mapping layer, this limitation applies to the Windows
 functions TextOut, ExtTextOut, DrawText, and GreyString. Attempts to use
 these functions with more than 512 characters result in no output.


 3.14  SetMessageQueue and Code Pages

 As implemented in the dynamic-link libraries of the WLO mapping layer, the
 SetMessageQueue function also automatically sets the code page (character
 set) to the ANSI code page (1004) usually used by Windows applications. Be
 aware of this side effect if your application specifically uses a different
 code page (such as code page 850). For a discussion of code-page issues in
 converted applications, see Chapter 2, "Converting Applications." ’


 3.15  Unsupported Windows Functions

 Following is a list of all the Windows functions that are not supported in
 the current release of the WLO Development Kit; the functions are grouped
 according to their corresponding dynamic-link library:
 .mk
 USER
 ClipCursor
 GetKeyboardState
 GetSysModalWindow
 MenuItemState
 SetKeyboardState
 SetMenuItemBitmaps
 SetSysModalWindow
 TrackPopupMenu

 KERNEL
 AllocSelector
 FreeSelector
 GetCodeHandle
 GetCodeInfo
 GetCurrentPDB
 GetInstanceData
 LimitEmsPages
 SwitchStackBack
 SwitchStackTo

 GetWinMem32Version
 Global16PointerAlloc
 Global16PointerFree
 Global32Alloc
 Global32CodeAlias
 Global32CodeAliasFree
 Global32Free
 Global32Realloc

 GDI
 ExtFloodFill
 FloodFill
 FrameRgn
 CreateEllipticRgn
 CreateEllipticRgnIndirect
 CreatePolyPolygonRgn
 CreatePolygonRgn
 CreateRoundRectRgn
 GetTextCharacterExtra
 SetDIBitsToDevice  (RGB support provided)
 SetTextCharacterExtra
 SetTextJustification
 StretchDIBits         (RGB support provided)

 .in +20P
 .rt
 AnimatePalette
 CreatePalette
 GetNearestPaletteIndex
 GetPaletteEntries
 GetSystemPaletteEntries
 SelectPalette
 SetPaletteEntries
 RealizePalette
 ResizePalette
 UpdateColors

 KEYBOARD
 GetKBCodePage
 GetKeyboardType
 GetKeyNameText
 MapVirtualKey
 OEMKeyScan
 SetSpeed
 ToAscii
 VkKeyScan

 SOUND
 CloseSound
 CountVoiceNotes
 GetThresholdEvent
 GetThresholdStatus
 OpenSound
 SetSoundNoise
 SetVoiceAccent
 SetVoiceEnvelope
 SetVoiceNote
 SetVoiceQueueSize
 SetVoiceSound
 SetVoiceThreshold
 StartSound
 StopSound
 SyncAllVoices
 WaitSoundState

 DEBUG
 ValidateCodeSegments
 ValidateFreeSpaces
 .in -20P


 3.16  BIOS/DOS Interrupts

 For OS/2 version 1.21, only Interrupt 5CH (the NetBIOS interrupt) and
 Interrupt 21H are supported by the Windows version 3.0 functions NetBIOSCall
 and Dos3Call. NetBIOSCall supports all NetBIOS services, except the
 call-back routine with the no-wait option.

 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
 Note

 Table 3.1 lists the supported and unsupported Interrupt 21H functions. This
 table is not final, however, since additional comments are expected from
 developers. If your application uses an unsupported interrupt, please notify
 Microsoft by submitting a support request (SR) through your OnLine account.
 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

 Supported and Unsupported Interrupt 21H Functions"

 Hex function                      Description  WLO support
 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

 00H                          Terminate   Yes
                              program

 01H                          Read        No
                              keyboard
                              and echo

 02H                          Display     No
                              character

 03H                          Auxiliary   No
                              input

 04H                          Auxiliary   No
                              output

 05H                          Print       No
                              character

 06H                          Direct      No
                              console
                              I/O

 07H                          Direct      No
                              console
                              input

 08H                          Read        No
                              keyboard

 09H                          Display     No
                              string

 0AH                          Buffered    No
                              keyboard
                              string

 0BH                          Check       No
                              keyboard
                              status

 0CH                          Flush       No
                              buffer,
                              read
                              keyboard

 0DH                          Reset disk  Yes

 0EH                          Select      Yes
                              disk

 0FH                          Open file   No

 10H                          Close file  No

 11H                          Search for  No
                              first
                              entry

 12H                          Search for  No
                              next entry

 13H                          Delete      No
                              file

 14H                          Sequential  No
                              read

 15H                          Sequential  No
                              write

 16H                          Create      No
                              file

 17H                          Rename      No
                              file

 18H                          Reserved    No

 19H                          Get         Yes
                              current
                              disk

 1AH                          Set disk    Yes
                              transfer
                              address

 1BH                          Get         No
                              default
                              drive data

 1CH                          Get drive   No
                              data

 1DH                          Reserved    No

 1EH                          Reserved    No

 1FH                          Reserved    No

 20H                          Reserved    No

 21H                          Random      No
                              read

 22H                          Random      No
                              write

 23H                          Get file    No
                              size

 24H                          Set         No
                              relative
                              record

 25H                          Set         Yes (0 only)
                              interrupt
                              vector

 26H                          Create new  No
                              PSP

 27H                          Random      No
                              block read

 28H                          Random      No
                              block
                              write

 29H                          Parse       Yes
                              filename

 2AH                          Get date    Yes

 2BH                          Set date    Yes

 2CH                          Get time    Yes

 2DH                          Set time    Yes

 2EH                          Set verify  Yes
                              flag

 2FH                          Get disk    Yes
                              transfer
                              address

 30H                          Get DOS     Yes
                              version
                              number

 31H                          Keep        No
                              process

 32H                          Reserved    No

 33H                          Get/Set     No
                              CTRL+C
                              flag

 34H                          Get InDos   No
                              flag

 35H                          Get         Yes (0,0x67 only)
                              interrupt
                              vector

 36H                          Get disk    Yes
                              free space

 37H                          Reserved    No

 38H                          Get/Set     No
                              country
                              data

 39H                          Create      Yes
                              directory

 3AH                          Remove      Yes
                              directory

 3BH                          Change      Yes
                              current
                              directory

 3CH                          Create      Yes
                              handle

 3DH                          Open        Yes
                              handle

 3EH                          Close       Yes
                              handle

 3FH                          Read        Yes
                              handle

 40H                          Write       Yes
                              handle

 41H                          Delete      Yes
                              directory
                              entry
                              (Unlink)

 42H                          Move file   Yes
                              pointer

 43H                          Get/Set     Yes
                              file
                              attributes
                              (Chmod)

 44H                          Device-dri  Yes (only AL = 0, 8, 9)
                              ver control
                              (IOCTL)

 45H                          Duplicate   Yes
                              file
                              handle

 46H                          Force       Yes
                              duplicate
                              file
                              handle

 47H                          Get         Yes
                              current
                              directory

 48H                          Allocate    No
                              memory
                              block

 49H                          Free        No
                              allocated
                              memory
                              block

 4AH                          Set memory  No
                              block

 4BH                          Execute     Yes (no overlays)
                              program
                                   (EXEC)

 4CH                          End         Yes
                              process

 4DH                          Get return  No
                              code of
                              child
                              process

 4EH                          Find first  Yes
                              file

 4FH                          Find next   Yes
                              file

 50H                          Reserved    No

 51H                          Reserved    No

 52H                          Reserved    No

 53H                          Reserved    No

 54H                          Get verify  Yes
                              state

 55H                          Reserved    No

 56H                          Change      Yes
                              directory
                              entry

 57H                          Get/Set     Yes
                              date and
                              time of
                              file

 58H                          Get/Set     No
                              allocation
                              strategy

 59H                          Get         Yes
                              extended
                              error
                              information

 5AH                          Create      Yes
                              temporary
                              file

 5BH                          Create new  Yes
                              file

 5CH                          Lock/Unlock  Yes
                              file

 5DH                          Reserved    No

 5EH                          Get         No
                              machine
                              name,
                              printer
                              setup

 5FH                          Device      No
                              redirection

 60H                          Reserved    No

 61H                          Reserved    No

 62H                          Get PSP     No
                              address

 63H                          Reserved    No

 64H                          Reserved    No

 65H                          Get         No
                              extended
                              country
                              informatiom

 66H                          Get or set  No
                              code page

 67H                          Set handle  Yes
                              count

 68H                          Commit      Yes
                              file

 69H                          Reserved    No

 6AH                          Reserved    No

 6BH                          Reserved    No

 6CH                          Extended    *
                              open file

 87H                          Get         No
                              process
                              identifier

 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
 Note

 The asterisk (*) in the "WLO support" column of Table 3.1 means that,
 although not supported in the current WLO release, this function will be
 supported in the final release.
 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ



 3.17  Real-Mode C Run-time Functions

 Some Windows applications use real-mode-only functions from the C run-time
 libraries. The custom C run-time libraries in the WLO Development Kit
 provide support for most of these functions by converting Interrupt 21H
 functions to Dos3Call functions. Table 3.2 lists the supported and
 unsupported functions. <TT>Supported and Unsupported\p Real-Mode C Run-time
 Functions"</TT>

 Function                                      WLO support
 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

 bdos                                          Yes

 _bios_disk                                    No

 _bios_equiplist                               No

 _bios_keybrd                                  No

 _bios_memsize                                 No

 _bios_printer                                 No

 _bios_serialcom                               No

 _bios_timeofday                               No

 _chain_intr                                   No

 _disable                                      No

 _dos_allocmem                                 No

 _dos_close                                    Yes

 _dos_creat                                    Yes

 _dos_creatnew                                 Yes

 dosexterr                                     Yes

 _dos_findfirst                                Yes

 _dos_findnext                                 Yes .RT

 _dos_freemem                                  No

 _dos_getdate                                  Yes

 _dos_getdiskfree                              Yes

 _dos_getdrive                                 Yes

 _dos_getfileattr                              Yes

 _dos_getftime                                 Yes

 _dos_gettime                                  Yes

 _dos_getvect                                  Yes (vectors 0 and 67)

 _dos_keep                                     No

 _dos_open                                     Yes

 _dos_read                                     Yes

 _dos_setblock                                 No

 _dos_setdate                                  Yes

 _dos_setdrive                                 Yes

 _dos_setfileattr                              Yes

 _dos_setftime                                 Yes

 _dos_settime                                  Yes

 _dos_setvect                                  Yes (vector 0 only)

 _dos_write                                    Yes

 _enable                                       No

 _harderr                                      No

 _hardresume                                   No

 _hardretn                                     No

 int86                                         No

 int86x                                        No

 intdos                                        Yes

 intdosx                                       Yes

 You can use the supported functions without getting unresolved linker-error
 messages. The unsupported functions will generate unresolved linker errors,
 but you should not be using these real-mode-only functions in any case, as
 there are OS/2 functions to replace them.
 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ







 Microsoft(R) Windows(TM)  Questions and Answers


 For the MS-DOS(R) or PC-DOS Operating System


 Questions and Answers


 This booklet answers some common questions that users ask about Microsoft(R)
 Windows(TM) version 3.0. You might want to read parts of this booklet if you
 are encountering problems with Windows, or if you need information that is
 not in the Microsoft Windows User's Guide. This booklet makes the same
 assumptions, and uses the same conventions, as those described on pages xxi
 through xxv of the Microsoft Windows User's Guide.

 If you cannot find the answer to your problem or question in this booklet,
 or elsewhere in the Microsoft Windows documentation, you can call Microsoft
 Product Support Services. Before calling Microsoft, please see "Calling
 Microsoft Product Support Services" at the end of this booklet. The phone
 numbers listed are for product support in the United States and Canada only.
 If you are outside North America, contact your country's Microsoft
 subsidiary.



 Getting the Information You Need


 This section briefly explains how to find answers in the information that's
 already available to you. Microsoft Windows comes with several valuable
 sources of information:

 The Microsoft Windows User's Guide, which explains how to use Windows and
 how to get the most out of your system. The Microsoft Windows User's Guide
 should supply answers for most of your questions.

 A comprehensive Help system that provides instant information while you're
 using Windows. For information on using Help, see page 70 of the Microsoft
 Windows User's Guide.

 Several text files that provide information on specific hardware, and
 include information that became available after the Microsoft Windows User's
 Guide was printed. The rest of this section explains what is in the text
 files and how to read them.

 The Windows text files are located in your Windows directory. The files are
 as follows:

 README.TXT
 General information about installing and running Windows.

 3270.TXT
 Information about using specific non-Windows 3270 emulation applications.

 NETWORKS.TXT
 Information about running Windows with specific network configurations.

 PRINTERS.TXT
 Information about configuring particular printers and fonts so you can use
 them with Windows.

 SYSINI.TXT
 SYSINI2.TXT
 SYSINI3.TXT
 Procedures for modifying SYSTEM.INI settings (for advanced users only).

 WININI.TXT
 WININI2.TXT
 Procedures for modifying WIN.INI settings (for advanced users only).



 To read the Windows text files:


 1. Double-click the Notepad icon from the Accessories Group in Program
 Manager.

 2. Choose Open from the Notepad File menu.

 3. Double-click the name of the text file you want to read.



 Installing Windows 3.0


 This section addresses some common questions about installing and setting up
 Windows 3.0.



 I am having difficulty installing Windows. Setup halts when it gets to Disk
 2. How can I prevent this?


 If your system halts (in other words, stops responding) before Setup has
 finished installing Windows, your system probably includes incompatible
 software or hardware.

 To eliminate the problem, try each of the following steps in order. Once you
 successfully install Windows, you need not perform the rest of the steps.

 Step 1: Make sure you are using the correct Setup options.

 Restart Setup by typing setup /i at the MS-DOS prompt.

 Carefully check the configuration options that Setup displays on the second
 Setup screen. You must select the options that match your computer's
 configuration.

 If Setup still halts, restart your computer and proceed with Step 2.

 Step 2: Simplify your AUTOEXEC.BAT and CONFIG.SYS files.

 Simplifying these files can eliminate memory-resident software that is
 incompatible with Windows. Use a text editor to edit each file as described
 in the following procedure.

 Disable any command lines for memory-resident programs and unnecessary
 device drivers. (See page 516 of the Microsoft Windows User's Guide for
 information on how to do this.)

 Save your changes to each file.

 Press CTRL+ALT+DELETE to restart your system.

 Try installing Windows again.

 If Setup still halts, restart your computer and proceed with Step 3.

 Step 3: Make sure you are running the correct version of MS-DOS.

 Each computer manufacturer's version of MS-DOS, such as MS-DOS for COMPAQ or
 PC-DOS for IBM systems, should be used only on corresponding systems. For
 example, MS-DOS for COMPAQ should be used only on COMPAQ systems, PC-DOS for
 IBM systems should be used only on IBM systems, and so on. You should use
 the version of MS-DOS that came with your computer.

 To find out what version of MS-DOS you are using, type ver at the MS-DOS
 prompt.

 If you need to install a different version of MS-DOS, do so according to the
 manufacturer's instructions.

 After installing a different version of MS-DOS, restart your system by
 pressing CTRL+ALT+DELETE.

 Try installing Windows again.

 If Setup still halts, restart your computer and proceed with Step 4.

 Step 4: Try setting up Windows without a mouse or network.

 Type setup /i to run Setup again.

 Choose "None" for the mouse and network options, even if your system
 includes a mouse or network.

 These options can sometimes cause incompatibilities with Setup. Once Windows
 is successfully installed, you can add support for both the mouse and the
 network from within Windows (see page 560 of the Microsoft Windows User's
 Guide for more information).

 If you have tried all four steps and still cannot install Windows
 successfully, contact Microsoft Product Support Services. But before calling
 Microsoft, please see "Calling Microsoft Product Support Services" at the
 end of this booklet. Be sure to tell your Microsoft representative that you
 have tried the steps outlined in this booklet.



 How do I set up non-Windows applications that Setup didn't find?


 After you have installed Windows, you can set up additional applications by
 using either Program Manager or Setup. (Use Program Manager if you are
 adding only one or two applications. Setup is easier for adding several
 applications.)

 For information on using Program Manager to add applications to Windows, see
 page 88 of the Microsoft Windows User's Guide. For information on using
 Setup to add applications, see page 561 of the Microsoft Windows User's
 Guide.



 How can I use my special hardware (display, printer, tablet, etc.) with
 Windows?


 To use your hardware with Windows, you install a Windows driver for that
 particular type of hardware. A driver is a file that allows Windows to
 communicate with hardware. Driver filenames contain the .DRV extension.

 Setup automatically installs the correct drivers when you select the
 appropriate hardware options. For example, if you tell Setup that you have a
 POSTSCRIPT  printer, Setup installs the POSTSCRIPT printer driver,
 PSCRIPT.DRV.

 Windows comes with drivers for most popular types of displays, printers, and
 other devices. Even if your special hardware is not listed among the
 hardware options that Setup displays, you might be able to use that hardware
 with Windows.

 To use your special hardware with Windows:

 Check the Hardware Compatibility List included in your Windows package for
 the hardware that Windows supports. If your hardware is on the list, Windows
 includes a driver for that hardware. In that case, use Setup to install your
 hardware.

 If your hardware is not on the Hardware Compatibility List, but can emulate
 another brand of hardware that Windows supports, tell Setup you have the
 type of hardware that is being emulated. For example, if your dot-matrix
 printer can emulate an Epson dot-matrix printer, tell Setup that you have an
 Epson printer.

 If your hardware is not on the Hardware Compatibility List and cannot
 emulate any of the hardware that Windows supports, check the Microsoft
 Windows Supplemental Driver Library.

 The Supplemental Driver Library is a collection of Windows drivers for less
 commonly used hardware. The library is not included in the Windows package,
 but you can get it for free or for a nominal charge. There are several ways
 to get the Supplemental Driver Library:

 If you have access to an electronic bulletin board, such as Microsoft
 OnLine, CompuServe, or GEnie, you can get a free copy of the library.

 On Microsoft OnLine, the Supplemental Driver Library is located in the
 Software Library.

 On CompuServe, the Supplemental Driver Library is located in the Software
 Library in the Microsoft Connection (MSCON).

 On GEnie, the Supplemental Driver Library is located in Library 2 of the
 Microsoft RoundTable Software Library.

 If you don't have access to one of the above bulletin boards, you may be
 able to get the Supplemental Driver Library from your user group or directly
 from your hardware manufacturer.

 Or you can order a copy of the Supplemental Driver Library directly from
 Microsoft. For more information, call 1-800-426-9400 (in the U.S. and
 Canada).

 If the Supplemental Driver Library does not include a driver for your
 hardware, contact your hardware manufacturer for a Windows 3.0 device driver
 designed for your hardware.



 How do I set up Windows to run in conjunction with a Novell network?


 Follow the instructions in the NETWORKS.TXT file, located in your Windows
 directory. (You can open NETWORKS.TXT using Notepad.)



 Running Windows 3.0


 This section provides answers to some common questions about starting and
 running Windows 3.0.



 How can I get Windows to run on my system? When I type win, my system halts.


 If your system halts (in other words, stops responding) when you try to
 start Windows, it is likely that your system includes hardware or software
 that is incompatible with Windows. The solution depends on the type of
 system you have. To get Windows running on your system, follow these steps:

 Step 1: Make sure you are using the correct Setup options.

 Run Setup by typing setup /i at the MS-DOS prompt.

 Carefully check the configuration options that Setup displays on the second
 Setup screen.

 To get Windows to work properly, you must select the options that match your
 computer's configuration.

 Check the Hardware Compatibility List, included in your Windows package, for
 your system type. If the Hardware Compatibility List has an asterisk by your
 system type, you must make sure that the correct system type is selected in
 Setup. (For more information on running Setup, see page 563 of the Microsoft
 Windows User's Guide.)

 After completing Setup, choose Reboot, or return to DOS.

 Type win to start Windows.

 If your system still halts, restart it and continue with Step 2.

 Step 2: Try running Windows in real mode.

 Type win /r to start Windows in real mode.

 If your system halts when you type win /r, you probably still have the wrong
 video display or system type selected. Repeat Step 1 again.

 If Windows starts successfully when you type win /r, but your system still
 halts when you type win, restart your system and continue with Step 3.

 Step 3: Simplify your AUTOEXEC.BAT and CONFIG.SYS files.

 Simplifying these files can eliminate memory-resident software that is
 incompatible with Windows. Use a text editor to edit each file as described
 in the following procedure.

 Disable any command lines for memory-resident programs and unnecessary
 device drivers. (For more information, see page 516 of the Microsoft Windows
 User's Guide.)

 Save your changes to each file.

 Press CTRL+ALT+DELETE to restart your system, and type win to start Windows.

 If your system still halts, restart your system and proceed with Step 4.

 Step 4: Make sure HIMEM is using the correct system type.

 Using a text editor, open your CONFIG.SYS file and find the HIMEM.SYS
 command line, which starts the HIMEM memory manager.

 Add the /M switch by typing /m: and the number for your system type at the
 end of the HIMEM.SYS command line. (See the following table for a list of
 system type numbers.)

 The /M switch tells HIMEM what type of system you have. Normally, HIMEM
 automatically detects your system type. However, HIMEM might be unable to
 detect some types of computers; this could cause your system to halt when
 you start Windows.

 The following table lists the system-type numbers to specify after the /M
 switch.

 Number    System Type
 1    IBM PC/AT or 100 percent compatible
 2    IBM PS/2
 3    Phoenix Cascade BIOS
 4    HP Vectra (A and A+)
 5    AT&T 6300 Plus
 6    Acer 1100
 7    Toshiba 1600 and 1200XE
 8    Wyse 12.5 MHz 286

 For example, if your system is a Toshiba 1200XE, your HIMEM.SYS command line
 might look like the following:

 device = c:\himem.sys /m:7

 If your system is a PC-compatible computer not listed above, try using the
 /m:3 setting.

 Save the changes to your CONFIG.SYS file.

 Press CTRL +ALT+DELETE to restart your system. Then type win to start
 Windows.

 If your system still halts, restart it and proceed with Step 5 (for 80386 or
 80486 systems only).

 Step 5: Add an EMMEXCLUDE line to your SYSTEM.INI file.

 This step is for 80386 or 80486 systems with at least 2 megabytes of memory.

 Using a text editor, open your SYSTEM.INI file, which is located in your
 Windows directory.

 Find the [386Enh] section of the file, and type the following line at the
 beginning of the [386Enh] section:

 EMMEXCLUDE = C000-D000

 Save your changes to the SYSTEM.INI file.

 Type win to start Windows.

 If Windows still does not run, call Microsoft Product Support Services for
 assistance. But before you call Microsoft, see "Calling Microsoft Product
 Support Services" at the end of this booklet.



 When I type win, Windows starts in real mode, even though my system is an
 80286 (or 80386). How can I get Windows to run in a different mode?


 If you have an 80286, 80386, or 80486 system, but Windows starts in real
 mode when you type win, one of the following might be the problem:

 Your system does not have enough memory to run in standard or 386 enhanced
 mode. You need at least 1 megabyte of memory to run Windows in standard
 mode, and 2 megabytes to run in 386 enhanced mode.

 Your system has enough memory, but the HIMEM memory manager is not properly
 installed.

 Your system has enough memory, but your CONFIG.SYS file is starting
 utilities that take up too much memory.

 To get Windows to run in standard or 386 enhanced mode, try each of these
 steps in order. Once Windows starts in the mode you want, you need not
 perform the remaining steps.

 Step 1: Make sure your CONFIG.SYS file contains a command line for
 HIMEM.SYS.

 In order for Windows to use your system's extended memory, your CONFIG.SYS
 file must contain a device command line for the HIMEM memory manager.

 Using a text editor, open your CONFIG.SYS file and look for a command line
 such as the following:

 device = c:\himem.sys

 If your CONFIG.SYS file does not contain a HIMEM.SYS command line, rerun
 Setup by typing setup at the MS-DOS prompt.

 If your CONFIG.SYS file does contain a HIMEM.SYS command line, make sure the
 path is correct. The HIMEM.SYS file should exist in the location that the
 command line specifies.

 Press CTRL+ALT+DELETE to restart your system, and try running Windows again.

 To tell Windows to start only in standard mode, type win /s. Windows will
 not start if it cannot start in standard mode.

 To tell Windows to start only in 386 enhanced mode, type win /3. Windows
 will not start if it cannot start in 386 enhanced mode.

 If Windows does not start in the mode you want, continue with Step 2.

 Step 2: Disable any device drivers that might use extended memory.

 Although your system might have 1 or 2 megabytes of memory, your CONFIG.SYS
 file might start device drivers that use extended memory. If so, Windows
 might not run in standard or 386 enhanced mode.

 Open your CONFIG.SYS file again.

 Disable any DEVICE commands for device drivers that might be taking up
 extended memory. (For more information, see page 516 of the Microsoft
 Windows User's Guide.) Do not disable the HIMEM.SYS command line.

 Save any changes to your CONFIG.SYS file.

 Press CTRL+ALT+DELETE to restart your system, and try running Windows again.

 If Windows does not start in the mode you want, continue with Step 3.

 Step 3: Disable your graphics card's auto-switching capabilities.

 If you are using a graphics card that has auto-switching capabilities,
 disable auto-switching.

 Normally, to disable auto-switching, you must change a hardware switch
 located on the graphics card. Follow the instructions in the documentation
 that accompanied your graphics card.

 After disabling the graphics card's auto-switching capability, restart your
 system by turning the power off and on again.

 Try running Windows again.

 If Windows still does not run in the mode you want, call Microsoft Product
 Support Services for assistance. But before calling Microsoft, see "Calling
 Microsoft Product Support Services" at the end of this booklet.

 For information on starting Windows in a specific mode, see page 428 of the
 Microsoft Windows User's Guide.



 How can I improve the speed at which Windows runs?


 There are several things you can do to improve speed. See page 503 of the
 Microsoft Windows User's Guide for a discussion of the methods for improving
 the speed and efficiency of Windows. Chapter 13, "Optimizing Windows,"
 explains how to configure your system for top efficiency with Windows.



 I am using a Logitech mouse with Windows and it is not working properly. How
 can I solve this problem?


 Occasionally, when a Logitech mouse is used with Windows 3.0, the cursor
 moves erratically or not at all. This could be due to one of the following:

 Setup changed the path from your Logitech mouse driver to the driver
 included with Windows. To determine if this is the problem, check your
 mouse-driver command line in either your CONFIG.SYS file or your
 AUTOEXEC.BAT file.

 If your Logitech mouse driver is MOUSE.SYS, the command line will be in your
 CONFIG.SYS file. If the MOUSE.SYS command line is similar to the following,
 your system is being directed to the wrong mouse driver:

 device = c:\windows\mouse.sys

 If your Logitech mouse driver is MOUSE.COM, the command line will be in your
 AUTOEXEC.BAT file. If the MOUSE.COM command line is similar to the
 following, your system is being directed to the wrong mouse driver:

 c:\windows\mouse.com

 Change the command line so that it specifies the directory that contains
 your original Logitech mouse driver, rather than the Windows directory.

 You don't have an updated mouse driver for non-Windows applications. You
 need version 4.1 or later of the Logitech mouse driver. To get an updated
 Logitech mouse driver, contact Logitech Technical Support at 415-795-8100
 (in the U.S. and Canada).



 Running Applications


 This section provides answers to some common questions about running
 applications with Windows.

 The Microsoft Windows User's Guide provides some troubleshooting tips for
 running applications. If you are having problems with running applications,
 see page 482 of the Microsoft Windows User's Guide.



 How do I run my non-Windows applications with Windows 3.0?


 There are many ways to run a non-Windows application with Windows. The
 following are the most common methods:

 Add the application (program item) to a group in Program Manager, and then
 start it by double-clicking its icon in Program Manager. See page 88 of the
 Microsoft Windows User's Guide for more information.

 Start the application from File Manager by double-clicking the application's
 filename. See page 137 of the Microsoft Windows User's Guide for more
 information.

 To run some non-Windows applications properly, Windows requires additional
 information about the application. For example, Windows might need to know
 how the application uses the video display. You specify such information in
 a program information file (PIF). For more information on PIFs, and on
 running non-Windows applications in general, see Chapter 12 of the Microsoft
 Windows User's Guide.



 How do I get my non-Windows application to run in a window?


 In 386 enhanced mode, you can run some non-Windows applications in a window.
 (You cannot run non-Windows applications in a window if you are running
 Windows in real mode or standard mode.)

 To get a non-Windows application to run in a window:

 Use PIF Editor to open the application's program information file (PIF), if
 it has one. (If it doesn't have a PIF, you should create one.) For
 information on creating and editing PIFs, see page 446 of the Microsoft
 Windows User's Guide.

 Make sure the Display Usage option is set to "Windowed," rather than to
 "Full Screen," in the application's PIF. For information on the Display
 Usage PIF option, see page 460 of the Microsoft Windows User's Guide.

 Make sure the Display Options are set correctly in the Advanced section of
 the application's PIF. For information on the Advanced options, see page 462
 and 469 of the Microsoft Windows User's Guide.

 NOTE
 Many non-Windows applications cannot run in a window because they perform
 graphics or other screen interactions that are incompatible with Windows'
 screen management. Most of these applications can run successfully with
 Windows as long as they run in a full-screen display, rather than in a
 window.



 Why doesn't the mouse work with my non-Windows application when I run it
 with Windows?


 You can use the mouse with a non-Windows application only when running the
 application in a full-screen display. When you run the application in a
 window, the mouse performs Windows tasks, such as moving or resizing the
 window; it does not provide input to the application running in that window.

 If the mouse does not work when you run the application in a full-screen
 display, you probably don't have a mouse driver installed for non-Windows
 applications. (Windows has its own built-in mouse driver, which enables you
 to use the mouse with Windows and Windows applications.) Check your
 CONFIG.SYS and AUTOEXEC.BAT files to ensure that your mouse driver is
 installed properly.



 How can I get Windows to start an application automatically when I start
 Windows?


 There are several ways to start an application when you start Windows:

 To start an application and Windows at the same time, type the application
 command on the Windows command line. For example, to start both Windows and
 Notepad, you could type the following at the MS-DOS prompt:

 win notepad.exe

 For information on the Windows command line, see page 425 of the Microsoft
 Windows User's Guide.

 To start an application automatically each time you start Windows, list that
 application on the run= command line of your WIN.INI file. (Your WIN.INI
 file is a text file located in your Windows directory. To edit the file, use
 a text editor, such as Notepad.)

 For example, the following command line would automatically start Microsoft
 Word each time you start Windows:

 run = c:\word\word.exe

 You can list more than one application on the run= command line. If an
 application is not in the Windows directory, include the full pathname to
 the executable application file.

 To automatically load an application in icon form each time you start
 Windows, list that application on the load= command line of your WIN.INI
 file. For example, the following command line would load Microsoft Word in
 icon form each time you start Windows:

 load = c:\word\word.exe

 You can list more than one application on the load= command line. If an
 application is not in the Windows directory, include the full pathname to
 the executable application file.

 For more information about the WIN.INI file, see the contents of the files
 WININI.TXT and WININI2.TXT (also located in your Windows directory).



 My applications always start with my Windows directory as the default
 directory. How can I get them to start with a different default directory?


 Normally, applications start with the Windows directory as the application's
 default directory. However, you can use the directory that contains the
 application file as the default directory. Or you can specify a different
 directory altogether.

 To use the application's directory as the default directory:

 Select the application's icon in Program Manager.

 Choose Properties from the File menu.

 In the Command Line box, type the full pathname of the application's
 executable file.

 For example, if the path to your application is C:\REFLEX\REFLEX.EXE and you
 want to it to use its own directory as the default directory, you would type
 the following in the Command Line box:

 C:\REFLEX\REFLEX.EXE

 Choose OK.

 Instead of using the application's directory as the default directory, you
 can specify a completely different directory. The method for doing so,
 however, differs for Windows and non-Windows applications.

 To specify a different default directory for aWindows application:

 Edit your AUTOEXEC.BAT file using a text editor, such as Notepad.

 Add the directory that contains the application to the PATH command line.

 For example, if the pathname of your application is
 C:\WINDOWS\CORELDRW\COREL.EXE, your PATH command might look like the
 following:

 path=c:\;c:\windows;c:\dos;c:\windows\coreldrw

 Save the changes to your AUTOEXEC.BAT file, and restart your system by
 pressing CTRL+ALT+DELETE.


 Start Windows and select the application's icon in Program Manager.

 Choose Properties from the File menu.

 In the Command Line box, type the full pathname of the default directory you
 want, followed by the name of the application's executable file.

 For example, if your application is named COREL.EXE, and you want to use the
 directory D:\DRAWINGS as the default directory, you would type the following
 in the Command Line box:

 D:\DRAWINGS\COREL.EXE

 Choose OK.

 To specify a different default directory for a non-Windows application:

 Use PIF Editor to edit the application's program information file (PIF). (If
 the application does not have a PIF, you should create one.) For information
 on using PIF Editor, see page 446 of the Microsoft Windows User's Guide.

 Type the pathname of the default directory in the Startup Directory box.

 Save your changes to the application's PIF. (You should save the PIF in your
 Windows directory or in the directory that contains the application file.)



 How do I provide expanded memory for my non-Windows applications when I run
 them with Windows 3.0?


 If you have an 8086, an 8088, or an 80286 computer, and you use applications
 that need expanded memory, you must have an expanded memory board. Your
 CONFIG.SYS file must contain a command line for the expanded memory manager
 that came with your memory board.

 If you have an 80386 or 80486 computer and you run Windows in 386 enhanced
 mode, Windows can simulate expanded memory for applications that require it,
 even if your system does not have expanded memory. You can use each
 application's program information file (PIF) to specify how much expanded
 memory a particular application needs. For information about working with
 PIFs, see page 444 of the Microsoft Windows User's Guide.

 NOTE

 If you have an 80386 or 80486 system, you can also install EMM386, a utility
 that provides expanded memory for applications when you are not running
 Windows in 386 enhanced mode. For more information, see page 540 of the
 Microsoft Windows User's Guide.



 How do I customize the icons in Program Manager?


 There are several ways to adjust and customize the program item icons in
 Program Manager:

 If more than one icon is available for a program item, you can choose a
 different icon by choosing Properties from the File menu and then choosing
 Change Icon in the Program Item Properties dialog box. You cycle through the
 avail- able icons by choosing View Next. See pages 90 and 96 of the
 Microsoft Windows User's Guide for more information.

 You can adjust the spacing between icons by choosing the Desktop icon from
 Control Panel, then typing a number in the Icon Spacing box. See page 156 of
 the Microsoft Windows User's Guide for more information.

 You can use an icon drawing program to create your own icon design, save it
 in an icon file with the extension .ICO, and specify that file in the
 Program Item Properties dialog box. (Windows does not include an icon
 drawing program. One is included with the Microsoft Windows Software
 Development Kit version 3.0. In addition, there are several "shareware" icon
 editors available that create icons compatible with Windows 3.0.)

 NOTE

 Your customized icons appear only in the Program Manager window. When you
 run an application that has a customized icon, its original icon is used
 when you minimize the running application.



 What do I do if I get the message "Unrecoverable Application Error"?


 This error occurs only when Windows is running in standard mode or 386
 enhanced mode. It indicates that a Windows application has caused a
 protection violation (that is, an application has used an area of memory to
 which it does not have access, potentially corrupting other code in that
 area of memory).

 If you receive this message, you should immediately close all applications,
 exit Windows and restart your system. Don't continue using Windows without
 restarting your system. When this error occurs, it means that memory might
 have been corrupted. Until you restart your system, other applications, or
 Windows itself, might behave erratically or terminate unexpectedly.

 NOTE

 Once one application causes this error, other applications might
 subsequently display the same error, even though they are not actually the
 cause of the problem.

 To prevent an unrecoverable application error from recurring, follow these
 steps:

 Step 1: Make sure the application was designed for Windows 3.0.

 Many unrecoverable application errors are caused by running a Windows
 application that was designed for older versions of Windows.

 If the error occurred when you were running an application designed for
 Windows 3.0, continue with Step 2.

 Step 2: Run Setup again to ensure that Windows is set up properly.

 An unrecoverable application error might result if you selected an incorrect
 computer or network during Setup.

 Exit Windows and type setup at the MS-DOS prompt.

 Check the settings that Setup displays to ensure that they match your
 hardware configuration.

 Exit Setup and restart Windows.

 If the error recurs, continue with Step 3.

 Step 3: Simplify your AUTOEXEC.BAT and CONFIG.SYS files.

 Simplifying these files can eliminate memory-resident software that is
 incompatible with Windows. Use a text editor to edit each file as described
 in the following procedure.

 Disable any command lines for memory-resident programs and unnecessary
 device drivers. (See page 516 of the Microsoft Windows User's Guide for
 information on how to do this.)

 Save your changes to each file.

 Press CTRL+ALT+DELETE to restart your system. Then restart Windows.

 If the error recurs, proceed with Step 4.

 Step 4: Make sure you are running the correct version of MS-DOS.

 Each computer manufacturer's version of MS-DOS, such as MS-DOS for

 COMPAQ or PC-DOS for IBM systems, should be used only on corresponding
 systems. For example, MS-DOS for COMPAQ should be used only on COMPAQ
 systems, PC-DOS for IBM systems should be used only on IBM systems, and so
 on. You should use the version of MS-DOS that came with your computer.

 To find out what version of MS-DOS you are using, type ver at the MS-DOS
 prompt.

 If you need to install a different version of MS-DOS, do so according to the
 manufacturer's instructions.

 After installing a different version of MS-DOS, restart your system by
 pressing CTRL+ALT+DELETE, and restart Windows.

 If the error recurs, contact Microsoft Product Support Services. But before
 calling Microsoft, see "Calling Microsoft Product Support Services" at the
 end of this booklet.



 What do I do if I get the message "Out of memory" when starting a
 non-Windows application?


 If you get the message "Out of memory" when you try to run an application,
 try the following:

 Minimize Windows applications (display them as icons).

 Close other applications.

 If you are running Windows in 386 enhanced mode, try running applications in
 a full-screen display instead of in a window.

 If you are running Windows in 386 enhanced mode, tell Windows not to allow
 non-Windows applications to run in the background. To do so, edit each
 application's program information file (PIF) and make sure the Execution:
 Background box is not selected.

 Clear or save the contents of the Clipboard.

 If you are using a desktop wallpaper, set the Wallpaper option to None.

 For more information on freeing up memory, see page 478 of the Microsoft
 Windows User's Guide. For more information on editing PIF options for 386
 enhanced mode, see page 437 of the Microsoft Windows User's Guide.



 Printing


 This section provides answers to some common questions about printing.

 The Microsoft Windows User's Guide provides some troubleshooting tips for
 printing. If you are having problems with printing in Windows, see page 211
 of the Microsoft Windows User's Guide.



 I can't print from Windows. How can I solve this problem?


 If you cannot print information from Windows, see page 212 of the Microsoft
 Windows User's Guide for a list of common printing problems and their
 solutions.

 If the Microsoft Windows User's Guide does not address your printing
 problem, try each of the following steps in order. Once you can print
 successfully from Windows, you need not perform the remaining steps.

 Step 1: Make sure you can print when you are not running Windows.

 If you cannot print when Windows is not running, the problem might be with
 your printer, printer cables, or printer port.

 If you can print when Windows is not running, but you still cannot print
 from Windows, continue with Step 2.

 Step 2: Check to make sure your printer is supported by Windows.

 For a complete list of printers that Windows supports, see the Hardware
 Compatibility List that was included in your Windows package.

 If your printer is not on the Hardware Compatibility List, check to see if
 it is included with the Supplemental Driver Library. (For additional
 information on the Supplemental Driver Library, see the question "How can I
 use my special hardware with Windows?" earlier in this booklet.)

 If your printer is on the Hardware Compatibility List, and you still cannot
 print from Windows, continue with Step 3.

 Step 3: Make sure your printer is installed properly for use with Windows.

 See pages 158 and 164 of the Microsoft Windows User's Guide for information
 on installing and configuring a printer for use with Windows.

 If your printer is properly installed and you still cannot print from
 Windows, continue with Step 4.

 Step 4: For a serial printer, make sure the communications settings are
 correct.

 If your printer is attached to a serial port (COM1, COM2, and so on),
 incorrect communications settings might prevent you from being able to print
 from Windows.

 Make sure the communications settings are correct for the serial port. See
 page 175 of the Microsoft Windows User's Guide for information on
 configuring a serial port.

 If the communications settings are correct, and you still cannot print from
 Windows, continue with Step 5.

 Step 5: Make sure that the SET TEMP command is set properly.

 Use a text editor to edit your AUTOEXEC.BAT file as described in the
 following procedure.

 See if the file contains a SET TEMP command.

 In order to print from Windows, your AUTOEXEC.BAT file should contain a SET
 TEMP command that specifies a drive with at least 1 megabyte of free disk
 space.

 If the file does not already contain a SET TEMP command, you should add one.

 For example, if drive D has more than 1 megabyte of free disk space, the SET
 TEMP command might look like the following:

 set temp = d:\

 Save the file.

 Restart your system by pressing CTRL+ALT+DELETE, restart Windows, and try
 printing again.

 If you still cannot print from Windows, continue with Step 6.

 Step 6: Make sure you are running the correct version of MS-DOS.

 Each computer manufacturer's version of MS-DOS, such as MS-DOS for COMPAQ or
 PC-DOS for IBM systems, should be used only on corresponding systems. For
 example, MS-DOS for COMPAQ should be used only on COMPAQ systems, PC-DOS for
 IBM systems should be used only on IBM systems, and so on. You should use
 the version of MS-DOS that came with your computer.

 To find out what version of MS-DOS you are using, type ver at the MS-DOS
 prompt.

 If you need to install a different version of MS-DOS, do so according to the
 manufacturer's instructions.

 After installing a different version of MS-DOS, restart your system by
 pressing CTRL+ALT+DELETE, restart Windows, and try printing again.

 If you still cannot print from Windows, call Microsoft Product Support
 Services for assistance. But before calling Microsoft, see "Calling
 Microsoft Product Support Services" at the end of this booklet.



 How do I print to a file?


 To print to a file, connect your printer to the printer port named FILE. See
 page 210 of the Microsoft Windows User's Guide for more information.



 Using DayBook


 This section provides answers to some common questions about using DayBook,
 an electronic organizer that is included with Windows 3.0.


 Do I need a mouse in order to use DayBook?


 Yes, a mouse is required to use DayBook.




 What can I do to increase the speed of DayBook?


 DayBook is written in a script language, and does not run as fast as
 programs that were written in a programming language and then compiled. In
 spite of this basic speed limitation, there are several things that you can
 do to speed up DayBook:

 Make sure there is as much free physical extended memory as possible. To do
 so, close other applications and, if you are using a desktop wallpaper, set
 the Wallpaper option to None.

 Turn off DayBook's opening animation by choosing Turn Off Animation
 from DayBook's File menu.

 Tell DayBook to run in black and white by changing the StartupSysColors=
 command line in the [ToolBook] section of the WIN.INI file, so the line
 appears as follows:

 StartupSysColors=False

 Use the SMARTDrive disk-caching utility, and allocate it as much memory as
 you can afford, up to about 2048K. (For information on using SMARTDrive, see
 page 530 of the Microsoft Windows User's Guide.)

 Defragment the information on your hard disk about once a week by running
 CHKDSK /F and a disk-compaction utility directly from MS-DOS (outside of
 Windows). Doing so keeps your hard disk running as fast and efficiently as
 possible. For information on using the CHKDSK utility and compacting your
 hard disk, see pages 510 and 512 of the Microsoft Windows User's Guide.



 Calling Microsoft Product Support Services


 This section provides answers to some common questions about contacting
 Microsoft Product Support Services.



 When should I call Microsoft Product Support Services?


 You should call Microsoft Product Support Services if you are encountering a
 problem with a Microsoft product that you cannot solve on your own. You
 should also call if you have a question and the answer is not in the manual
 or in the on-line text files that accompany the product (for example,
 README.TXT).


 What number should I call for Microsoft Windows 3.0 product support?


 For answers to questions about Microsoft Windows 3.0, call Microsoft Product
 Support Services at 206-637-7098 (in the U.S. and Canada). If you are
 outside North America, contact your country's Microsoft subsidiary. Before
 calling, you should read the answer to the question "What information should
 I have ready when I call Microsoft product support," later in this section.



 What number should I call for DayBook and ToolBook product support?


 For answers to questions about DayBook, call Microsoft Product
 Support Services at 206-637-7098 (in the U.S. and Canada).

 For answers to questions about the full (authoring) version of ToolBook,
 call Asymetrix Product Support at 206-637-1600. For the name of a software
 dealer in your area where you can purchase the full (authoring) version of
 ToolBook, call 1-800-624-8999 ext. 299A.


 What information should I have ready when I call Microsoft product support?


 Your Microsoft support representative will be able to answer your question
 or solve your problem more efficiently if you find out as much as you can
 about your computer before you call. The Microsoft representative will need
 to know about both your system's hardware and software.

 NOTE

 At the back of the Microsoft Windows User's Guide is a form you can fill out
 before calling Microsoft Product Support Services. However, since that form
 is common to all Microsoft products, you should also complete the following
 steps to collect Windows-specific information.



 Collecting Information About Your System's Hardware


 When reporting a problem, it is important for you to be able to tell your
 Microsoft support representative what type of hardware your system has. If
 possible, before calling Microsoft, write down the following information
 about your system's hardware:

 Your computer's manufacturer, model name, and model number.

 Most computers bear a nameplate with this information. Or look in the manual
 that accompanied your computer.

 The type and amount of memory your computer has.

 If some of the memory exists on an add-on memory board, also note the
 manufacturer and model of the memory board.

 If you have MS-DOS version 4.0 or later, you can find out about your
 computer's memory configuration by typing mem at the MS-DOS prompt. You
 might want to print a copy of the resulting information by pressing
 ALT+PRINT SCREEN.

 The manufacturer, model name, and resolution of your video display.

 The manufacturer and model name of your mouse, if you have one.

 How many hard disks your computer has, and how much space is available on
 each disk.

 To find out the available space on a hard disk, click its drive icon in File
 Manager. File Manager then displays the available space in the lower-left
 corner of the window. Or type chkdsk at the MS-DOS prompt.

 If possible, you should also note the manufacturer and model name of each
 disk drive.

 The manufacturer and model name of your printer, if you have one.

 The manufacturer and model name of any other hardware your computer has (for
 example, a CD-ROM drive, a hand-held scanner, or a modem).


 Collecting Information About Your System's Software


 It is also important for you to be able to tell your Microsoft support
 representative what type of software your system has. Before calling
 Microsoft, you should write down the following information about your
 system's software:

 The manufacturer and version of MS-DOS you are using (for example, MS-DOS
 for COMPAQ version 3.31)

 Information about any memory-resident software, including
 terminate-and-stay-resident (TSR) programs and device drivers you are using.
 The following procedure
 explains how to get this information.

 Information about your Windows configuration, including the version number
 and the mode in which you are currently running Windows. The following
 procedure explains how to get this information.

 There are several ways to collect information about your system's software.
 The easiest way is to use some of the facilities that Windows offers.
 However, if you cannot run Windows, you will need to use MS-DOS methods
 instead.



 To get information about your system's software using Windows:


 Start Windows as you did when you encountered the problem you are
 reporting.

 For example, if you encountered the problem after you started Windows by
 typing win /r, you would type win /r.

 Choose About Program Manager from the Help menu in Program Manager. Windows
 displays the About dialog box, which contains information about your Windows
 configuration. Write down the information contained in the About dialog box.

 Start Windows Setup by double-clicking the Windows Setup icon in the Main
 Group of Program Manager. Write down the information contained in the
 Windows Setup window and then close Setup.

 Choose Run from the File menu in Program Manager.

 Type sysedit and choose OK.

 The System Configuration Editor (Sysedit) window appears. Sysedit is a
 special version of Notepad that lets you edit and print four files that
 affect the way Windows starts and runs. Sysedit contains four document
 windows, one for each file.

 Choose Print from the File menu to print the first file.

 Click the next document window to bring it to the foreground.

 Choose Print again.

 Repeat steps 7 and 8 until you have printed the contents of all four files.

 If you cannot run Windows, you will need to get software information by
 using MS-DOS methods. The following procedure explains how to do this.



 To get information about your system's software if you can't run Windows:


 Change to the hard disk drive from which your system starts. On most
 systems, this is drive C. To change to drive C, type c: and press ENTER.

 Type cd\ to change to the root directory of your hard disk drive.

 Print the contents of your CONFIG.SYS file by typing a command such as the
 following (replace "LPT1:" with the name of your printer port):

 > Lpt1:

 If you don't have a printer, type the following command and write down the
 contents of the file as displayed on your screen:

 type config.sys

 Print the contents of your AUTOEXEC.BAT file by typing a command such as the
 following (replace "LPT1:" with the name of your printer port):

 > Lpt1:

 If you don't have a printer, type the following command and write down the
 contents of the file as displayed on your screen:

 type autoexec.bat

 Change to your Windows directory by using the CD command. For example, if
 Windows is installed in the \WINDOWS directory, you would type cd \WINDOWS
 to change to this directory.

 Print the contents of your WIN.INI file by typing a command such as the
 following (replace "LPT1:" with the name of your printer port):

 > Lpt1:

 If you don't have a printer, type the following command and write down the
 contents of the file as displayed on the screen:

 type win.ini

 Print the contents of your SYSTEM.INI file by typing a command such as the
 following (replace "LPT1:" with the name of your printer port):

 > Lpt1:

 If you don't have a printer, type the following command and write down the
 contents of the file as displayed on your screen:

 type system.ini

 Once you have gathered information about your system's hardware and
 software, call Microsoft Product Support Services. Product support
 representatives are available Monday through Friday, from 5 A.M. to 7 P.M.
 Pacific Standard Time.




 Information in this document is subject to change without notice and
 does not represent a commitment on the part of Microsoft Corporation.
 The software described in this document is furnished under a license
 agreement or nondisclosure agreement. The software may be used or
 copied only in accordance with the terms of the agreement. It is against
 the law to copy the software on any medium except as specifically
 allowed in the license or nondisclosure agreement. No part of this
 manual may be reproduced or transmitted in any form or by any means,
 electronic or mechanical, including photocopying and recording, for
 any purpose without the express written permission of Microsoft.

 RESTRICTED RIGHTS: Use, duplication, or disclosure by the U.S. Government
 is subject to restrictions as set forth in subparagraph (c)(i)(ii)
 of the Rights in Technical Data and Computer Software clause at DFARS
 252.227-7013 or subparagraphs (c)(1) and (2) of Commercial Computer
 Software--Restricted Rights at 48 CFR 52.227-19, as
 applicable. Contractor/Manufacturer is Microsoft Corporation, One
 Microsoft Way,
 Redmond, Washington 98052-6399.

 (C)Copyright Microsoft Corporation, 1985-1990.
 All rights reserved.
 Printed and bound in the United States of America.

 Microsoft, MS, MS-DOS, and the Microsoft logo are
 registered trademarks, and Making it all make sense and Windows
 are trademarks of Microsoft Corporation.

 Acer is a registered trademark of Acer Technologies Corporation.

 AT&T is a registered trademark of American Telephone and Telegraph
 Company.

 Reflex is a registered trademark of Borland International, Inc.

 COMPAQ is a registered trademark of Compaq Computer Corporation.

 CompuServe is a registered trademark of CompuServe, Inc.

 Corel is a trademark of Corel Systems Corporation.

 DayBook is a trademark, and ToolBook is a registered trademark, of
 Asymetrix Corporation.

 Epson is a registered trademark of Epson America, Inc.

 GEnie is a trademark of General Electric Corporation.

 HP and Vectra are registered trademarks of Hewlett-Packard Company.

 IBM, PS/2, and AT are registered trademarks of International Business
 Machines Corporation.

 Logitech is a trademark of Logitech, Inc.

 Novell is a registered trademark of Novell, Inc.

 POSTSCRIPT is a registered trademark of Adobe Systems, Inc.

 Toshiba is a registered trademark of Kabushiki Kaisha Toshiba.

 Wyse is a registered trademark of Wyse Technology.







 OBJECT LINKING and EMBEDDING SPECIFICATION



 January 1991 Beta Version


 Extensible Application Protocols
 Object Linking and Embedding


 Microsoft Corporation
 One Microsoft Way
 Redmond WA, 98052

 (C) Copyright Microsoft Corporation 1990, 1991. All rights reserved





 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

 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 actions 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 imposed 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"

 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 contained 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 legal. This is the crucial difference between containment and our
 current implementations of pasting operations: 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
 Form of Transfer  Source    Destination
 ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
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 icon-like picture perhaps 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
 Other than section 2.1, all of section 2 is new in this version of the
 document.
 The Object Linking and Embedding interface provides easy methods for
 inserting linked and embedded objects, viewing the objects, editing them,
 and changing their properties.   Each of these methods will be discussed in
 turn.
 The user interface described here is not mandatory.  This document specifies
 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 invoked.

 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 ItemName 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.


 Inserting Objects
 The basic user interface for inserting links and embedded objects relies on
 the familiar Cut, Copy, and Paste commands on the Edit menu, plus one
 additional command, Paste Link, for inserting links.  To accelerate linking
 and embedding or provide additional control over data formats, applications
 may also implement optional commands such as Paste Special and Insert New
 Object.  The following sections discuss the standard insertion procedures
 first, followed by the optional commands.

 Inserting Embedded Objects:  Cut/Copy from Source, Paste into Destination
 The basic procedure for inserting embedded objects is simple.  For example,
 to insert a drawing into a text document, the following steps would be
 required:
   ž   In the editor application for the drawing, select the drawing and
       choose the Copy command from the Edit menu.
   ž   In the text application,  choose the Paste command from the Edit menu.

   ž   This procedure inserts the drawing at the current location of the
       cursor in the text document.
   ž   In general, for applications that support OLE, the
       Paste command will embed the object that is on the Clipboard, as in
       the example just described.  Under some circumstances, however, the
       application may choose not to embed the object.  In particular,
       suppose that the object is represented on the Clipboard not only by
       the embedded object format but also by an alternate format that
       completely represents the original data and that the application knows
       how to edit.  In this case, the application may choose to insert this
       editable alternate data rather than embedding the object.  Most
       applications, however, will not be able to provide full editing
       capabilities for any alternate format, so they will simply embed the
       object and allow the source application to provide editing
       tools.
   ž   Thus in most applications that support OLE, when the Clipboard
       contains an object from another application, the Paste command will
       embed the object in the current document.  Note that in applications
       that do not support OLE, this Paste command would simply insert a
       static copy of the data, without providing easy access to the tools
       required for later editing of the data.  The easy editing provided by
       embedded objects will be discussed further below.


 Inserting Links:  Copy from Source, Paste Link into Destination
 Inserting links to objects is just as easy as embedding objects.  To
 continue the previous example, suppose that instead of embedding the
 drawing, the user wanted to insert a link to the drawing.  The following
 steps would be required:
   ž   In the editor application for the drawing, select the drawing and
       choose the Copy command from the Edit menu.  (This step is exactly the
       same as in the procedure for inserting an embedded object.)
   ž   In the text application,  choose the Paste Link command from the Edit
       menu.

   ž   This procedure inserts a link to the drawing at the current location
       of the cursor in the text document.  The drawing is displayed in the
       text document but stored in the original drawing file.  The link is an
       "automatic" link; in other words, whenever the drawing file is
       changed, the drawing in the text file is updated automatically.
       Automatic and manual links are described more fully in the discussion
       of the Link Properties dialog.
   ž   Once a link exists in one document, it can be inserted in other
       documents via Copy and Paste (not Paste Link).  For example, suppose
       that Document1 contains Link1, which refers to a bitmap in a graphics
       file.  If Link1 is selected, the Copy command copies Link1, not the
       bitmap that is the source object.  The Paste command then inserts a
       copy of Link1 (which we can call CopyOfLink1) at the current cursor
       location.  Like Link1, CopyOfLink1 refers to the original bitmap.  If
       Paste Link is used instead of Paste, a  link to (not a copy of) Link1
       is inserted.  This new link ("LinkToLink1") refers to Link1, which in
       turn refers to the original bitmap.  Link1, CopyOfLink1, and
       LinkToLink1 all yield exactly the same visual presentation (a
       representation of the original bitmap) in their client documents, but
       Link1 and CopyOfLink1 refer directly to the bitmap, whereas
       LinkToLink1 refers to the bitmap only indirectly, via Link1.
   ž
   ž   Just as links can be copied from one location to another via Copy and
       Paste, they can also be moved via Cut and Paste.  In this respect
       links behave like any other objects that can be manipulated via the
       Clipboard.


 Optional Methods for Inserting Links and Embedded Objects
 For inserting links and embedded objects, many applications will need
 nothing more than the simple methods discussed in the preceding sections.
 Some applications, however, may want to provide extra control or convenience
 via the Paste Special and Insert New Object commands.

 Controlling Data Formats:  "Paste Special..." Command
 Some applications can interpret and edit data in a wide variety of
 formats-not only the format native to the application, but also one or more
 other ones, such as Rich Text Format (RTF), ASCII text, bitmaps, and
 object-oriented picture formats.  Such applications may wish to provide a
 "Paste Special..." command on the Edit menu, to provide more control over
 which format is used when data is pasted in from another application.
 By default, the standard Paste and Paste Link commands look on the Clipboard
 for a format that completely represents the original data and that the
 client application can edit with its own tools.  If such a format is found,
 the original data is translated into that format and inserted into the
 client.  In some cases, however, the user may want to override the default
 format.  For example, certain special tools or editing operations (e.g.
 rotation) might only be available for a non-default format (e.g. drawings in
 a text application).  Alternatively, the user might want to force the data
 to be inserted as an embedded object (rather than translated into a
 client-editable format), so that the tools of the original creator
 application (called the "server" application) could easily be invoked to
 edit the object.  These choices between formats are supported by the Paste
 Special dialog.

 The Data Type list in the Paste Special dialog shows the formats available
 on the Clipboard.  The list also includes one additional entry, "<Object>
 Object" (e.g. "Excel Worksheet Object") that will be discussed further
 below.
   ž   The Paste button translates the data into the selected format and
       inserts it into the document, without establishing a link to the
       original source of the data.  (If the user has not changed the default
       format, i.e. the one originally selected in the list, then pressing
       Paste in this dialog is equivalent to choosing Paste from the Edit
       menu.)  If the user has selected "<Object> Object" rather than a data
       format, the data is inserted as an embedded object rather than
       translated into a client-editable format.
   ž   Like the Paste button, the Paste Link button translates the data into
       the selected format and inserts it into the document.  Unlike the
       Paste button, however, Paste Link establishes an automatic link to the
       original source of the data.  (If the user has not changed the default
       format, i.e. the one originally selected in the list, then pressing
       Paste Link in this dialog is equivalent to choosing Paste Link from
       the Edit menu.)

   ž   The Paste Special dialog provides a superset of the functionality
       provided by the Paste Link command, and thus it is not strictly
       necessary for applications that include Paste Special to also provide
       Paste Link.  Nonetheless, it is strongly recommended that the Paste
       Link command be retained even when Paste Special is provided, because
       Paste Link is a more convenient and less complicated means of
       establishing links.


 Embedding Blank Objects:  "Insert New Object..." Command
 To accelerate the procedure for embedding blank objects, applications may
 implement an "Insert New Object..." command.  In applications that include
 an Insert menu, the command should appear on that menu and should be called
 "New Object...".  In applications that do not include an Insert menu, the
 command should appear on the Edit menu and should be called "Insert New
 Object...".

 The Object Type list in the Insert New Object dialog contains object names
 drawn from the registration database maintained by the system.  To embed an
 object, the user selects its name from the list and presses OK.  This
 activates the server application for the selected object; the server
 displays a blank window, in which the user can create and edit the object.
 After the editing is complete, the user selects the Update command from the
 File menu of the server.  This command closes the server and inserts the
 object in the client, at the location where the cursor was positioned when
 the Insert New dialog was invoked.  (For additional details on the File
 Update command and other aspects of editing and saving objects, see below.)

 Viewing Objects
 Complex compound documents may contain several linked or embedded objects
 (OLE objects), interspersed with objects that are native to the document.
 Because the OLE objects support operations different from those supported by
 the native objects, it is convenient to be able to visually distinguish the
 OLE objects from the native ones.  For this purpose, applications should
 provide visual indications of OLE object boundaries.  The boundaries for a
 particular object should appear whenever the object is selected.  In
 addition, applications should also provide a way for all object boundaries
 to be turned on or off at once, to facilitate easy viewing of all OLE
 objects in a document.  For example, applications could reveal object
 boundaries, as well as other normally hidden information, via a "Hidden
 Structure" command on the View menu or a "Show All" checkbox in a
 Preferences dialog.
 The exact method of indicating object boundaries depends on the nature of
 the client application and the type of linked or embedded object.  Three
 possible methods are:
   ž   Complete borders surrounding the object.  For PC VGA monitors, the
       border should be dark grey; for non-VGA PC monitors, the border should
       be a 50% grey pattern; and for Macintoshes, the border should consist
       of a one-pixel-wide white line sandwiched between two 50% grey lines.
   ž   Special graphic characters (e.g. "[" and "]" ) at the beginning and
       end of the object.
   ž   Distinctive formatting (e.g. a dotted underline) that is not used
       elsewhere in the client.

   ž   Whichever method is used, the goal is to provide a clear indication of
       the extent of the linked or embedded object.


 Editing Objects
 Once linked or embedded objects have been inserted into a document, the
 standard user interface provides two methods for editing them.  The first
 method is very simple:  Double-clicking on the object boundary invokes the
 server application (i.e. the original creator application) that is
 associated with the object.  (If the object is atomic-that is, if only the
 whole object can be selected in the client-then the user can double-click
 anywhere on the object to invoke the server.)  The second method for editing
 linked or embedded objects relies on the  "<Object> Properties" command on
 the Edit menu of the client.  This command is discussed further in the next
 section.
 When the server window opens, the object is loaded into the window.  For
 embedded objects, the window is initially sized to show only the portion of
 the object that was displayed in the client.  (Some embedded objects, such
 as spreadsheets, may include portions that are not displayed.  These hidden
 portions are included because the displayed portion draws data from them.)
 The user can resize the window to display additional portions of the
 embedded object.  In the case of linked objects, the entire linked file is
 loaded, and the linked portion is selected.
 The user can modify the object with the editing tools provided by the
 server.  The process for updating the object in the client file varies
 slightly depending on whether the server supports the Multiple Document
 Interface (MDI).

 Updating Objects from Non-MDI Servers
 When a non-MDI application functions as a server, the Save command on the
 File menu changes to Update.   After the user is finished editing the
 object, this command can be used to close the server, update the object in
 the client, and reactivate the client window.  Updates to embedded objects
 can be undone via the Undo command on the Edit menu of the client.  If the
 user tries to exit the server without updating the object, a warning message
 is displayed.

 When an embedded object is being edited, the File Save As command can be
 used to save a copy of the object in a separate file.  If the client file
 has not yet been updated, a warning message is displayed before the standard
 Save As dialog appears.  The same warning is displayed if the File New
 command is chosen.  In all other respects, the Save As and New commands
 behave just as they would if the application were not functioning as a
 server.
 When the server closes, the focus returns to the client.
 If the user attempts to close the client while servers for that client are
 still open, the servers are closed first, after the usual checks for unsaved
 data.

 Updating Objects from MDI Servers
 The procedure for editing and updating objects from MDI servers is similar
 to the procedure for non-MDI servers, with the following exceptions.
   ž   If the focus changes from the embedded object window to a "normal"
       document window (i.e. one containing an existing file or a new
       document), the File Update command changes back to File Save.  If the
       embedded object window regains the focus, File Save becomes File
       Update again.
   ž   When the File Save As or File New command is chosen, the window
       containing the embedded object remains open.  Therefore it is not
       necessary to display the "Update <client file name>?" message if the
       client file has not yet been updated.
   ž   If the embedded object window is not the only open document window in
       the server, then the File Update command only closes the embedded
       object window.  The other document windows, and the server application
       window itself, remain open, and the server retains the focus.


 Changing Object Properties
 The properties of linked and embedded objects may be changed via the
 "<Object> Properties" command.  This command appears on the Edit menu of the
 client; it may also be invoked via Alt+Double-Click on the boundary of an
 object.  (If the object is atomic-that is, if only the whole object can be
 selected in the client-then Alt+Double-Click may be used anywhere on the
 object to invoke the "<Object> Properties dialog.)  Depending on what kind
 of objects are included in the current selection in the client, the
 "<Object> Properties" command may modify its name and invoke different
 dialogs.

 If no links or embedded objects are included in the selection, the command
 name is "Object Properties" and is greyed to indicate that the command
 cannot be chosen.  If links are included in the selection, the command
 changes to "Link Properties..." and leads to a dialog (see below for
 details).  If the selection includes no links but includes one or more
 embedded objects, the command leads to the "<Object> Properties" dialog.  In
 this case, if the objects are of different types, the command name is simply
 "Object Properties..." (and the dialog title is "Object Properties", without
 the ellipsis).  If the objects are all of the same type, the first part of
 the name indicates that type.  For example, if the objects are all Excel
 worksheets, the command name is "Excel Worksheet Properties..." (and the
 dialog title is "Excel Worksheet Properties").

 <Object>Properties Dialog
 The text at the top of the dialog shows the number of embedded objects that
 are selected in the document.  If all the objects are of the same type, the
 text mentions the type as well as the number of objects:  "<Number>
 <ObjectType> selected" (e.g. "3 Microsoft Excel Worksheets selected").  If
 the objects are of different types, the text omits the object type and
 simply refers to the objects as "embedded objects":  "<Number> embedded
 objects selected".
 The buttons operate as follows:
   ž   The Open button opens the object for editing; in other words, the
       server application for the object is started, and the object is loaded
       into the application.
   ž   The Change to Picture button changes the object to a picture that can
       no longer be edited via the standard OLE techniques.  It is still
       possible to edit the graphic aspects of the picture via the older,
       more cumbersome cut/copy/paste techniques.  For example, the user
       could cut the picture out of the client, paste it into a graphics
       application, modify the picture, cut it out of the graphics
       application, and paste it back into the original client.  However, it
       is unlikely that the picture contains all of the information in the
       original object (unless the original object was itself a picture).
       For example, a picture of a spreadsheet object retains no information
       about the underlying formulas.  Thus the Change to Picture operation
       usually causes an irreversible loss of data.
   ž   After an object is changed to a picture, no object boundaries are
       displayed for the picture.

   ž   An embedded object may contain a link, but the <Object> Properties
       dialog provides no direct access to the link properties.  To access
       those properties, the user must first invoke the editor for the object
       and then choose the Link Properties command in the editor.


 Link Properties Dialog
 The Link Properties dialog allows users to open linked files for editing,
 change the type of updating (automatic or manual) for links, update linked
 objects, cancel links, and repair broken links.

 When the Link Properties dialog first opens, the Links list shows each link
 contained in the current selection in the document; each link item in the
 list is initially selected.  The listbox is an extended-selection listbox,
 which allows the user to select one or several links by using Shift-Click
 for range selection and Control-Click for discontiguous selection, just as
 in the Windows File Manager.
 Below the listbox, the dialog contains two "Update" radio buttons:
 "Automatic" and "Manual".  When the dialog opens, these buttons reflect
 whether the currently selected links are automatically updated whenever the
 linked file changes or whether they must be manually updated.  The update
 rule for the selected links can be changed via the radio buttons.  If links
 with different update rules are selected in the list, neither the
 "Automatic" or "Manual" radio button is selected.  In this case, pressing
 one of the buttons changes all the selected links to have the corresponding
 update property.
 The push buttons at the bottom of the dialog carry out the following
 operations:
   ž   "Open Source" opens the linked file for the link selected in the Links
       list; in other words, the server application for the linked file is
       started, and the linked file is loaded into the server.  Pressing this
       button is equivalent to double-clicking on the link boundary in the
       client.  If the selection in the Links list includes multiple links
       that are not all linked to the same file, each linked file is opened.
   ž   "Update Now" updates all links selected in the Links list.  In other
       words, the presentations of the linked objects in the client are
       updated to reflect the current data in the linked files.  Suppose that
       the selected links are all associated with a file called "source.doc".
       It is possible that the client contains other, currently unselected
       links associated with the same file.  In this case, after the selected
       links are updated, a message box is displayed.  If the originally
       selected links were associated with several files, and if the document
       contains other unselected links to those files, the message box will
       be displayed once for each of the files.
   ž   "Cancel Link" permanently breaks the link between the client and the
       server.  The linked object in the client is changed to a picture that
       can no longer be updated or edited via the standard OLE techniques.
       As described for the "Change to Picture" operation in the <Object>
       Properties dialog, the picture can still be edited via the older
       cut/copy/paste techniques, but it is unlikely that the picture retains
       all the data present in the original linked object.   No link
       boundaries are displayed for the picture.
   ž   The "Change Link..." button is greyed if the selection in the Links
       list includes multiple links that are not all linked to the same file.
       Otherwise, if all the selected links are linked to the same file, the
       button is active and leads to a dialog exactly like the File Open
       dialog, except that the title is "Change Link"; the standard File Open
       dialog is described in the Appendix).
   ž   The Change Link dialog allows the user to change the file to which a
       link refers.  This capability has two uses.  First, it allows broken
       links to be reestablished.  For example, suppose that a linked file is
       renamed or moved to a new location.  The dialog allows the user to
       reconnect the link in the client to the linked file under its new name
       or in its new location.  Second, the dialog allows a single client
       that operates on linked data files to be successively connected to
       different sets of linked files.  This flexibility in providing data to
       the client is particularly useful for applications such as
       spreadsheets and databases.
   ž   When the user chooses a file and presses OK in the Change Links
       dialog, the links that were selected in the Links list are
       disconnected from their previous file and connected to the newly
       chosen file.  It is possible that the previous file was also
       associated with other, currently unselected links in the client.  In
       this case, after the selected links are changed, a message box is
       displayed.  This message is analogous to the one described above for
       the Update Now button.

   ž   In addition to the standard controls, the Link Properties dialog may
       also include a dropdown list for changing the format (e.g. Text or
       Picture) in which the object is displayed.  If present, this dropdown
       list should be placed at the bottom of the dialog, just above the push
       buttons.


 Other Dialogs for Link Updating
 When a file containing manual links is opened, a message box is displayed to
 ask the user whether to update the links.

 If the user presses the Yes button in the message box, the application
 updates the links.  The progress indicator is displayed while the links are
 being updated.  The Stop button interrupts the update without cancelling any
 updating that has already been carried out.  If the client can support a
 complete cancellation of all updates, the message box should contain a
 Cancel button instead of the Stop button.

 If some of the linked files were unavailable, a warning dialog is displayed.
 This dialog contains two buttons, OK and Link Properties....  The OK button
 closes the dialog without updating the links.  The Link Properties... button
 selects the entire document and displays the Link Properties dialog.  The
 whole document is selected so that all links in the document appear in the
 Links list in the Link Properties dialog.  Unavailable linked files are
 marked with the word "Unavailable" in the third column of the list.  The
 user can attempt to locate the unavailable files by using the Change Links
 dialog, which is available via the Change Links... button in the Link
 Properties dialog.





 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 ConventionsA 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 list shows the results of these rules in various
 representative scenarios.

  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


  Pictorial data
 Worksheet: embed
 Structured document: embed
 Picture frame: embed
 Rich text frame: embed
 Presentation graphics: embed
 Draw program: embed

  Structured data
 Worksheet: convert
 Structured document: convert
 Picture frame: embed
 Rich text frame: convert
 Presentation graphics: embed
 Draw program: embed

  Structured document
 Worksheet: convert
 Structured document: convert
 Picture frame: embed
 Rich text frame: convert
 Presentation graphics: embed
 Draw program: embed

  Compound document link
 Worksheet:link to owner
 Structured document: link to owner
 Picture frame: link to owner
 Rich text frame: link to owner
 Presentation graphics: link to owner
 Draw program: link to owner

  Embedded object
 Worksheet: embed owner
 Structured document: embed owner
 Picture frame: embed owner
 Rich text frame: embed owner
 Presentation graphics: embed owner
 Draw program: 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 application 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 involve additional
 function in applications. Others involve an extra action by the user to
 achieve the intended 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", ... ) == ECD_OK ) ...

 Open a Document
 When a client opens a document that contains a link or an embedded object,
 it should register the document (with EcdRegisterClientDoc) and 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.
     EcdRegisterClientDoc( ... )
     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 terminate until the library notifies the client that
 the operation is complete.  The client should notify the library whether the
 document was saved or changes were discarder, and should call
 EcdReleaseClientDoc to indicate that the document is no longer open.
 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
         EcdSavedClientDoc( ... )
     break;

 case CLOSE:
         for each object
             if( EcdRelease(lpobj ) == ECD_BUSY)
                 add to list of objects in process of closing
         while busy objects remain
             dispatch messages
         if( close without save )
             EcdRevertClientDoc( ... )
         EcdReleaseClientDoc( ... )


 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 OwnerLink 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", ...)
         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", ...) == 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 "<Type> 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 preference 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.
 Ecdrelease 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 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, or if the server is a single instance
 application.  The latter case is handled by the startup negotiation
 described in the appendix. The intent is that separate instances of
 applications should normally be used to avoid interfering with the
 application's context information (e.g. current window, current selection
 etc).

 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 As
 The normal "Save As..." command has the additional effect of changing the
 association of the in-memory document to be the new file, , so the
 connection to the client should be broken (after optionally updating the
 client's version of the 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 and changes have been
 made but not updated to the client, it should query the user whether to
 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_WAIT_FOR_RELEASE,    // client must wait for release callback before
 quitting or calling
                 // another method on the object.
 ECD_BUSY,        // attempt to execute a method while another method
                                 // is being executed in the background.
 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_ERROR_ADDRESS,      // one of the pointers is invalid
 ECD_ERROR_NOT_EQUAL,    // objects are not equal
 ECD_ERROR_HANDLE,       // invalid handle encountered
 ECD_ERROR_GENERIC,
 ECD_ERROR_MAPPING_MODE, // This is temporary: picture has a mapping mode
 that
                 // cannot be handled. Remove it when you figure
                                        // out how to convert to
                                        MM_ANISOTROPIC
 ECD_ERROR_INVALIDCLASS, // Invalid class
 ECD_ERROR_SYNTAX,       // command syntax error
 ECD_ERROR_PROTECT_ONLY, // attempt to call create APIsfrom real mode
 ECD_ERROR_NOT_OPEN,     // object is not open for editing
 ECD_ERROR_POKENATIVE,   // failure of poking native data to server
 ECD_ERROR_ADVISE_PICT,  // failure of advise for picture data
 ECD_ERROR_DATATYPE,     // data format is not supported
 ECD_ERROR_ALREADY_BLOCKED // trying to block a blocked server
 } 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_CHANGED,
 ECD_SAVED,
 ECD_CLOSED,
 ECD_RENAMED,
 ECD_QUERY_PAINT,        // interruptible paint support
 ECD_RELEASE,            // object is released (asynchronous operation is
                             // is finished)
 ECD_QUERY_RETRY         // retry query for the busy from the server.
 } 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 );
 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 an asynchronous
 operation on the object has finally terminated either correctly or with an
 error.  The client should call EcdQueryReleaseError to determine whether the
 operation succeeded, and optionall can call EcdQueryReleaseMethod to find
 out the operation that has terminated (in case the client has forgotten).
 ECD_QUERY_RETRY:  the server has responded to a request indicating that it
 is busy.  This notification asks the client if the library should continue
 trying the request.  If the callback function returns false, the transaction
 with the server will be aborted.


 return value
 BOOL
 this value is ignored except in the case of ECD_QUERY_PAINT and
 ECD_QUERY_RETRY.   The client should return false (zero) if the painting or
 server transaction should be aborted, and true (non-zero) if  the library
 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).  In these cases the library will return ECD_WAIT_FOR_RELEASE
 when the function is first initiated, will notify the client of completion
 or error, and will return ECD_BUSY if the client attempts to invoke a
 conflicting operation while the previous one is in progress.  The client can
 determine if an asynchronous operation is in progress by calling
 EcdQueryReleaseStatus, which returns ECD_BUSY if the operation has not yet
 completed.

 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 );
 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 );
 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 );
 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.

 Client Document Management Functions
 In order to enable proper link tracking in future implementations of the
 libraries, the library needs to keep track of client documents where obejcts
 are being created and destroyed.  For these purposes the client must
 register its open document(s) with the library and obtain a (long) handle
 for use in object-creation functions.  The client must also notify the
 library when renaming, closing, saving, or reverting to saved state has been
 performed.  The first function below registers an open document with the
 library, and the following four functions notify the library of
 document-level actions that the client has performed.
 In addition, the client must maintain a persistent name for each object that
 is unique within the scope of the client document.  This name must be
 specified when the object is created.  It must be stored in the client
 document and must remain the same when the saved and reopened later.

 EcdRegisterClientDoc
 LHCLIENTDOC FAR PASCAL EcdRegisterClientDoc (classname, documentname,
 reserved);
 classname
 LPSTR
 string name of the class of the client document

 documentname
 LPSTR
 string name of the client document, typically a fully qualified pathname

 reserved
 LONG
 reserved for future use, must be 0L.

 return value
 LHCLIENTDOC
 a long handle to be used to identify the client document in object creation
 calls and the following document management calls.

 EcdReleaseClientDoc
 ECDSTATUS   FAR PASCAL EcdReleaseClientDoc (lhclientdoc);
 lhclientdoc
 LHCLIENTDOC
 handle to the document which is no longer open.

 EcdRenameClientDoc
 ECDSTATUS   FAR PASCAL EcdRenameClientDoc (lhclientdoc, newdocname);
 lhclientdoc
 LHCLIENTDOC
 handle to the document which has been renamed (eg with Save As)

 newdocname
 LPSTR
 the new string name of the document.

 EcdRevertClientDoc
 ECDSTATUS   FAR PASCAL EcdRevertClientDoc (LHCLIENTDOC);
 lhclientdoc
 LHCLIENTDOC
 handle to the document which has reverted to saved state

 EcdSavedClientDoc
 ECDSTATUS   FAR PASCAL EcdSavedClientDoc (LHCLIENTDOC);
 lhclientdoc
 LHCLIENTDOC
 handle to the document which has been saved

 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
 );
 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, lhclientdoc,
 lpobjname, lplpobject , renderopt, cfFormat);
 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.

  lhclientdoc
 LHCLIENTDOC
 long handle to client document where object is being created

 lpobjname
 LPSTR
 the client's name for the object.

 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, lhclientdoc,
 lpobjname, lplpobject , 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 );
  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 );
 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,
 lhclientdoc, lpobjname, lplpobject );
 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

 lhclientdoc
 LHCLIENTDOC
 long handle to client document where object is being created

 lpobjname
 LPSTR
 the client's name for the object.

 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 );
 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, lhclientdoc,
 lpobjname, lplpobject ,renderopt, cfFormat );
 This function creates an object of a specified class.  The server is opened
 to perform the initial editing.

 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.

 lhclientdoc
 LHCLIENTDOC
 long handle to client document where object is being created

 lpobjname
 LPSTR
 the client's name for the 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

 EcdCreateFromTemplate
 ECDSTATUS FAR PASCAL EcdCreateFromTemplate( protocol, lpclient,
 objectname, lhclientdoc, lpobjname, 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.

 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

 lhclientdoc
 LHCLIENTDOC
 long handle to client document where object is being created

 lpobjname
 LPSTR
 the client's name for the 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


 EcdCreateFromFile
 ECDSTATUS   FAR PASCAL  EcdCreateFromFile (lpprotocol, lpclient, lpfilename,
 lhclientdoc, lpobjname, lplpobject, optrender, cfFormat);
 EcdCreateFromFile creates an embedded object from the contents of a named
 file.  The server will be activated to render the native data and picture,
 and then closed down.  The server will not show the object to the user for
 editing.


 EcdCreateLinkFromFile
 ECDSTATUS   FAR PASCAL  EcdCreateLinkFromFile ( lpprotocol, lpclient,
 lpfile, lpitem, lhclientdoc, lpobjname, lplpecdobject, optRender, cfFormat);
 Analogous to EcdCreateFromFile, this function creates a link to an object in
 a file.  The server will be activated if necessary to render the
 presentation data, but will not be shown to the user for editing.

 lpprotocol
 LPSTR
 as above

 lpclient
 LPECDCLIENT
 as above

 lpfile
 LPSTR
 as above

 lpitem
 LPSTR
 the string name of the item which identifies the part of the server document
 to be linked.  This may be a null string in which case the link is to the
 whole of the document.

 lhclientdoc
 LHCLIENTDOC
 as above

 lpobjname
 LPSTR
 as above

 lplpecdobject
 LPECDOBJECT FAR *
 as above

 optRender
 ECDOPT_RENDER
 as above

 cfFormat
 ECDCLIPFORMAT
 as above


 Creating an object by converting an existing object


 EcdObjectConvert
 ECDSTATUS FAR PASCAL EcdObjectConvert( lpobject, protocol, lpclient,
 lhclientdoc, lpobjname, 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.

 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

 lhclientdoc
 LHCLIENTDOC
 long handle to client document where object is being created

 lpobjname
 LPSTR
 the client's name for the 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, lhclientdoc, lpobjname,
 lplpobject );
 This function makes a duplicate copy of an object.  A new client context may
 be supplied.

 lpobject
 LPECDOBJECT
 a long pointer to the object to be copied

 lpclient
 LPECDCLIENT
 a long pointer to the client structure for the new object

 lhclientdoc
 LHCLIENTDOC
 long handle to client document where object is being created

 lpobjname
 LPSTR
 the client's name for the 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.

 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,
 lhclientdoc, lpobjname,  lplpobject );
 This function makes a local embedded copy of a linked object. This may
 involve launching the server application.

 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

 lhclientdoc
 LHCLIENTDOC
 long handle to client document where object is being created

 lpobjname
 LPSTR
 the client's name for the object.

 lplpobject
 LPECDOBJECT FAR *
 as lplpobject earlier

 return value
 ECDSTATUS
 see ECDSTATUS type definition.


 Object method functions


 Asynchronous operations
 typedef enum {
     ECD_NONE,               // no method active
     ECD_DELETE,             // object delete
     ECD_COPYFROMLNK,        // CopyFromLink (auto reconnect)
     ECD_LOADFROMSTREAM,     // LoadFromStream (auto reconnect)
     ECD_LNKPASTE,           // PasteLink (auto reconnect)
     ECD_SHOW,               // Show
     ECD_OPEN,               // Open
     ECD_UPDATE,             // Update
     ECD_CLOSE,              // Close
     ECD_RECONNECT,          // Reconnect
     ECD_CREATEFROMTEMPLATE, // CreatefromTemplate
     ECD_CREATE,             // create
     ECD_SETUPDATEOPTIONS,   // setting update options
     ECD_SRVRUNLAUNCH        // server is being unluanched
 }ECD_RELEASE_METHOD;

 EcdQueryReleaseStatus
 ECDSTATUS   FAR PASCAL LeQueryReleaseStatus (lpobj)

 lpobj
 LPECDOBJECT
 long pointer to the object whose status is to be queried

 return value
 ECDSTATUS
 ECD_BUSY if an operation is in progress otherwise ECD_OK


 EcdQueryReleaseError
 ECDSTATUS   FAR PASCAL LeQueryReleaseError (lpobj)

 Name
 Typelpobj
 LPECDOBJECT
 long pointer to the object whose status is to be queried

 return value
 ECDSTATUS
 an indication of the error that occurred, ECD_OK if completion was
 successful.


 EcdQueryReleaseMethod
 ECD_RELEASE_METHOD   FAR PASCAL LeQueryReleaseMethod (lpobj)

 lpobj
 LPECDOBJECT
 long pointer to the object whose status is to be queried

 return value
 ECD_RELEASE_METHOD
 an enum value indicating the method that completed.  See above.


 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.

 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 an object and reclaim storage.  Closes the object if it is open.
 This call indicates that the object is no longer part of the client
 document.


 EcdRelease
 ECDSTATUS FAR PASCAL EcdRelease(lpobject);
 This call has the same parameters and return type as EcdDelet, and releases
 the object from memory, closing it if open, but does not indicate that the
 object has been deleted from the client document.  EcdRelease should be
 called for all objects when closing the client document.

  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.


 Formatting an object


 EcdSetTargetDevice
 ECDSTATUS FAR PASCAL  EcdSetTargetDevice( lpobject, hTargetDevice );

 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 );

 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 );


 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 );

 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.


 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
 ECDSTATUS FAR PASCAL EcdGetData(lpobject, cfFormat, lphandle);
 This function retrieves data in the requested format from the object.  If
 the object cannot provide the data, a null handle is returned.


 lpobject
 LPECDOBJECT
 a long pointer to the object from which to retrieve data

 cfFormat
 ECDCLIPFORMAT
 format in which the data should be returned

 lphandle
 HANDLE FAR *
 long pointer to a handle where the library will store a handle to a memory
 object containing the data in the requested format, or null if cannot
 satisfy the request.

 return value
 ECDSTATUS
 see ECDSTATUS type definition


 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.


 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,
 ecdupdate_onclose } ECDOPT_UPDATE;

 EcdGetLinkUpdateOptions
 ECDSTATUS   FAR PASCAL  EcdGetLinkUpdateOptions( lpobject, lpupdateopt );
 This function returns the update options for the specified object.


 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.

 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.


 EcdQueryOpen
 ECDSTATUS FAR PASCAL EcdQueryOpen( lpobject );
 This function queries whether the object is open.

 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.

 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.


 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.

 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.

 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
     EcdCreateFromFile
     EcdCreateLinkToFile
 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,
 lhclientdoc, lpobjname, lplpobject , renderopt, cfFormat, objtype);

 ECDSTATUS FAR PASCAL DefCreateFromClip ( protocol, lpclient, lhclientdoc,
 lpobjname, 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.

 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.

 lhclientdoc
 LHCLIENTDOC
 long handle to client document

 lpobjname
 LPSTR
 string containing the client's name 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,
 lhclientdoc, lpobjname, lplpobject, objtype, aClass, cfFormat );

 ECDSTATUS FAR PASCAL DefLoadFromStream( lpstream, protocol, lpclient,
 lhclientdoc, lpobjname, lplpobject, objtype, aClass, cfFormat );

 lpstream
 LPECDSTREAM
 a long pointer to an ECDSTREAM structure allocated and initialized by the
 client aplication.  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

 lhclientdoc
 LHCLIENTDOC
 long handle to client document

 lpobjname
 LPSTR
 string containing the client's name for the object.

 lplpobject
 LPECDOBJECT FAR *
 a long pointer to an LPECDOBJECT where the library will store the long
 ointer 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 *SetTargetDevice) ( LPECDOBJECT lpobj,
                         HANDLE  hdata );
     ECDSTATUS (FAR PASCAL *SetBounds)( LPECDOBJECT lpobj, LPRECT );
     ECDSTATUS (FAR PASCAL *EnumFormats) (LPECDOBJECT lpobj,
                             ECDCLIPFORMAT  clipFormat);
     ECDSTATUS (FAR PASCAL *Release)( LPECDOBJECT lpobj);
     ECDSTATUS (FAR PASCAL *SetHostNames)( LPECDOBJECT lpobj, LPSTR. LPSTR );
     ECDSTATUS (FAR PASCAL *SaveToStream)(LPECDOBJECT, LPECDSTREAM);
     ECDSTATUS (FAR PASCAL *Clone)(LPECDOBJECT,LPECDCLIENT, LHCLIENTDOC,
                     LPSTR,LPECDOBJECT FAR * );
     ECDSTATUS (FAR PASCAL *CopyFromLink)( LPECDOBJECT, LPECDCLIENT,
                     LHCLIENTDOC, LPSTR, 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,
                         LHCLIENTDOC lhclientdoc,
                         LPSTR lpobjname
                         LPECDOBJECT FAR * lplpobject);
 } ECDOBJECTVTBL
 typedef struct _ECDOBJECT{
     struct _ECDOBJECTVTBL FAR *vptr;
     /* server supplied object state goes here */
 } ECDOBJECT;



 Object release
 The Release 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 Release 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
 typedef enum {
     ECD_SRVR_MULTI,           // multiple instances
     ECD_SRVR_SINGLE           // single instance (mutiple document)
 }ECD_SRVR_USE;

 ECDSTATUS FAR PASCAL EcdRegisterServer( classname, lpsrvr , lplhserver,
 hInst, srvr_use );
 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.

 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.

 srvr_use
 ECDSRVR_USE
 indicates whether a single instance of this server should be used to support
 multiple clients, or whether multiple instances should be used.  Note that
 MDI servers may follow either convention.  SDI servers must be multiple
 instance.  This option is used to control the negotiation between client and
 server libraries on opening an object.

 return value
 ECDSTATUS
 see ECDSTATUS type description.


 Concurrency control

 Server applications may control when the server library will process
 requests from clients (and potentially call back to the server application)
 with the following functions.

 EcdBlockServer, EcdUnblockServer
 ECDSTATUS FAR PASCAL EcdBlockServer (LPECDSERVER);
 ECDSTATUS FAR PASCAL EcdUnblockServer (LPECDSERVER, BOOL FAR *);
 EcdBlockServer directs the library to queue incoming requests until such
 time as the server calls EcdUnblockServer.   EcdUnblockServer processes one
 request (if any are ending) and returns through the second parameter a
 boolean indicating whether or not there are more requests in the queue.

 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.

 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.

 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.

 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.

 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.

 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.

 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,lpdoc,lplhdoc
 );
 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.

 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.

 lpdoc
 LPECDDOCUMENT
 a long pointer to an ECDDOCUMENT structure allocated and initialized by the
 server application.

 lplhdoc
 LHDOCUMENT FAR *
 a long pointer to a long handle where the library will return the handle by
 which it identifies the document internally.

 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.

 pdoc
 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.

 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.


 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.

 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.

 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.

 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.

 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.
 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.

 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.

 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.

 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.

 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.

 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 = <classname>
 .classes\<classname> = <Human readable classname, localizable>
 .classes\<classname>\protocol\StdFileEditing\Server =     <pathname and
 arguments>
 .classes\<classname>\protocol\StdFileEditing\Handler = <dll pathname>
 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.
 ...
 [Embedding]
 <classname>=<comment>,<human readable classname>,<pathname and
 arguments>,Picture,1
 The system registration service also reads and writes registration
 information in the Embedding section of win.ini for compatibility with
 earlier applications.  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.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.
 Client side logic is as follows.  In all cases if an initiate receives more
 than one response the first is taken and the others are terminated.
 Linked object:

     Initiate classname, documentname
     if not found {
         initiate classname, OLEsystem
         if not found {
             initiate classname, System
             if not found {
                 launch appname, -Embedding
                 fLaunched = true
                 initiate classname, OLEsystem
                 if not found {
                     initiate classname, System
                     if not found
                         return error
                 }
             }
         }
         // here we have a conversation with system or OLEsystem topic
         DDE_EXECUTE StdOpenDocument(docname)
         initiate classname, Documentname
         if not found {
             if( fLaunched ) DDE_EXECUTE StdExit //clean up!
             return error
         }
     }
     // here we have a conversation with the right document
 Embedded object:

     initiate classname, OLEsystem
     if not found {
         initiate classname, System
         if not found {
             launch appname, -Embedding
             fLaunched = true
             initiate classname, OLEsystem
             if not found {
                 initiate classname, System
                 if not found
                     return error
             }
         }
     }
     // here we have a conversation with system or OLEsystem topic
     DDE_EXECUTE StdEditDocument(docname)
         // or StdCreateDoc if this is Insert New Object command
     initiate classname, Documentname
     if not found {
         if( fLaunched ) DDE_EXECUTE StdExit     //clean up!
         return error
     }
     // now we have a conversation with the right document.


 Server-side logic is as follows.  There are two cases, one where the server
 wishes to re-use a single instance for editing all objects (in MDI child
 windows), and the other where a new instance is to be used for each object.
 The latter case includes SDI applications.  In addition, SDI application
 should reject requests to open or create a new docuemnt if they already have
 a document open.
 Single instance app:

         case wm_dde_initiate
             if classname == this class {
                 if ( docname == OLEsystem || docname == System )
                         initateack
                 else if docname == name of some open document
                         initiateack
             }

 multi-instance app:

         case wm_dde_initiate:
             if classname == this class {
                 if ( docname == OLEsystem || docname == System ) {
                         if no documents open
                                 initiateack
                 }
                 else if docname == name of some open document
                         initiateack
             }


 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 document 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



 ClassName:szClassname
 DocumentName:szDocument
 ItemName:szItemApplications 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 environmental information that the server supports for its
 documents. Currently defined are StdHostNames , StdDocDimensions and
 StdTargetDevice. Applications can declare 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 interpreted 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 document). 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:
    <itemname>/<update type>

 For backward compatibility, omission of the update type results in the same
 as specifying /Change. <update type> 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 <item, update type, format,
 conversation>. 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 acknowledgement, 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.


