home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / C++-7 / DISK11 / MFC / DOC / TN009.TX$ / tn009
Encoding:
Text File  |  1992-01-14  |  14.7 KB  |  320 lines

  1. Microsoft Foundation Classes                           Microsoft Corporation
  2. Technical Notes
  3.  
  4. #9 : Writing an OLE Client Application
  5.  
  6. This note describes the classes and steps involved in creating
  7. an OLE client application.
  8.  
  9. Please be sure to read the general MFC OLE overview first (TN008.TXT).
  10.  
  11. =============================================================================
  12. Features of an OLE Client Application
  13. =====================================
  14.  
  15. User Interface Features
  16. -----------------------
  17. The following list briefly describes some of the end-user features of a
  18. typical OLE Client application. How the MFC OLE classes are used to provide
  19. this support is described later.
  20.  
  21. 1) Insert New Object dialog
  22.     The menu item "Insert &New Object" usually resides on the "Insert"
  23.     or "Edit" menu.  This menu item will bring up a dialog showing all
  24.     the available class names (from the registered OLE Servers in the system).
  25.     The selected class name is used to create a new object of that type
  26.     and insert it into the client document.
  27.     The new object will start out in a blank state - which means
  28.     you must add data to it (by editing it in the server application)
  29.     before it becomes useable by the end user.
  30.  
  31. 2) Paste, Paste Link menu items
  32.     The standard "Edit" menu will usually contain "Paste" and "Paste Link".
  33.     If the client app only supports embedding, there will be no "Paste Link".
  34.     These menu items will be enabled or disabled depending on the current
  35.     contents of the clipboard.
  36.  
  37. 3) Object menu item
  38.     The bottom of the "Edit" menu will usually contain an "Object" menu item.
  39.     This is a dynamic menu item that changes depending on the current
  40.     selection.  If more than one verb is possible it will change into
  41.     a popup menu listing all the verbs.
  42.  
  43. 4) Links dialog
  44.     This is the standard dialog used to view, fix and otherwise manipulate
  45.     all the links in the current document.
  46.  
  47. 5) Insitu features
  48.     The client document is reponsible for drawing the embedded/linked object
  49.     data in the appropriate location.  Also supporting selection of items
  50.     and/or ranges of items as well as non-embedded document components.
  51.     Lastly double-clicking on an embedded/linked object should activate
  52.     that object.
  53.  
  54. 6) OLE items as part of a document
  55.     The embedded/linked items are maintained as part of the document.
  56.     When the document is saved, so are the embedded items as well as the
  57.     links to the linked items.  When the client document is loaded from disk
  58.     the reverse happens and the embedded/linked items are loaded as part of
  59.     the document.
  60.     If your current client application (or the one you are planning) does
  61.     not have documents, or "load" and "save" functionality - you may
  62.     want to implement an OLE server instead.
  63.  
  64. Additional Features
  65. -------------------
  66. There are many other advanced features of an OLE Client than you can
  67. implement on top of MFC OLE. These features are minimally supported in
  68. the MFC OLE classes and are not well documented or illustrated in the
  69. existing sample programs.  These will be added into future versions of
  70. MFC OLE.
  71.  
  72. Additional information on these features can be found in the Windows 3.1
  73. OLE documentation.
  74.  
  75. Features not supported:
  76.     * Paste Special dialog (all the interfaces are there, but no canned
  77.         dialog to make this easy).
  78.     * Full support for UNDO (COleClientItem::CreateCloneFrom is provided,
  79.         but a client app must still do a lot of extra work).
  80.     * Full range of object creation options (for example creating from
  81.         template, or creating from file).  Easy to add in your class derived
  82.         from COleClientItem if needed, but this functionality is
  83.         usually done with the MFC CFile and CArchive classes.
  84.     * Clients using the server data for more than pictures.  In general
  85.         a client will create an embedded/linked object with the
  86.         standard draw option (olerender_draw).  This means the 
  87.         client will just draw the embedded/linked object in a
  88.         rectangle on the screen.  Other render options are available.
  89.     * After loading a document which has manual links, the client app
  90.         should prompt the user to see if they want to update links now.
  91.  
  92. =============================================================================
  93. Tasks of an OLE Client Developer
  94. ================================
  95.  
  96. The Classes
  97. ------------
  98. As mentioned in the overview, the MFC OLE classes require that you
  99. derive your own document and item classes from the MFC OLE base
  100. classes.
  101.  
  102. The document class defines the structure of how items are managed.
  103. The item class defines the structure of how linked and/or embedded
  104. OLE items fit into your application.
  105.  
  106. Creating the document class
  107. ---------------------------
  108. Your client document will typically contain both OLE and non-OLE data.
  109. Presumably you already have a class or two to manage non-OLE data in
  110. your application (i.e. to store, display, hit detect the contents
  111. of a Window's client area).
  112. You must decide how OLE data will mix with the non-OLE data.
  113. If your non-OLE data is stored as a CObject* collection, then there is
  114. no extra work needed (since an OLE item is a CObject as well).
  115. If not, you will have to extend your data structures so that they can
  116. contain a client item wherever you want to mix OLE and non-OLE data.
  117.  
  118. Class 'COleClientDoc' provides a base class that is used to contain
  119. embedded items.  You must derive your own document class from
  120. 'COleClientDoc'.  Be sure to override the member function 'GetNextItem'
  121. to iterate over all the OLE items in the document (the interface is
  122. very similar to MFC lists).
  123.  
  124. You must register your client document when it is created (using 'Register').
  125. Also there are specific notification routines that must be called:
  126.     NotifyRename        - call after document has been renamed by user
  127.     NotifyRevert        - call after document has been reverted to original
  128.                         (i.e. re-opened ignoring recent changes)
  129.     NotifySaved            - call after document has been saved to disk
  130.  
  131. All of these steps are covered in the OCLIENT sample program.
  132. The class CMainDocument is attached to CMainWnd and together they
  133. serve as the main client document.
  134.  
  135. Creating the item class
  136. -----------------------
  137. Your client item is the client-side view of the linked or embedded
  138. OLE object.  Class 'COleClientItem' provides a base class that is used
  139. to keep extra application specific information about each linked/embedded
  140. item.  The position of the item in the client document is an example of
  141. extra  member data you can add to your class derived from COleClientItem.
  142.  
  143. Since a COleClientItem must always be contained in a COleClientDoc, the
  144. containing document must be passed as a parameter to the constructor.
  145.  
  146. Your client item objects (derived from COleClientItem) will be created
  147. in several end-user scenarios: (see below for how to implement these)
  148.     * with the InsertNewObject dialog
  149.     * when pasted from the clipboard (paste or paste-link)
  150.     * when loaded from an existing file
  151.  
  152. You must override the member function 'OnChange' which is a callback
  153. that notifies the client that the server has changed.  There are three
  154. reasons the client item may change: a linked item is changed (with
  155. automatic notification turned on), the document edited on the server
  156. is saved or the document edited on the server is closed.
  157.  
  158. In general do not redraw the client item when you get the 'OnChange'
  159. callback, but instead post an update message (or use InvalidateRect
  160. for the window).
  161.  
  162. All of these steps are covered in the OCLIENT sample program.
  163. The class CEmbeddedItem is attached to CItemWnd and together they
  164. provide both the data and user interface to the client item.
  165.  
  166.  
  167. Checking errors and catching exceptions
  168. ---------------------------------------
  169. Abnormal conditions, like out of memory, or can't launch server will
  170. result in a COleException being thrown.  A COleException object
  171. can be examined to see what OLESTATUS error code caused the problem.
  172. If a set of conditions are expected, the MFC OLE member function will
  173. return a BOOL.  If the BOOL returns FALSE, a more detailed error
  174. report can be determined by COleClientItem::GetLastStatus which
  175. returns the OLESTATUS of the last OLE API function call.
  176.  
  177. Asynchronous Requests
  178. ---------------------
  179. The member function COleClientItem::WaitForServer is used
  180. to synchronize the client with the server.  If a server request can't
  181. be finished immediately, the client application will wait inside of
  182. 'WaitForServer' until the operation is complete (successful or not).
  183. The client code calling this just sees a simple synchronous call.
  184.  
  185. While the client app is waiting it will continue to dispatch windows
  186. messages.  The static member function 'COleClientItem::InWaitForServer'
  187. can be used to see if the client application is already nested in
  188. a server request.  See the OCLIENT sample app for an example of the
  189. use of 'InWaitForServer'.
  190.  
  191. Advanced users may wish to override 'WaitForServer' and customize
  192. it's behavior as appropriate.  See the OCLIENT sample app for an
  193. example of how to turn on the hourglass when a client operation
  194. is going to take too long as the result of a server not being ready.
  195.  
  196. Implementing the UI features
  197. ----------------------------
  198. The following gives a brief overview of what you must do to implement
  199. the major User Interface features of OLE for your client application.
  200. See above for the list of 6 major UI features.  See the OCLIENT sample
  201. program for a working example of how to implement these features.
  202.  
  203. 1) Insert New Object dialog
  204.     (a) call 'AfxOleInsertDialog' to prompt the user for class name
  205.     (b) create an object of your COleClientItem derived class using
  206.             'COleClientItem::CreateNewObject'.
  207.     (c) insert it at the current document (eg: at the insertion point
  208.             if applicable to your application).
  209.  
  210. 2) Paste, Paste Link menu items
  211.     (a) create menu items for "Paste" and, optionally, "Paste Link"
  212.     (b) override OnInitMenu or OnInitMenuPopup in your main frame window
  213.         (i) call 'COleClientItem::CanPaste' to determine if you
  214.             can paste or not and enable menu item accordinglly
  215.         (ii) call 'COleClientItem::CanPasteLink' to determine if you
  216.             can paste link or not and enable menu item accordinglly
  217.  
  218.     (c) when either is selected, use CreateFromClipboard or
  219.         CreateLinkFromClipboard to create the new object from clipboard.
  220.  
  221. 3) Object menu item
  222.     This is a complicated UI which is provided for you in the standard
  223.     MFC OLE library.
  224.     (a) create menu items for "Object" with special ID value
  225.     (b) as with Paste, override OnInitMenu or OnInitMenuPopup in
  226.             your main frame window
  227.     (c) call 'AfxOleSetEditMenu' with the item, menu, and the position where
  228.             to store the 'Object' menu in the specific popup.
  229.  
  230. 4) Links dialog
  231.     (a) add a "Links" menu item to the "Edit" menu popup
  232.     (b) when the user selects the "Links" menu item, call 'AfxOleLinksDialog'
  233.     (c) you can disable the menu item either if no linked items are
  234.         selected, or if the document does not contain linked items.
  235.         (by overriding OnInitMenu or OnInitMenuPopup in
  236.         your main frame window).
  237.  
  238. 5) Insitu features
  239.     This is the most work.
  240.     (a) when your window gets an OnPaint request, it must draw the
  241.     COleClientItem by calling 'Draw'.  This draw routine is passed
  242.     a DC and a bounds rectangle.
  243.     (b) depending on your model of selection - you probably want to support
  244.     selection of linked/embedded items
  245.     (c) perhaps support resizing of embedded items - call SetBounds to
  246.     change the size.
  247.     (d) lastly, when the user double-clicks on a client item, it should
  248.     be activated by calling 'Activate'.  Overriding OnLButtonDblClk
  249.     in the appropriate window class.
  250.  
  251. 6) Object as part of a document
  252.     (a) provide an implementation of Save/load that uses the CArchive
  253.         serialization mechanism.
  254.     (b) implement Serialize for your derived COleClientItem class, and
  255.         be sure to call the base class COleClientItem::Serialize, since
  256.         this will save the embedded/linked object information.
  257.  
  258. =============================================================================
  259. Other Issues:
  260. =============
  261.  
  262. Building
  263. --------
  264. Assuming you are already building a normal MFC windows application,
  265. you must do the following additional steps:
  266.  
  267.     * include 'afxole.h' in those source files using MFC OLE (this will
  268.         include 'afxwin.h' if not included already).
  269.     * Link with the appropriate MFC library as usual.
  270.     * You will also need to link with two additional libraries:
  271.         OLECLI.LIB   - interfaces to the client side OLE APIs
  272.         SHELL.LIB    - interfaces to the registration API
  273.         COMMDLG.LIB  - interfaces to the common dialog API
  274.     * you must include the standard client resources by including
  275.         'afxoleUI.h' and 'afxoleUI.rc' in your client application's
  276.         RC file.  This includes the dialog templates and standard
  277.         strings for the UI parts of the OLE support.
  278.  
  279.     * Warning: the OLE Links dialog may call COMMDLG to prompt
  280.         the user for a new filename.  This requires a reasonable
  281.         amount of stack space (8K or more).
  282.  
  283. Testing
  284. -------
  285. There are two test programs provided in source form in the MFC SAMPLE
  286. directory.
  287.  
  288.         TESTCLNT    - a test client (i.e. used to test servers)
  289.         TESTSERV    - a test server (i.e. used to test clients)
  290.  
  291.     You will probably want to use 'TestServ' or some other OLE server
  292.     to test your application.  See the contents of the sample source
  293.     directories for more details on these test programs.
  294.  
  295. Debugging
  296. ---------
  297. See TN007.TXT for a description of the 'afxTraceFlags' options for
  298. doing advanced debugging.  The multi-application debugging option
  299. (option 1) is extremely useful, especially if you are debugging a
  300. client and a server at the same time.
  301.  
  302. The main message pump reporting (option 2) is very useful when you
  303. are trying to figure out which messages are being dispatched.
  304.  
  305. Option 0x10 is provided specifically for OLE debugging, and
  306. turns on some rather verbose reporting messages informing you what
  307. is going on in the MFC OLE classes.
  308.  
  309. Sample Code
  310. -----------
  311. In addition to the test programs, the OCLIENT sample provides a simple
  312. sample of a OLE Client application.  It exploits all of the user interfaces
  313. provided by MFC OLE.
  314. It is a good example since it is relatively simple.
  315. It is a poor example since each embedded/linked items is stored in a
  316. CWnd (a CItemWnd).  In general embedded/linked items are normally
  317. drawn as part of your client area.
  318.  
  319. =============================================================================
  320.