home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / inole2 / chap18 / cosmo1.0 / oleobj.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  15KB  |  547 lines

  1. /*
  2.  * OLEOBJ.C
  3.  *
  4.  * Contains all callback functions in the OLEOBJECTVTBL struture:
  5.  *      ObjDoVerb
  6.  *      ObjEnumFormats
  7.  *      ObjGetData
  8.  *      ObjQueryProtocol
  9.  *      ObjRelease
  10.  *      ObjSetBounds
  11.  *      ObjSetColorScheme
  12.  *      ObjSetData
  13.  *      ObjSetTargetDevice
  14.  *      ObjShow
  15.  *
  16.  * There are additional callbacks in the OLEOBJECTVTBL.
  17.  * Also contains PObjectAllocate, a constructor for the object.
  18.  *
  19.  * Copyright(c) Microsoft Corp. 1992-1994 All Rights Reserved
  20.  * Win32 version, January 1994
  21.  */
  22.  
  23. #ifdef MAKEOLESERVER
  24.  
  25. #include <windows.h>
  26. #include <ole.h>
  27. #include "cosmo.h"
  28. #include "oleglobl.h"
  29. #include "oleinst.h"    //OBJVERB_* defines for ObjDoVerb
  30.  
  31. /*
  32.  * PObjectAllocate
  33.  *
  34.  * Purpose:
  35.  *  Allocates a COSMOOBJECT structure and sets the defaults in its fields.
  36.  *  Used from DocGetObject.
  37.  *
  38.  * Parameters:
  39.  *  pVtblObj        LPOLESERVERDOCVTBL used to initialize the pvtbl field.
  40.  *
  41.  * Return Value:
  42.  *  LPCOSMOOBJECT   Pointer to the allocated structure in local memory.
  43.  *                  The hMem field will contain a handle to the structure
  44.  *                  to pass to LocalFree.
  45.  */
  46.  
  47. LPCOSMOOBJECT WINAPI PObjectAllocate(LPOLEOBJECTVTBL pVtblObj)
  48.     {
  49.     HLOCAL          hMem;
  50.     LPCOSMOOBJECT   pObj;
  51.  
  52.     hMem=LocalAlloc(LPTR, sizeof(COSMOOBJECT));
  53.     pObj=(LPCOSMOOBJECT)(PSTR)hMem;
  54.  
  55.     //Initialize the object.
  56.     pObj->hMem=hMem;
  57.     pObj->pvtbl=pVtblObj;
  58.     pObj->fRelease=TRUE;
  59.  
  60.     return pObj;
  61.     }
  62.  
  63.  
  64.  
  65.  
  66. /*
  67.  * ObjDoVerb
  68.  *
  69.  * Purpose:
  70.  *  Performs actions on an object when the user opens an object
  71.  *  according to the verb given.
  72.  *
  73.  * Parameters:
  74.  *  pObj            LPCOSMOOBJECT specifying the object affected.
  75.  *  iVerb           UINT index to the verb chosen, zero based.
  76.  *  fShow           BOOL--TRUE if the application should show
  77.  *                  itself with ShowWindow.  FALSE means no change.
  78.  *  fFocus          BOOL--TRUE if the server should get the focus.
  79.  *
  80.  * Return Value:
  81.  *  OLESTATUS       OLE_OK if all is well, otherwise an OLE_* error value.
  82.  */
  83.  
  84. OLESTATUS WINAPI ObjDoVerb(LPCOSMOOBJECT pObj, UINT iVerb
  85.     , BOOL fShow, BOOL fFocus)
  86.     {
  87.     /*
  88.      * 1.   Execute the verb.
  89.      *        a.  For a 'Play' verb, a server does not generally show
  90.      *            its window or affect the focus.
  91.      *
  92.      *        b.  For an 'Edit' verb, show the server's window and the
  93.      *            object if fShow is TRUE, and take the focus if fFocus
  94.      *            is TRUE.  An ideal way to accomplish this is to call
  95.      *            the ObjShow method through the OLEOBJECTVTBL since that
  96.      *            method will handle showing the object and taking the
  97.      *            focus itself.
  98.      *
  99.      *        c.  An 'Open' verb is not clearly defined; depending on the
  100.      *            application it may mean the same as 'Play' or 'Edit.'
  101.      *            The Cosmo server, if it had an 'Open' verb, would treat
  102.      *            it like 'Edit.'
  103.      *
  104.      * 2.  Return OLE_OK if the verb was successfully executed, otherwise
  105.      *     OLE_ERROR_DOVERB.
  106.      */
  107.  
  108.     switch (iVerb)
  109.         {
  110.         case OBJVERB_EDIT:
  111.             /*
  112.              * On edit, simply show yourself and expect a SetData.
  113.              * Best strategy is to use the Show method for this
  114.              * object if necessary, reducing redundancy.
  115.              */
  116.             if (fShow)
  117.                 return (pObj->pvtbl->Show)((LPOLEOBJECT)pObj, fShow);
  118.  
  119.             //Return OLE_OK
  120.             break;
  121.  
  122.  
  123.         case OBJVERB_PLAY:
  124.             //Unsupported at this time.
  125.             return OLE_ERROR_DOVERB;
  126.  
  127.         default:
  128.             return OLE_ERROR_DOVERB;
  129.         }
  130.  
  131.     return OLE_OK;
  132.     }
  133.  
  134.  
  135.  
  136.  
  137.  
  138. /*
  139.  * ObjEnumFormats
  140.  *
  141.  * Purpose:
  142.  *  Requests the server to produce the 'next' supported clipboard
  143.  *  format.  Each format is returned in sequence until the terminator
  144.  *  (a NULL) is returned.
  145.  *
  146.  * Parameters:
  147.  *  pObj            LPCOSMOOBJECT specifying the object affected.
  148.  *  cf              OLECLIPFORMAT the last clipboard format returned by
  149.  *                  this function.  0 indicates the first.
  150.  *
  151.  * Return Value:
  152.  *  OLESTATUS       OLE_OK if all is well, otherwise an OLE_* error value.
  153.  */
  154.  
  155. OLECLIPFORMAT WINAPI ObjEnumFormats(LPCOSMOOBJECT pObj, OLECLIPFORMAT cf)
  156.     {
  157.     /*
  158.      * 1.   Depending on cf, return the 'next' clipboard format in which
  159.      *      the server can render the object's data.
  160.      * 2.   If there are no more supported formats after the format in cf,
  161.      *      return NULL.
  162.      *
  163.      * We must use multiple if's instead of a switch statement because
  164.      * all the cf* values are not constants.
  165.      */
  166.  
  167.     if (0==cf)
  168.        return pOLE->cfNative;
  169.  
  170.     if (pOLE->cfNative==cf)
  171.        return pOLE->cfOwnerLink;
  172.  
  173.     if (pOLE->cfOwnerLink==cf)
  174.        return CF_METAFILEPICT;
  175.  
  176.     if (CF_METAFILEPICT==cf)
  177.        return CF_BITMAP;
  178.  
  179.     if (CF_BITMAP==cf)
  180.        return pOLE->cfObjectLink;
  181.  
  182.     //This IF is here just to be explicit.
  183.     if (pOLE->cfObjectLink==cf)
  184.        return 0;
  185.  
  186.     return 0;
  187.     }
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194. /*
  195.  * ObjGetData
  196.  *
  197.  * Purpose:
  198.  *  Retrieves data from the object in a specified format, where the
  199.  *  server should allocate memory (GlobalAlloc with GMEM_DDESHARE),
  200.  *  fill the memory, and return the handle.
  201.  *
  202.  * Parameters:
  203.  *  pObj            LPCOSMOOBJECT specifying the object affected.
  204.  *  cf              OLECLIPFORMAT format to return data in, may be "Native."
  205.  *  phData          HGLOBAL FAR * in which to store the allocated handle.
  206.  *
  207.  * Return Value:
  208.  *  OLESTATUS       OLE_OK if all is well, otherwise an OLE_* error value.
  209.  */
  210.  
  211. OLESTATUS WINAPI ObjGetData(LPCOSMOOBJECT pObj, OLECLIPFORMAT cf
  212.     , HGLOBAL FAR * phData)
  213.     {
  214.     HGLOBAL             hMem;
  215.  
  216.     /*
  217.      * 1.   Allocate the requested data throguh GlobalAlloc (with
  218.      *      GMEM_MOVEABLE and GMEM_DDESHARE).  The exception is data for
  219.      *      CF_BITMAP which uses a call like CreateBitmap.
  220.      * 2.   Lock and fill the memory with the appropriate data.
  221.      * 3.   Unlock the memory and store the handle in *phData.
  222.      * 4.   Return OLE_OK if successful, OLE_ERROR_MEMORY otherwise.
  223.      */
  224.  
  225.     //Return Native, metafile, or bitmap as requested.
  226.     if (pOLE->cfNative==cf)
  227.         hMem=HGetPolyline(pGlob->hWndPolyline);
  228.  
  229.     if (CF_METAFILEPICT==cf)
  230.         hMem=HGetMetafilePict(pGlob->hWndPolyline);
  231.  
  232.     if (CF_BITMAP==cf)
  233.         hMem=HGetBitmap(pGlob->hWndPolyline);
  234.  
  235.  
  236.     //Use filename
  237.     if (pOLE->cfObjectLink==cf)
  238.          hMem=HLinkConstruct(rgpsz[IDS_CLASSCOSMO], "", "");
  239.  
  240.     /*
  241.      * Even though this is exactly like ObjectLink, this is coded as
  242.      * a separate case just in case it changes in the future.
  243.      */
  244.     if (pOLE->cfOwnerLink==cf)
  245.         hMem=HLinkConstruct(rgpsz[IDS_CLASSCOSMO], "", "");
  246.  
  247.  
  248.     if (NULL==hMem)
  249.         return OLE_ERROR_MEMORY;
  250.  
  251.     *phData=hMem;
  252.     return OLE_OK;
  253.     }
  254.  
  255.  
  256.  
  257.  
  258.  
  259. /*
  260.  * ObjQueryProtocol
  261.  *
  262.  * Purpose:
  263.  *  Returns a pointer to an COSMOOBJECT with the appropriate VTBL for
  264.  *  the protocol, either StdFileEditing or StdExecute.  Returns NULL
  265.  *  if that protocol is not supported.
  266.  *
  267.  * Parameters:
  268.  *  pObj            LPCOSMOOBJECT specifying the object affected.
  269.  *  pszProtocol     OLE_LPCSTR, the protocol name.
  270.  *
  271.  * Return Value:
  272.  *  OLESTATUS       OLE_OK if all is well, otherwise an OLE_* error value.
  273.  */
  274.  
  275. LPVOID WINAPI ObjQueryProtocol(LPCOSMOOBJECT pObj, OLE_LPCSTR pszProtocol)
  276.     {
  277.  
  278.     /*
  279.      * 1.   If the protocol in pszProtocol is supported, return a pointer
  280.      *      to an object that contains an appropriate VTBL fot that protocol,
  281.      *      such as the pObj passed to this method.
  282.      * 2.   If the protocol is not supported, return NULL.
  283.      */
  284.  
  285.     //Check if OLESVR is asking for "StdFileEditing"
  286.     if (0==lstrcmp(pszProtocol, rgpsz[IDS_STDFILEEDITING]))
  287.         return (LPVOID)pObj;
  288.  
  289.     return (LPVOID)NULL;
  290.     }
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297. /*
  298.  * ObjRelease
  299.  *
  300.  * Purpose:
  301.  *  Notifies a server that is can free any resources associated with an
  302.  *  object.
  303.  *
  304.  * Parameters:
  305.  *  pObj            LPCOSMOOBJECT specifying the object affected.
  306.  *
  307.  * Return Value:
  308.  *  OLESTATUS       OLE_OK if all is well, otherwise an OLE_* error value.
  309.  */
  310.  
  311. OLESTATUS WINAPI ObjRelease(LPCOSMOOBJECT pObj)
  312.     {
  313.     /*
  314.      * 1.   Free any resources allocated for this object, but
  315.      *      DO NOT free the OLEOBJECT structure itself.
  316.      * 2.   Set a flag to indicate that Release has been called.
  317.      * 3.   NULL any saved LPOLECLIENT stores in the OLEOBJECT structure.
  318.      * 4.   Return OLE_OK if successful, OLE_ERROR_GENERIC otherwise.
  319.      *
  320.      * Do not use the Release method to free the memory containing
  321.      * the object since you still need to use its pClient and fRelease.
  322.      * This method simply notifies the object that no one is using it
  323.      * anymore so we don't try to send notifications.
  324.      */
  325.  
  326.     pObj->fRelease=TRUE;
  327.     pObj->pClient=NULL;
  328.     return OLE_OK;
  329.     }
  330.  
  331.  
  332.  
  333.  
  334.  
  335. /*
  336.  * ObjSetBounds
  337.  *
  338.  * Purpose:
  339.  *  Specifies a new boundary rectangle for the object in MM_HIMETRIC
  340.  *  units.  Only useful for embedded objects since a linked object
  341.  *  depends on the file loaded.
  342.  *
  343.  * Parameters:
  344.  *  pObj            LPCOSMOOBJECT specifying the object affected.
  345.  *  pRect           LPRECT containing the new bounds.
  346.  *
  347.  * Return Value:
  348.  *  OLESTATUS       OLE_OK if all is well, otherwise an OLE_* error value.
  349.  */
  350.  
  351. OLESTATUS WINAPI ObjSetBounds(LPCOSMOOBJECT pObj, OLE_CONST RECT FAR *pRect)
  352.     {
  353.     //Unused in OLE1.x
  354.     return OLE_OK;
  355.     }
  356.  
  357.  
  358.  
  359.  
  360. /*
  361.  * ObjSetColorScheme
  362.  *
  363.  * Purpose:
  364.  *  Provides a color scheme that the client application recommends for
  365.  *  rendering graphical data.
  366.  *
  367.  * Parameters:
  368.  *  pDoc            LPCOSMOOBJECT specifying the object affected.
  369.  *  pPal            LPLOGPALETTE describing the recommended palette.
  370.  *
  371.  * Return Value:
  372.  *  OLESTATUS       OLE_OK if all is well, otherwise an OLE_* error value.
  373.  */
  374.  
  375. OLESTATUS WINAPI ObjSetColorScheme(LPCOSMOOBJECT pObj
  376.     , OLE_CONST LOGPALETTE FAR *pPal)
  377.     {
  378.     /*
  379.      * Servers are not required to use this palette.  The LPLOGPALETTE
  380.      * only is a convenient structure to contain the color scheme; IT DOES
  381.      * not REPRESENT A PALETTE IN STRICT TERMS!  Do NOT call CreatePalette
  382.      * and try to realize it.
  383.      *
  384.      * The color scheme contained in the LOGPALETTE structure contains
  385.      * a number of colors where the first color is the suggested foreground,
  386.      * the second the suggested background, then the first HALF of those
  387.      * remaining are suggested fill colors and the last half suggested
  388.      * line colors.  If there are an odd number of colors, give the extra
  389.      * color to the fill colors, that is, there is one less line color than
  390.      * fill colors.
  391.      */
  392.  
  393.     return OLE_ERROR_PALETTE;
  394.     }
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  
  401. /*
  402.  * ObjSetData
  403.  *
  404.  * Purpose:
  405.  *  Instructs the object to take the given data as current and copy it
  406.  *  to the object's internal data, use when a client opens an embedded
  407.  *  object or if the client calls OleSetData.
  408.  *
  409.  *  *NOTE: This function MUST be supported even if the registration
  410.  *         database does not contain an entry for SetDataFormats for
  411.  *         this server, because the callback is still used when opening
  412.  *         an embedded object for editing.
  413.  *
  414.  * Parameters:
  415.  *  pObj            LPCOSMOOBJECT specifying the object affected.
  416.  *  cf              OLECLIPFORMAT format to return data in, may be "Native."
  417.  *  hData           HGLOBAL to memory containing the data.
  418.  *
  419.  * Return Value:
  420.  *  OLESTATUS       OLE_OK if all is well, otherwise an OLE_* error value.
  421.  */
  422.  
  423. OLESTATUS WINAPI ObjSetData(LPCOSMOOBJECT pObj, OLECLIPFORMAT cf
  424.     , HGLOBAL hData)
  425.     {
  426.     LPPOLYLINE          lppl;
  427.  
  428.     /*
  429.      * 1.   If the data format is not supported, return OLE_ERROR_FORMAT.
  430.      * 2.   Attempt to GlobalLock the memory to get a pointer to the data.
  431.      *      If GlobalLock returns NULL, return OLE_ERROR_MEMORY.
  432.      * 3.   Copy the data to the object identified by pObj.
  433.      * 4.   Unlock and GlobalFree the data handle.  The ObjSetData method
  434.      *      is responsible for the memory.
  435.      * 5.   Return OLE_OK.
  436.      */
  437.  
  438.     //Check if we were given Native data.  We don't support anything else.
  439.     if (pOLE->cfNative!=cf)
  440.         return OLE_ERROR_FORMAT;
  441.  
  442.     lppl=(LPPOLYLINE)GlobalLock(hData);
  443.  
  444.     /*
  445.      * CHECK the return from GlobalLock since we don't know where this
  446.      * handle has been.
  447.      */
  448.     if (NULL==lppl)
  449.         return OLE_ERROR_MEMORY;
  450.  
  451.     //Set the data through the editing window.
  452.     SendMessage(pGlob->hWndPolyline, PLM_POLYLINESET, TRUE, (LONG)lppl);
  453.  
  454.     //Make sure we are not dirty--no updating is yet necessary.
  455.     FDirtySet(FALSE);
  456.  
  457.     //Server is responsible for freeing the data.
  458.     GlobalUnlock(hData);
  459.     GlobalFree(hData);
  460.     return OLE_OK;
  461.     }
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468. /*
  469.  * ObjSetTargetDevice
  470.  *
  471.  * Purpose:
  472.  *  Communicates information from the client application to the server
  473.  *  about the device on which the object is drawn.
  474.  *
  475.  * Parameters:
  476.  *  pObj            LPCOSMOOBJECT specifying the object affected.
  477.  *  hData           HGLOBAL containing a STDTARGETDEVICE structure.
  478.  *
  479.  * Return Value:
  480.  *  OLESTATUS       OLE_OK if all is well, otherwise an OLE_* error value.
  481.  */
  482.  
  483. OLESTATUS WINAPI ObjSetTargetDevice(LPCOSMOOBJECT pObj, HGLOBAL hData)
  484.     {
  485.  
  486.     /*
  487.      * The server is responsible for freeing the the data handle
  488.      * once it has finished using that data.
  489.      *
  490.      * If NULL==hData, then rendering is necessary for the screen.
  491.      */
  492.  
  493.     if (NULL!=hData)
  494.         GlobalFree(hData);
  495.  
  496.     return OLE_OK;
  497.     }
  498.  
  499.  
  500.  
  501.  
  502.  
  503.  
  504.  
  505. /*
  506.  * ObjShow
  507.  *
  508.  * Purpose:
  509.  *  Causes the server to show an object, showing the window and
  510.  *  scrolling it's client area if necessary.
  511.  *
  512.  * Parameters:
  513.  *  pObj            LPCOSMOOBJECT specifying the object affected.
  514.  *  fTakeFocus      BOOL:  TRUE if the server should get the focus,
  515.  *                  FALSE if not.
  516.  *
  517.  * Return Value:
  518.  *  OLESTATUS       OLE_OK if all is well, otherwise an OLE_* error value.
  519.  */
  520.  
  521. OLESTATUS WINAPI ObjShow(LPCOSMOOBJECT pObj, BOOL fTakeFocus)
  522.     {
  523.     /*
  524.      * 1.   Show the application window(s) if not already visible.
  525.      * 2.   Scroll the object identified by pObj into view, if necessary.
  526.      * 3.   Select the object if possible.
  527.      * 4.   If fTakeFocus is TRUE, call SetFocus with the main window handle.
  528.      * 5.   Return OLE_OK if successful, OLE_ERROR_GENERIC otherwise.
  529.      */
  530.  
  531.     //Keep WM_SIZE on the ShowWindow from making us dirty.
  532.     pGlob->fNoDirty=TRUE;
  533.  
  534.     //Since we only have one object, we don't care what's in pObj.
  535.     ShowWindow(pGlob->hWnd, SW_NORMAL);
  536.  
  537.     pGlob->fNoDirty=FALSE;
  538.  
  539.     if (fTakeFocus)
  540.         SetFocus(pGlob->hWnd);
  541.  
  542.     return OLE_OK;
  543.     }
  544.  
  545.  
  546. #endif //MAKEOLESERVER
  547.