home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_122 / 2.ddi / OLESRVR.ZIP / OBJECT.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-10  |  18.5 KB  |  721 lines

  1. // ObjectWindows - (C) Copyright 1992 by Borland International
  2.  
  3. /* implementation of class TOLEObject */
  4.  
  5. #include <owl.h>
  6.  
  7. #define SERVERONLY
  8. #include <ole.h>
  9.  
  10. #include <ctype.h>
  11. #include "olesrvr.h"
  12. #include <string.h>
  13. #include <fstream.h>
  14.  
  15. OLEOBJECTVTBL  TOLEObject::_vtbl;
  16.  
  17.  
  18. /*
  19.     constructor
  20.     -----------
  21. */
  22. TOLEObject::TOLEObject ()
  23. {
  24.   lpvtbl = &_vtbl;
  25.   native.type = objEllipse;
  26.   native.version = 1;
  27.   lpClients[0] = 0;
  28.   fRelease = FALSE;
  29. }
  30.  
  31.  
  32. ostream &operator<< (ostream &out, TOLEObject &obj)
  33. {
  34.   out << int (obj.native.type) << " ";
  35.   out << obj.native.version;
  36.   return out;
  37. }
  38.  
  39.  
  40. istream  &operator>> (istream &in, TOLEObject &obj)
  41. {
  42.   int  newType;
  43.  
  44.   in >> newType;
  45.   ((TWindowServer *) GetApplicationObject()->MainWindow)->ShapeChange ((NATIVETYPE) newType);
  46.   obj.native.type = (NATIVETYPE) newType;
  47.   in >> obj.native.version;
  48.   return in;
  49. }
  50.  
  51.  
  52. /*
  53.     SetType
  54.     -------
  55.  
  56.     sets the "type" instance variable and calls ObjectChanged()
  57. */
  58. void
  59. TOLEObject::SetType (NATIVETYPE type)
  60. {
  61.   native.type = type;
  62.  
  63.   ObjectChanged();
  64. }
  65.  
  66.  
  67. /*
  68.     ObjectChanged
  69.     -------------
  70.  
  71.     send each of the clients we are linked to an OLE_CHANGED message
  72. */
  73. void
  74. TOLEObject::ObjectChanged ()
  75. {
  76.   TOLEDocument  *pDoc = ((TOLEApp *) GetApplicationObject())->pServer->pDocument;
  77.  
  78.   //
  79.   // call the object through its callback function
  80.   //
  81.   if (lpClients[0])
  82.     for (int i = 0; lpClients[i] != 0; i++)
  83.       lpClients[i]->lpvtbl->CallBack (lpClients[i], OLE_CHANGED, this);
  84.  
  85.   //
  86.   // mark the document as changed
  87.   //
  88.   pDoc->fDirty = TRUE;
  89. }
  90.  
  91.  
  92. /*
  93.     AddClientLink
  94.     -------------
  95. */
  96. void
  97. TOLEObject::AddClientLink (LPOLECLIENT lpOleClient)
  98. {
  99.   //
  100.   // we always append clients to the end of the list
  101.   //
  102.   // find the next slot
  103.   //
  104.   for (int i = 0; i < MAXLINKS; i++)
  105.     if (lpClients[i] == 0) {
  106.       lpClients[i] = lpOleClient;
  107.       lpClients[i + 1] = 0;  // NULL terminator
  108.       return;
  109.     }
  110. }
  111.  
  112.  
  113. /*
  114.     Draw
  115.     ----
  116.  
  117.     draw the type specified by "type" using the device context that is passed
  118.     in
  119. */
  120. void
  121. TOLEObject::Draw (HDC hDC)
  122. {
  123.   HANDLE  hOldBrush = SelectObject (hDC, CreateSolidBrush (RGB (255, 0, 0)));
  124.   HANDLE  hOldPen = SelectObject (hDC, GetStockObject (NULL_PEN));
  125.  
  126.     switch (native.type) {
  127.         case objEllipse:
  128.       Ellipse (hDC, 0, 0, OBJWIDTH, OBJHEIGHT);
  129.             break;
  130.  
  131.         case objRect:
  132.             Rectangle (hDC, 0, 0, OBJWIDTH, OBJHEIGHT);
  133.             break;
  134.  
  135.         case objTriangle:
  136.       int    xCenter = OBJWIDTH / 2;
  137.       POINT  pts[] = {{xCenter, 0},
  138.                       {0, OBJHEIGHT - 1},
  139.                       {OBJWIDTH - 1, OBJHEIGHT - 1},
  140.                       {xCenter, 0}};
  141.  
  142.       Polygon (hDC, pts, 4);
  143.             break;
  144.         }
  145.  
  146.   DeleteObject (SelectObject (hDC, hOldBrush));
  147.   SelectObject (hDC, hOldPen);
  148. }
  149.  
  150.  
  151. /*
  152.     GetNativeData
  153.     -------------
  154.  
  155.     returns a global memory handle that contains the native data for the
  156.     receiver
  157.  
  158.     this handle can be used to set the Native clipboard data format
  159. */
  160. HANDLE
  161. TOLEObject::GetNativeData ()
  162. {
  163.   HANDLE     hData;
  164.   LPNATIVE   lpData;
  165.  
  166.   hData = GlobalAlloc (GMEM_DDESHARE, sizeof (native));
  167.  
  168.   if (hData) {
  169.     lpData = (LPNATIVE) GlobalLock (hData);
  170.     *lpData = native;
  171.     GlobalUnlock (hData);
  172.   }
  173.  
  174.   return hData;
  175. }
  176.  
  177.  
  178. /*
  179.     GetLinkData
  180.     -----------
  181.  
  182.     returns a global memory handle that contains three fields:
  183.  
  184.     - class name
  185.     - document name (typically a fully qualified path name that identifies
  186.       the file containing the document)
  187.     - item name (uniquely identifies the part of the document that is defined
  188.       as an object)
  189.  
  190.     the class name and document name are null terminated, and the item name
  191.     has two terminating null characters, e.g. CNAME\0DNAME\0INAME\0\0
  192.  
  193.     NOTE: item names are assigned by the server. since we have only 1 object
  194.           per document, we always use the same name ("1"). most applications
  195.           would use a different strategy, e.g. "Object1", "Object2", ...
  196.  
  197.     since "ObjectLink" and "OwnerLink" formats contain the same information
  198.     the handle that is returned can be used for both clipboard formats
  199. */
  200. HANDLE
  201. TOLEObject::GetLinkData ()
  202. {
  203.   HANDLE         hData;
  204.   LPSTR          lpData;
  205.   TOLEDocument  *pDoc = ((TOLEApp *) GetApplicationObject())->pServer->pDocument;
  206.   int            docNameLen = strlen (pDoc->szName);
  207.   const int      classKeyLen = sizeof (szClassKey) - 1;        
  208.   int            len =  classKeyLen + docNameLen + strlen ("1") + 4;
  209.  
  210.   hData = GlobalAlloc (GMEM_DDESHARE, len);
  211.  
  212.   if (hData) {
  213.     lpData = (LPSTR) GlobalLock (hData);
  214.   
  215.     //
  216.     // write class name
  217.     //
  218.     lstrcpy (lpData, szClassKey);
  219.     lpData += classKeyLen + 1;
  220.   
  221.     //
  222.     // write document name
  223.     //
  224.     lstrcpy (lpData, pDoc->szName);
  225.     lpData += docNameLen + 1;
  226.   
  227.     //
  228.     // write item name (we always write "1")
  229.     //
  230.     *lpData++ = '1';
  231.     *lpData++ = '\0';
  232.   
  233.     //
  234.     // write extra null terminator
  235.     //
  236.     *lpData = '\0';
  237.   
  238.     GlobalUnlock (hData);
  239.   }
  240.  
  241.   return hData;
  242. }
  243.  
  244.  
  245. /*
  246.     SizeToHiMetric
  247.     --------------
  248.  
  249.     convert a width and height from device units to MM_HIMETRIC units
  250.     which are required by the OLE libraries
  251. */
  252. static
  253. void
  254. SizeToHiMetric (int &width, int &height)
  255. {
  256.   HDC         hDC = GetDC (0);  // screen
  257.   int         dpiX = GetDeviceCaps (hDC, LOGPIXELSX);
  258.   int         dpiY = GetDeviceCaps (hDC, LOGPIXELSY);
  259.   const long  HiMetricPerInch = 2540;
  260.  
  261.   width = int (width * HiMetricPerInch / dpiX);
  262.   height = int (height * HiMetricPerInch / dpiY);
  263.  
  264.   ReleaseDC (0, hDC);
  265. }
  266.  
  267.  
  268. /*
  269.     GetMetafilePicture
  270.     ------------------
  271. */
  272. HANDLE
  273. TOLEObject::GetMetafilePicture ()
  274. {
  275.   LPMETAFILEPICT  lpPict;
  276.   HANDLE          hPict;
  277.   HMETAFILE       hMF;
  278.   HDC             hDC = CreateMetaFile (NULL);
  279.   int             width = 100, height = 100;
  280.  
  281.   //
  282.   // draw the object into the metafile
  283.   //
  284.   SetWindowOrg (hDC, 0, 0);
  285.   SetWindowExt (hDC, width, height);
  286.   Draw (hDC);
  287.  
  288.   //
  289.   // get the handle to the metafile.
  290.   //
  291.   hMF = CloseMetaFile (hDC);
  292.  
  293.   //
  294.   // allocate the metafile picture
  295.   //
  296.   hPict = GlobalAlloc (GMEM_DDESHARE, sizeof (METAFILEPICT));
  297.  
  298.   if (hPict) {
  299.     SizeToHiMetric (width, height);
  300.     lpPict = (LPMETAFILEPICT) GlobalLock (hPict);
  301.   
  302.     lpPict->mm   = MM_ANISOTROPIC;
  303.     lpPict->hMF  = hMF;
  304.     lpPict->xExt = width;
  305.     lpPict->yExt = height;
  306.  
  307.     GlobalUnlock (hPict);
  308.   }
  309.  
  310.   return hPict;
  311. }
  312.  
  313.  
  314. /*
  315.     GetBitmapData
  316.     -------------
  317. */
  318. HBITMAP
  319. TOLEObject::GetBitmapData ()
  320. {
  321.   HWND     hWnd = GetApplicationObject()->MainWindow->HWindow;
  322.   HDC      hDC = GetDC (hWnd);
  323.   HDC      hMemoryDC = CreateCompatibleDC (hDC);
  324.   HBITMAP  hBitmap = CreateCompatibleBitmap (hDC, 100, 100);
  325.   HBITMAP  hOldBitmap = (HBITMAP) SelectObject (hMemoryDC, hBitmap);
  326.   int      width = 100, height = 100;
  327.  
  328.   ReleaseDC (hWnd, hDC);
  329.   PatBlt (hMemoryDC, 0, 0, width, height, WHITENESS);
  330.   Draw (hMemoryDC);
  331.   SelectObject (hMemoryDC, hOldBitmap);
  332.   DeleteDC (hMemoryDC);
  333.  
  334.   //
  335.   // convert the width and height to MM_HIMETRIC (all OLE libraries express
  336.   // the size of every object in MM_HIMETRIC)
  337.   //
  338.   SizeToHiMetric (width, height);
  339.  
  340.   //
  341.   // SetBitmapDimension() wants the width and height in .1 millimeter
  342.   // units, so we must divide by 10...
  343.   //
  344.   SetBitmapDimension (hBitmap, width / 10, height / 10);
  345.  
  346.   return hBitmap;
  347. }
  348.  
  349.  
  350. /*
  351.     callback DoVerb
  352.     -------- ------
  353.  
  354.     client application has called OleActivate() on an embedded object and
  355.     requests an action on the object
  356.  
  357.     the action is specified by the verb identifier "wVerb"
  358.  
  359.     our server only understands EDIT and PLAY:
  360.       - all we do for PLAY is beep
  361.  
  362.       - for EDIT we bring up the server and let the user edit the specified
  363.         object
  364.  
  365.     PARAMETERS:
  366.       - "wVerb" is the index to the verb to execute
  367.       - "fShow" indicates if the server should show the object or remain in
  368.         its current state
  369.       - "fFocus" indicates if the server should take the focus
  370.  
  371.     WHAT TO DO:
  372.       - for PLAY verb, a server doesn't usually show its window or affect the
  373.         focus
  374.       - for EDIT verb, show the server's window and object if "fShow" and take
  375.         the focus is "fFocus"
  376.       - return OLE_OK if successful, OLE_ERROR_DOVERB otherwise
  377. */
  378. OLESTATUS FAR PASCAL _export
  379. TOLEObject::DoVerb (LPOLEOBJECT lpOleObject,
  380.                       unsigned    int wVerb,
  381.                       BOOL        fShow,
  382.                       BOOL        fTakeFocus)
  383. {
  384.   switch (wVerb) {
  385.     case verbEdit:
  386.       //
  387.       // the easiest way to show the server's window is to send the object a
  388.       // "Show" message
  389.       //
  390.       return fShow ? lpOleObject->lpvtbl->Show (lpOleObject, fTakeFocus) : OLE_OK;
  391.  
  392.     case verbPlay:
  393.       for (int i = 0; i < 10; i++)
  394.         MessageBeep (0);
  395.  
  396.       return OLE_OK;
  397.  
  398.     default:
  399.       return OLE_ERROR_DOVERB;
  400.   }
  401. }
  402.  
  403.  
  404. /*
  405.     callback EnumFormats
  406.     -------- -----------
  407.  
  408.     client has requested that we enumerate all clipboard formats that we
  409.     support for object "lpOleObject"
  410.  
  411.     the server library will make multiple calls until we return the format
  412.     that the server library is looking for
  413.  
  414.     PARAMETERS:
  415.       - "cfFormat" is the last format returned by this method. if it is 0 then
  416.         this is the first call to the method for this series
  417.  
  418.     we terminate the query by returning NULL
  419.  
  420.     NOTE: we *must* return the formats in the same order as the order that
  421.           data is placed on the clipboard!
  422. */
  423. OLECLIPFORMAT FAR PASCAL _export
  424. TOLEObject::EnumFormats (LPOLEOBJECT   /* lpOleObject */,
  425.                            OLECLIPFORMAT cfFormat)
  426. {
  427.   TOLEApp  *pApp = (TOLEApp *) GetApplicationObject();
  428.  
  429.   //
  430.   // if "cfFormat" is 0 that indicates the client wants us to return the
  431.   // first format
  432.   //
  433.   if (cfFormat == 0)
  434.     return pApp->cfNative;
  435.  
  436.   else if (cfFormat == pApp->cfNative)
  437.     return pApp->cfOwnerLink;
  438.  
  439.   else if (cfFormat == pApp->cfOwnerLink)
  440.     return CF_METAFILEPICT;
  441.  
  442.   else if (cfFormat == CF_METAFILEPICT)
  443.     return CF_BITMAP;
  444.  
  445.   else
  446.     return NULL;
  447. }
  448.  
  449.  
  450. /*
  451.     callback GetData
  452.     -------- -------
  453.  
  454.     we are requested to supply data for the object in a specific format,
  455.     such as Native or CF_METAFILEPICT
  456.  
  457.     in general you should handle the same data formats that you put on the
  458.     clipboard when the object was embedded/linked
  459.  
  460.     these should be the same formats that are returned by method EnumFormats()
  461.  
  462.     requests foro GetData occur at any time that the client needs to display
  463.     an object or when the data must be written to a client file
  464. */
  465. OLESTATUS FAR PASCAL _export
  466. TOLEObject::GetData (LPOLEOBJECT lpOleObject,
  467.                        WORD        cfFormat,
  468.                        LPHANDLE    lpHandle)
  469. {
  470.   TOLEApp     *pApp = (TOLEApp *) GetApplicationObject();
  471.   TOLEObject  *pObject = (TOLEObject *) lpOleObject;  // just a cast
  472.  
  473.   if (cfFormat == pApp->cfNative) {
  474.     *lpHandle = pObject->GetNativeData();
  475.  
  476.     return *lpHandle ? OLE_OK : OLE_ERROR_MEMORY;
  477.   }
  478.  
  479.   if (cfFormat == pApp->cfOwnerLink) {
  480.     *lpHandle = pObject->GetLinkData();
  481.  
  482.     return *lpHandle ? OLE_OK : OLE_ERROR_MEMORY;
  483.   }
  484.  
  485.   if (cfFormat == CF_BITMAP) {
  486.     *lpHandle = pObject->GetBitmapData();
  487.  
  488.     return *lpHandle ? OLE_OK : OLE_ERROR_MEMORY;
  489.   }
  490.  
  491.   if (cfFormat == CF_METAFILEPICT) {
  492.     *lpHandle = pObject->GetMetafilePicture();
  493.  
  494.     return *lpHandle ? OLE_OK : OLE_ERROR_MEMORY;
  495.   }
  496.  
  497.   return OLE_ERROR_FORMAT;
  498. }
  499.  
  500.  
  501. /*
  502.     callback QueryProtocol
  503.     -------- -------------
  504.  
  505.     server library is trying to determine which protocols we support
  506.  
  507.     "lpszProtocol" will either be "StdFileEditing" or "StdExecute"
  508.  
  509.     if we don't support the protocol then we should return NULL
  510.  
  511.     since we don't support "StdFileExecute" we return NULL in that case
  512. */    
  513. LPVOID FAR PASCAL _export
  514. TOLEObject::QueryProtocol (LPOLEOBJECT lpOleObject,
  515.                              LPSTR       lpszProtocol)
  516. {
  517.     return lstrcmp (lpszProtocol, "StdFileEditing") ? NULL : lpOleObject;
  518. }
  519.  
  520.  
  521. /*
  522.     callback Release
  523.     -------- -------
  524.  
  525.     this method gets called when the library wants to inform us that we have
  526.     no more clients connected to the object
  527.  
  528.     it is initiated after the client calls OleDelete() or the server calls
  529.     OleRevokeServer(), OleRevokeServerDoc(), or OleRevokeObject()
  530.  
  531.     this is the last time that the receiving object will be called, so all
  532.     resources for the object can be free'd, but we MUST not delete the object
  533.     itself...
  534.  
  535.     WHAT TO DO:
  536.       - free resourcess associated with the object
  537.       - set a flag to indicate "Release" has been called
  538.       - NULL out any saved LPOLECLIENT handles saved in the object
  539.       - return OLE_OK if successful, OLE_ERROR_GENERIC otherwise
  540. */
  541. OLESTATUS FAR PASCAL _export
  542. TOLEObject::Release (LPOLEOBJECT lpOleObject)
  543. {
  544.   TOLEObject  *pObject = (TOLEObject *) lpOleObject;
  545.  
  546.   pObject->lpClients[0] = 0;
  547.   pObject->fRelease = TRUE;
  548.     return OLE_OK;
  549. }
  550.  
  551.  
  552. /*
  553.     callback SetBounds
  554.     -------- ---------
  555. */
  556. OLESTATUS FAR PASCAL _export
  557. TOLEObject::SetBounds (LPOLEOBJECT /* lpoleobj */,
  558.                          LPRECT      /* lprect */)
  559. {
  560.     return OLE_ERROR_GENERIC;
  561. }
  562.  
  563.  
  564. /*
  565.     callback SetColorScheme
  566.     -------- --------------
  567. */
  568. OLESTATUS FAR PASCAL _export
  569. TOLEObject::SetColorScheme (LPOLEOBJECT  /* lpOleObject */,
  570.                               LPLOGPALETTE /* lpPal */)
  571. {
  572.     return OLE_ERROR_GENERIC;
  573. }
  574.  
  575.  
  576. /*
  577.     callback SetData
  578.     -------- -------
  579.  
  580.     this routine gets called to provide the server with the data for an
  581.     object that is embedded in a client
  582.  
  583.     this routine gets called after the server has received an "Edit" message
  584.  
  585.     this method is always called before "DoVerb" and "Show"
  586.  
  587.     WHAT TO DO:
  588.       - if the data format isn't Native, return OLE_ERROR_FORMAT
  589.       - lock down the memory to get a pointer to the data, returning
  590.         OLE_ERROR_MEMORY if GlobalLock() returns NULL
  591.       - copy the data to "lpOleObject"
  592.       - unlock the memory and call GlobalFree() on the handle (you are
  593.         responsible for the memory!)
  594.       - return OLE_OK
  595. */
  596. OLESTATUS FAR PASCAL _export
  597. TOLEObject::SetData (LPOLEOBJECT   lpOleObject,
  598.                        OLECLIPFORMAT cfFormat,
  599.                        HANDLE        hData)
  600. {
  601.   TOLEApp  *pApp = (TOLEApp *) GetApplicationObject();
  602.  
  603.   if (cfFormat != pApp->cfNative)
  604.     return OLE_ERROR_FORMAT;  // data isn't in Native format
  605.  
  606.   else {
  607.     LPNATIVE  lpData = (LPNATIVE) GlobalLock (hData);
  608.  
  609.     if (lpData == NULL)
  610.       return OLE_ERROR_MEMORY;
  611.  
  612.     else {
  613.       TOLEObject  *pObject = (TOLEObject *) lpOleObject;
  614.  
  615.       ((TWindowServer *) pApp->MainWindow)->ShapeChange (lpData->type);
  616.       pObject->native = *lpData;
  617.       pApp->pServer->pDocument->fDirty = FALSE;
  618.  
  619.       GlobalUnlock (hData);
  620.       GlobalFree (hData);    
  621.       return OLE_OK;
  622.     }
  623.   }
  624. }
  625.  
  626.  
  627. /*
  628.     callback SetTargetDevice
  629.     -------- ---------------
  630. */
  631. OLESTATUS FAR PASCAL _export
  632. TOLEObject::SetTargetDevice (LPOLEOBJECT /* lpOleObject */,
  633.                                HANDLE      /* hData */)
  634. {
  635.     return OLE_ERROR_GENERIC;
  636. }
  637.  
  638.  
  639. /*
  640.     callback Show
  641.     -------- ----
  642.  
  643.     this method gets called when we should make the object visible by
  644.     making the server window visible and possibly scroling the object into
  645.     view
  646.  
  647.     if the object is selectable, select it as well
  648.  
  649.     PARAMETERS:
  650.       - "fTakeFocus" indicates whether the server should set focus to itself
  651.  
  652.     WHAT TO DO:
  653.       - show the window(s) if not visible
  654.       - scroll "lpOleObject" into view and select it if possible
  655.       - if "fTakeFocus" is TRUE, call SetFocus() with the main window handle
  656.       - return OLE_OK if successful, OLE_ERROR_GENERIC otherwise
  657. */
  658. OLESTATUS FAR PASCAL _export
  659. TOLEObject::Show (LPOLEOBJECT /* lpOleObject */,
  660.                     BOOL        fTakeFocus)
  661. {
  662.   TOLEApp  *pApp = (TOLEApp *) GetApplicationObject();
  663.  
  664.   //
  665.   // in our case all we need to do is request that the window is showing
  666.   //
  667.   pApp->MainWindow->Show (SW_SHOWNORMAL);
  668.  
  669.   if (fTakeFocus)
  670.     SetFocus (pApp->MainWindow->HWindow);
  671.  
  672.   return OLE_OK;
  673. }
  674.  
  675.  
  676.  
  677. typedef OLESTATUS FAR PASCAL _export (FAR *LPOBJDOVERB)(LPOLEOBJECT,unsigned int,BOOL,BOOL);
  678. typedef OLECLIPFORMAT FAR PASCAL _export (FAR *LPOBJENUMFORMATS)(LPOLEOBJECT,OLECLIPFORMAT);
  679. typedef OLESTATUS FAR PASCAL _export (FAR *LPOBJGETDATA)(LPOLEOBJECT,WORD,LPHANDLE);
  680. typedef LPVOID         FAR PASCAL _export (FAR *LPOBJQUERYPROTOCOL)(LPOLEOBJECT,const char far *);
  681. typedef OLESTATUS FAR PASCAL _export (FAR *LPOBJRELEASE)(LPOLEOBJECT);
  682. typedef OLESTATUS FAR PASCAL _export (FAR *LPOBJSETBOUNDS)(LPOLEOBJECT,const RECT far *);
  683. typedef OLESTATUS FAR PASCAL _export (FAR *LPOBJSETCOLORSCHM)(LPOLEOBJECT,const LOGPALETTE far *);
  684. typedef OLESTATUS FAR PASCAL _export (FAR *LPOBJSETDATA)(LPOLEOBJECT,OLECLIPFORMAT,HANDLE);
  685. typedef OLESTATUS FAR PASCAL _export (FAR *LPOBJSETTARGETDEVICE)(LPOLEOBJECT,HANDLE);
  686. typedef OLESTATUS FAR PASCAL _export (FAR *LPOBJSHOW)(LPOLEOBJECT,BOOL);
  687.  
  688.  
  689. /*
  690.     InitVTBL
  691.     --------
  692.  
  693.     create thunks for OLEOBJECT method callback tables
  694. */
  695. BOOL
  696. TOLEObject::InitVTBL (HINSTANCE hInstance)
  697. {
  698.     _vtbl.DoVerb = (LPOBJDOVERB) MakeProcInstance ((FARPROC) DoVerb, hInstance);
  699.     _vtbl.EnumFormats = (LPOBJENUMFORMATS) MakeProcInstance ((FARPROC) EnumFormats, hInstance);
  700.     _vtbl.GetData = (LPOBJGETDATA) MakeProcInstance ((FARPROC) GetData, hInstance);
  701.     _vtbl.QueryProtocol = (LPOBJQUERYPROTOCOL) MakeProcInstance ((FARPROC) QueryProtocol, hInstance);
  702.     _vtbl.Release = (LPOBJRELEASE) MakeProcInstance ((FARPROC) Release, hInstance);
  703.     _vtbl.SetBounds = (LPOBJSETBOUNDS) MakeProcInstance ((FARPROC) SetBounds, hInstance);
  704.     _vtbl.SetColorScheme = (LPOBJSETCOLORSCHM) MakeProcInstance ((FARPROC) SetColorScheme, hInstance);
  705.     _vtbl.SetData = (LPOBJSETDATA) MakeProcInstance ((FARPROC) SetData, hInstance);
  706.     _vtbl.SetTargetDevice = (LPOBJSETTARGETDEVICE) MakeProcInstance ((FARPROC) SetTargetDevice, hInstance);
  707.     _vtbl.Show = (LPOBJSHOW) MakeProcInstance ((FARPROC) Show, hInstance);
  708.  
  709.   return _vtbl.DoVerb != NULL &&
  710.          _vtbl.EnumFormats != NULL &&
  711.          _vtbl.GetData != NULL &&
  712.          _vtbl.QueryProtocol != NULL &&
  713.          _vtbl.Release != NULL &&
  714.          _vtbl.SetBounds != NULL &&
  715.          _vtbl.SetColorScheme != NULL &&
  716.          _vtbl.SetData != NULL &&
  717.          _vtbl.SetTargetDevice != NULL &&
  718.          _vtbl.Show != NULL;
  719. }
  720.  
  721.