Annotation of mstools/mfc/doc/tn010.txt, revision 1.1.1.1

1.1       root        1: Microsoft Foundation Classes                           Microsoft Corporation
                      2: Technical Notes
                      3: 
                      4: #10 : Writing an OLE Server Application
                      5: 
                      6: This note describes the classes and steps involved in creating
                      7: an OLE server application.
                      8: 
                      9: Please be sure to read the general MFC OLE overview (TN008.TXT).
                     10: 
                     11: =============================================================================
                     12: Features of an OLE Server Application
                     13: =====================================
                     14: 
                     15: User Interface Features
                     16: -----------------------
                     17: 
                     18: The following briefly describes some of the end-user features of a
                     19: typical OLE Server application. How the MFC OLE classes are used to
                     20: provide this support is described later.
                     21: 
                     22: 1) Editing Embedded Data
                     23:     OLE Servers will support editing of embedded data.  That is, data stored
                     24:     in a client document which is given to the server to edit or display.
                     25:     The data is given back to the client document to be saved when closed.
                     26:     In the case of editing an embedded document, the "File" menu should
                     27:     have an "Update" menuitem instead of "Save".
                     28: 
                     29: 2) Editing Linked Data
                     30:     A server may optionally provide linking to server documents.
                     31:     In this case the server will provide in addition to the embedded
                     32:     data editing features, the ability to open normal files and copy
                     33:     data to the clipboard.
                     34: 
                     35:     Additional features of linked data is that data updated the server
                     36:     can automatically be updated in the client.  The client may turn
                     37:     of automatic updates if desired.
                     38: 
                     39: 3) SDI vs MDI user interface
                     40:     Since multiple client applications may be using embedded or linked
                     41:     data at the same time, we need to support multiple servers.
                     42:     There are two ways this can be done.  With a single document interface
                     43:     (SDI) the application must support multiple instances (i.e. a new
                     44:     instance of the server application will be launched for each edited
                     45:     document).  For server applications that support links, or an MDI
                     46:     interface, one instance of the application will responding to all
                     47:     OLE client requests (i.e. create an new CMDIChildWnd for each document).
                     48: 
                     49: 4) Additional Verbs
                     50:     All OLE client apps provide access to the primary verb for an embedded
                     51:     or linked object. This primary verb is usually "edit". Additional
                     52:     verbs may be defined, and will be presented in the OLE client's Edit
                     53:     menu when the embedded (or linked) object is selected.
                     54:     These additional verbs can be added by registering the server
                     55:     using the AfxOleRegisterServerName() function, or by using a
                     56:     setup program.
                     57: 
                     58: Additional Features
                     59: -------------------
                     60: There are many other advanced features of an OLE Server you may wish
                     61: to consider.
                     62: 
                     63:     * the ability to support multiple data formats.  MFC OLE defaults
                     64:         to supporting "native" format and drawing as a meta-file.
                     65: 
                     66:     * OLE servers do not have to be visual and have a complete user
                     67:         interface.  Note-it and sound players are examples of these
                     68:         simple servers that support embedding.
                     69: 
                     70:     * OLE servers can support multiple types.  For example the MS Excel
                     71:         application supports charts and spreadsheets.
                     72: 
                     73:     * OLE servers may also support execution of generic DDE execute
                     74:         commands.  Refer to the 'OnExecute' member functions.
                     75: 
                     76:     * it is possible to support links but not embedding.  This is not
                     77:         very typical but it is possible.
                     78: 
                     79:     * MFC OLE does not support OLE Handlers (i.e. DLLs for doing more
                     80:         efficient server operations).  OLE Handlers can be written
                     81:         using the OLE API and may talk to an OLE server application
                     82:         written with MFC OLE.
                     83: 
                     84: =============================================================================
                     85: Tasks of an OLE Server Developer
                     86: ================================
                     87: 
                     88: The Classes
                     89: ------------
                     90: As mentioned in the overview, the MFC OLE classes require that you
                     91: derive your own classes from the MFC OLE base classes.  You must
                     92: provide at least three derived classes, one for the server
                     93: application, one for the server document and one for the server
                     94: items.
                     95: 
                     96: The server is used for managing server docs and is notified when clients
                     97: want to open or edit server documents.
                     98: 
                     99: The server document class defines the structure of how items are managed.
                    100: The server item class defines the structure of how linked and/or embedded
                    101: OLE items fit into your application.
                    102: 
                    103: There will typically only be one server object in your application.  Having
                    104: more than one is necessary only if you want to support multiple OLE types.
                    105: There will one server document object per document.  For an SDI multi-instance
                    106: application this will be one document per application.  For an MDI
                    107: single-instance application, this will be one document for each MDI Child
                    108: window.
                    109: 
                    110: Each document may have zero or more server items.
                    111: 
                    112: 
                    113: Creating the server class
                    114: -------------------------
                    115: Class 'COleServer' provides a base class that is used for all global
                    116: server management.  You must derive your own server class from
                    117: 'COleServer' and override several member functions:
                    118: 
                    119:     OnCreateDoc   - create a new server document
                    120:     OnEditDoc     - edit an existing server document
                    121: 
                    122: For servers that support links, you must also implement:
                    123:     OnOpenDoc     - open an existing document
                    124: 
                    125: 
                    126: In all of these cases you should create a new object of your
                    127: server document class (derived from COleServerDoc) and return
                    128: it.  Do not register this server document.
                    129: 
                    130: 
                    131: Creating the document class
                    132: ---------------------------
                    133: Class 'COleServerDoc' provides a base class that is used to contain
                    134: server items.  You must derive your own document class from
                    135: 'COleServerDoc' and override several member functions:
                    136: 
                    137:     OnGetDocument    - return a new item representing the entire document
                    138:     OnGetItem        - return a new item representing the named part of
                    139:                             the document.
                    140: 
                    141: In both of these cases, you should create a new object of your server
                    142: item class (derived from COleServerItem) and return it.
                    143: 
                    144: For applications that support links, a server document should be created
                    145: for every named file.  If the server document is not opened as a
                    146: result of a COleServer request (eg: OnCreateDoc or OnOpenDoc above) you must
                    147: explicitly register the document (eg: when the user directly opens an
                    148: existing file from the File/Open menu item).   The 'Register'
                    149: member function is used for this registering.  'Revoke' can be used
                    150: to revoke the document.
                    151: 
                    152: When the server document changes, there are specific notification routines
                    153: that must be called:
                    154:     NotifyRename        - call after document has been renamed by user
                    155:     NotifyRevert        - call after document has been reverted to original
                    156:                         (i.e. re-opened ignoring recent changes)
                    157:     NotifySaved         - call after document has been saved to disk
                    158: 
                    159: Additional notifications include:
                    160:     NotifyClosed        - closed notification for old OLE servers
                    161:                             (usually NotifySaved and Revoke is enough)
                    162:     NotifyChanged        - notify of some global document change
                    163: 
                    164: 
                    165: Creating the item class
                    166: -----------------------
                    167: Your server item is the server-side view of the linked or embedded
                    168: OLE object.  Class 'COleServerItem' provides a base class that is used
                    169: to keep all the native data required to manage the server data as well
                    170: as any additional user interface data.
                    171: A COleServerItem must always be contained in a COleServerDoc.  If the
                    172: server item is created as a result of a COleServerDoc callback
                    173: (i.e. OnGetDocument or OnGetItem) than no extra work must be done.
                    174: 
                    175: Do not create server items outside these callbacks.
                    176: 
                    177: You must override several member functions:
                    178:     OnShow is called when the item is to be shown.  It should scroll
                    179:         the specific item into view and set the focus to it if appropriate.
                    180:     OnDraw is called when the item is to be drawn (NOTE: it is drawn
                    181:        into metafile DC, not a screen DC).
                    182:     Serialize is part of the normal CObject serialization.
                    183: 
                    184:     Serialize is the means for getting the native data.  You must implement
                    185:         Serialize in your item class to load and store all important
                    186:         native data for your server item.
                    187:         COleServerItem::Serialize is a pure virtual function so you should
                    188:         not call this as part of your serialize operation.
                    189: 
                    190: 
                    191: Flow of control
                    192: ---------------
                    193: Scenario for creating a new embedded object: (from Insert-New-Object
                    194:   on the client app)
                    195:    * the server is asked to create a new document (OnCreateDoc)
                    196:    * the server document is asked to get an item representing
                    197:        the entire document (OnGetDocument)
                    198:    * the server item will be shown - but the client will still have
                    199:        a "blank" item.
                    200:    * when the server document is saved (eg: File/Update) then the client
                    201:        will be updated.
                    202: 
                    203: Scenario for editing an existing embedded object:
                    204:    * the server is asked to create a new document (OnCreateDoc)
                    205:    * the server document is asked to get an item representing
                    206:        the entire document (OnGetDocument)
                    207:    * the server item is de-serialized from the data provided by the client.
                    208:        This will be the data from a previous serialization.
                    209:    * the server item will be shown.
                    210:    * when the server document is saved (eg: File/Update) then the client
                    211:        will be updated.
                    212: 
                    213: Scenario for editing an linked object:
                    214:    * the server is asked to open an existing document (OnOpenDoc)
                    215:    * the server document is asked to get an item representing
                    216:        the entire document (OnGetDocument) or just a part of the
                    217:        document (OnGetItem) depending on how the link was stored.
                    218:    * the server item will be shown.
                    219: 
                    220: 
                    221: Checking errors and catching exceptions
                    222: ---------------------------------------
                    223: Some callbacks from the server or server document or server
                    224: items will return OLESTATUS codes.  These should follow the conventions
                    225: of the OLE API (i.e. return OLE_OK if ok, some other OLESTATUS code
                    226: on error, eg: OLE_ERROR_GENERIC).
                    227: Other callbacks that return more useful information may throw exceptions
                    228: in the server or if possible just return a NULL value (eg: for OnCreateDoc
                    229: in the COleServer).
                    230: 
                    231: Asynchronous Requests
                    232: ---------------------
                    233: When inside a callback from a server or server document or server item
                    234: you should not do any modal operation or anything that will cause your
                    235: application to call GetMessage or PeekMessage.  The debugging version
                    236: of the MFC CWinApp class has special asserts that will catch scenarios
                    237: where server code is calling the main message pump when it shouldn't.
                    238: 
                    239: Implementing the UI features
                    240: ----------------------------
                    241: The following gives a brief overview of what you must do to implement
                    242: the major User Interface features of OLE for your server application.
                    243: See above for the list of 4 major UI features.  See the OSERVER and
                    244: TESTSERV sample program for a working examples (OSERVER just supports
                    245: embedding, TESTSERV supports linking and embedding).
                    246: 
                    247: 1) Editing Embedded Data
                    248:     When your program is executed, you should examine the command
                    249:     line argument in InitInstance.  Check for the special "-Embedding"
                    250:     or "/Embedding" flag, which determines if this application was
                    251:     launched for embedding or not.
                    252:     When constructing a server object (i.e. an object of your class
                    253:     derived from COleServer) pass TRUE to the constructor if the
                    254:     application was launched embedded.  If launched embedded, the
                    255:     server application will automatically shutdown when no more
                    256:     client applications are connected to it.
                    257: 
                    258:     The basic structure of the server/server document/server item
                    259:     provides most of what is needed for editing embedded data.
                    260:     If your application also supports links to files, be sure to
                    261:     change the file menu to "Update" instead of "Save".
                    262: 
                    263: 2) Editing Linked Data
                    264:     There are additional ways of accessing data when passed links.
                    265:     In addition to the "/Embedding" flag, server applications that
                    266:     support links should also look for a filename after the embedding
                    267:     command line argument.  If found, this is the first file that
                    268:     should be opened.
                    269: 
                    270:     In order for a client to paste a link to your server application,
                    271:     you must copy a link to the clipboard.  See the TESTSERV program
                    272:     for an example of this.
                    273: 
                    274:     Lastly, since clients may want immediate updates, the NotifyChanged
                    275:     operation in COleServerItem can be used to notify the client that
                    276:     this one specific change has occured.  In general changes to all
                    277:     server items (embedded and linked) will be notified when the
                    278:     server document is saved (i.e. NotifySaved is called).
                    279: 
                    280: 3) SDI vs MDI user interface
                    281:     Building an SDI vs MDI app is just like a normal MFC windows app.
                    282:     The additional work you must do is to register your server
                    283:     (i.e. an object of your class derived from COleServer).  Call
                    284:     the Register function with the OLE class name (non-localized)
                    285:     and a BOOL indicating if your app is multiple instance or not:
                    286: 
                    287:         SDI <=> multiple instance
                    288:                     (one CFrameWnd per document usually)
                    289:         MDI <=> single instance
                    290:                     (one CMDIChildWnd per document usually)
                    291: 
                    292: 4) Additional Verbs
                    293:     Additional verbs must be defined in the registration database.
                    294:     See below for the steps involved in creating a .REG file.
                    295:     Additional verbs may be handled by overriding COleServerItem::OnExtraVerb
                    296:     and doing a switch on the passed verb number).  You should
                    297:     return OLE_ERROR_DOVERB for verbs you don't understand.
                    298: 
                    299:     The primary verb of 0 is handled automatically by the default OnShow
                    300:     member function.
                    301: 
                    302: =============================================================================
                    303: Creating a REG file
                    304: ===================
                    305: 
                    306: In order to provide the OLE system functionality with enough information
                    307: about your OLE server, you must add this information to the system
                    308: registration database.
                    309: 
                    310: The sample OSERVER.REG provides a registration file with the
                    311: basic structure which you can start with.  Follow the additional
                    312: steps below.
                    313: 
                    314: To actually place the information in the registration database, you
                    315: can use the AfxOleRegisterServerName() function to automatically
                    316: register the server when running it from the program manager, file
                    317: manager, or from an Icon.  The AfxOleRegisterServerName() function
                    318: will also keep up with any changes in the server location.  To use
                    319: this function, simply call it within your application's
                    320: InitInstance() function.  It takes a class name and human readable
                    321: name as parameters (see steps 2 and 3 below).
                    322: 
                    323: Steps for writing/customizing a .REG file:
                    324: 
                    325: 1) start from an existing .REG file, it's easier that way.  The OLE
                    326:       sample programs have sample .REG files in their source directories.
                    327: 
                    328: 2) pick a OLE class name for each of your OLE object types
                    329:     This is an implementation name so it should be designed
                    330:     to avoid collisions - so use your company's name or your
                    331:     initials at the start of the class name.  This name should not
                    332:     contain spaces.  eg: "MSGraph" or "JOE_CHART".
                    333: 
                    334: 3) provide a human readable form of that OLE class name.  This
                    335:     is what people will see in the "Insert New Object" dialog box
                    336:     and other user interfaces.  This name may contain spaces.
                    337:     eg: "Microsoft Graph" or "Joe's Cool Chart Thing"
                    338: 
                    339: 4) provide the path name for where your server application will
                    340:     be installed.  The standard for this is to place each server
                    341:     in a sub-directory of the Windows system directory
                    342:     (usually C:\WINDOWS\OLEAPPS\MYSERVER).
                    343:     If the server is going to be on the search path when Windows
                    344:     is running, you do not have to specify an absolute path.
                    345: 
                    346: 5) if you have a standard suffix for all your data files, add that
                    347:     to the registration file.
                    348: 
                    349: 6) if you have additional verbs for your server data, add them starting
                    350:     with index 0.  You will usually want to use verb index 0 as the
                    351:     standard "Edit" verb.
                    352: 
                    353: 7) save the registration file with the same name as your server
                    354:     (eg: if you are building MYSERVER.EXE, name the file MYSERVER.REG).
                    355: 
                    356: =============================================================================
                    357: Other Issues:
                    358: =============
                    359: 
                    360: Building
                    361: --------
                    362: Assuming you are already building a normal MFC windows application,
                    363: you must do the following additional steps:
                    364: 
                    365:     * include 'afxole.h' in those source files using MFC OLE (this will
                    366:         include 'afxwin.h' if not included already).
                    367:     * Link with the appropriate MFC library as usual.
                    368:     * You will also need to link with two additional libraries:
                    369:         OLESVR.LIB    - interfaces to the server side OLE APIs
                    370:         SHELL.LIB     - interfaces to the system registration database
                    371: 
                    372: Debugging and Testing
                    373: ---------------------
                    374: See TN007.TXT and TN009.TXT for general tips on debugging OLE applications.
                    375: 
                    376: 
                    377: =============================================================================
                    378: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.