home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / C++-7 / DISK11 / MFC / DOC / TN010.TX$ / tn010
Encoding:
Text File  |  1992-03-17  |  16.6 KB  |  379 lines

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