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 / chap24 / polyline / ioleobj.cpp < prev    next >
C/C++ Source or Header  |  1996-05-22  |  18KB  |  713 lines

  1. /*
  2.  * IOLEOBJ.CPP
  3.  * Polyline Component Chapter 24
  4.  *
  5.  * Implementation of the IOleObject interface for Polyline.  Some of
  6.  * these just pass through to the default handler which does default
  7.  * implementations.
  8.  *
  9.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  10.  *
  11.  * Kraig Brockschmidt, Microsoft
  12.  * Internet  :  kraigb@microsoft.com
  13.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  14.  */
  15.  
  16.  
  17. #include "polyline.h"
  18.  
  19.  
  20. /*
  21.  * CImpIOleObject::CImpIOleObject
  22.  * CImpIOleObject::~CImpIOleObject
  23.  *
  24.  * Parameters (Constructor):
  25.  *  pObj            PCPolyline of the object we're in.
  26.  *  pUnkOuter       LPUNKNOWN to which we delegate.
  27.  */
  28.  
  29. CImpIOleObject::CImpIOleObject(PCPolyline pObj
  30.     , LPUNKNOWN pUnkOuter)
  31.     {
  32.     m_cRef=0;
  33.     m_pObj=pObj;
  34.     m_pUnkOuter=pUnkOuter;
  35.     return;
  36.     }
  37.  
  38. CImpIOleObject::~CImpIOleObject(void)
  39.     {
  40.     return;
  41.     }
  42.  
  43.  
  44.  
  45. /*
  46.  * CImpIOleObject::QueryInterface
  47.  * CImpIOleObject::AddRef
  48.  * CImpIOleObject::Release
  49.  *
  50.  * Purpose:
  51.  *  IUnknown members for CImpIOleObject object.
  52.  */
  53.  
  54. STDMETHODIMP CImpIOleObject::QueryInterface(REFIID riid, PPVOID ppv)
  55.     {
  56.     return m_pUnkOuter->QueryInterface(riid, ppv);
  57.     }
  58.  
  59.  
  60. STDMETHODIMP_(ULONG) CImpIOleObject::AddRef(void)
  61.     {
  62.     ++m_cRef;
  63.     return m_pUnkOuter->AddRef();
  64.     }
  65.  
  66. STDMETHODIMP_(ULONG) CImpIOleObject::Release(void)
  67.     {
  68.     --m_cRef;
  69.     return m_pUnkOuter->Release();
  70.     }
  71.  
  72.  
  73.  
  74.  
  75.  
  76. /*
  77.  * CImpIOleObject::SetClientSite
  78.  * CImpIOleObject::GetClientSite
  79.  *
  80.  * Purpose:
  81.  *  Manages the IOleClientSite pointer of our container.
  82.  */
  83.  
  84. STDMETHODIMP CImpIOleObject::SetClientSite
  85.     (LPOLECLIENTSITE pIOleClientSite)
  86.     {
  87.     if (NULL!=m_pObj->m_pIOleClientSite)
  88.         m_pObj->m_pIOleClientSite->Release();
  89.  
  90.     m_pObj->m_pIOleClientSite=pIOleClientSite;
  91.  
  92.     if (NULL!=m_pObj->m_pIOleClientSite)
  93.         {
  94.         HRESULT         hr;
  95.         LPMONIKER       pmk;
  96.         LPOLECONTAINER  pIOleCont;
  97.  
  98.         m_pObj->m_pIOleClientSite->AddRef();
  99.  
  100.         /*
  101.          * Within IRunnableObject::Run we're supposed to register
  102.          * ourselves as running...however, the moniker has to come
  103.          * from the container's IOleClientSite::GetMoniker.  But
  104.          * Run is called before SetClientSite here, so we have to
  105.          * register now that we do have the client site as well
  106.          * as lock the container.
  107.          */
  108.  
  109.         hr=m_pObj->m_pIOleClientSite->GetMoniker
  110.             (OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_OBJFULL, &pmk);
  111.  
  112.         if (SUCCEEDED(hr))
  113.             {
  114.             INOLE_RegisterAsRunning(this, pmk, 0
  115.                 , &m_pObj->m_dwRegROT);
  116.             pmk->Release();
  117.             }
  118.  
  119.         hr=m_pObj->m_pIOleClientSite->GetContainer(&pIOleCont);
  120.  
  121.         if (SUCCEEDED(hr))
  122.             {
  123.             m_pObj->m_fLockContainer=TRUE;
  124.             pIOleCont->LockContainer(TRUE);
  125.             pIOleCont->Release();
  126.             }
  127.  
  128.         //CHAPTER24MOD
  129.         /*
  130.          * Go get the container's IDispatch for ambient
  131.          * properties if it has one, and initilize ourself
  132.          * with those properties.
  133.          */
  134.         hr=m_pObj->m_pIOleClientSite->QueryInterface(IID_IDispatch
  135.             , (void **)&m_pObj->m_pIDispatchAmbients);
  136.  
  137.         if (SUCCEEDED(hr))
  138.             m_pObj->AmbientsInitialize(INITAMBIENT_ALL);
  139.         //End CHAPTER24MOD
  140.         }
  141.  
  142.     return NOERROR;
  143.     }
  144.  
  145. STDMETHODIMP CImpIOleObject::GetClientSite(LPOLECLIENTSITE *ppSite)
  146.     {
  147.     //Be sure to AddRef the new pointer you are giving away.
  148.     *ppSite=m_pObj->m_pIOleClientSite;
  149.     m_pObj->m_pIOleClientSite->AddRef();
  150.  
  151.     return NOERROR;
  152.     }
  153.  
  154.  
  155.  
  156.  
  157.  
  158. /*
  159.  * CImpIOleObject::SetHostNames
  160.  *
  161.  * Purpose:
  162.  *  Provides the object with names of the container application and
  163.  *  the object in the container to use in object user interface.
  164.  *
  165.  * Parameters:
  166.  *  pszApp          LPCOLESTR of the container application.
  167.  *  pszObj          LPCOLESTR of some name that is useful in window
  168.  *                  titles.
  169.  *
  170.  * Return Value:
  171.  *  HRESULT         NOERROR
  172.  */
  173.  
  174. STDMETHODIMP CImpIOleObject::SetHostNames(LPCOLESTR pszApp
  175.     , LPCOLESTR pszObj)
  176.     {
  177.     if (NULL!=m_pObj->m_hDlg)
  178.         {
  179.         TCHAR       szTemp[128];
  180.  
  181.        #ifdef WIN32ANSI
  182.         char        szObj[80];
  183.         WideCharToMultiByte(CP_ACP, 0, pszObj, -1, szObj, 80
  184.             , NULL, NULL);
  185.         wsprintf(szTemp, SZPOLYFRAMETITLE, szObj);
  186.        #else
  187.         wsprintf(szTemp, SZPOLYFRAMETITLE, pszObj);
  188.        #endif
  189.         SetWindowText(m_pObj->m_hDlg, szTemp);
  190.         }
  191.  
  192.     return NOERROR;
  193.     }
  194.  
  195.  
  196.  
  197.  
  198.  
  199. /*
  200.  * CImpIOleObject::Close
  201.  *
  202.  * Purpose:
  203.  *  Forces the object to close down its user interface and unload.
  204.  *
  205.  * Parameters:
  206.  *  dwSaveOption    DWORD describing the circumstances under which
  207.  *                  the object is being saved and closed.
  208.  *
  209.  * Return Value:
  210.  *  HRESULT         NOERROR or a general error value.
  211.  */
  212.  
  213. STDMETHODIMP CImpIOleObject::Close(DWORD dwSaveOption)
  214.     {
  215.     HWND        hWnd;
  216.     BOOL        fSave=FALSE;
  217.  
  218.     hWnd=m_pObj->m_hDlg;
  219.  
  220.     //If object is dirty and we're asked to save, save it and close.
  221.     if (OLECLOSE_SAVEIFDIRTY==dwSaveOption && m_pObj->m_fDirty)
  222.         fSave=TRUE;
  223.  
  224.     /*
  225.      * If asked to prompt, only do so if dirty, then if we get a
  226.      * YES, save as usual and close.  On NO, just close.  On
  227.      * CANCEL return OLE_E_PROMPTSAVECANCELLED.
  228.      */
  229.     if (OLECLOSE_PROMPTSAVE==dwSaveOption && m_pObj->m_fDirty)
  230.         {
  231.         TCHAR       szTitle[20];
  232.         TCHAR       szTemp[80];
  233.         UINT        uRet;
  234.  
  235.         lstrcpy(szTitle, m_pObj->String(IDS_CLOSECAPTION));
  236.         lstrcpy(szTemp, m_pObj->String(IDS_CLOSEPROMPT));
  237.  
  238.         uRet=MessageBox(hWnd, szTemp, szTitle, MB_YESNOCANCEL);
  239.  
  240.         if (IDCANCEL==uRet)
  241.             return ResultFromScode(OLE_E_PROMPTSAVECANCELLED);
  242.  
  243.         if (IDYES==uRet)
  244.             fSave=TRUE;
  245.         }
  246.  
  247.     if (fSave)
  248.         {
  249.         m_pObj->SendAdvise(OBJECTCODE_SAVEOBJECT);
  250.         m_pObj->SendAdvise(OBJECTCODE_SAVED);
  251.         }
  252.  
  253.     //We get directly here on OLECLOSE_NOSAVE.
  254.     if (m_pObj->m_fLockContainer)
  255.         {
  256.         //Match LockContainer call from SetClientSite
  257.         LPOLECONTAINER  pIOleCont;
  258.  
  259.         if (SUCCEEDED(m_pObj->m_pIOleClientSite
  260.             ->GetContainer(&pIOleCont)))
  261.             {
  262.             pIOleCont->LockContainer(FALSE);
  263.             pIOleCont->Release();
  264.             }
  265.         }
  266.  
  267.     if (NULL!=hWnd)
  268.         {
  269.         //This hides the window and sends the appropriate notify.
  270.         DoVerb(OLEIVERB_HIDE, NULL, NULL, -1, NULL, NULL);
  271.  
  272.         m_pObj->SendAdvise(OBJECTCODE_CLOSED);
  273.         PostMessage(hWnd, POLYM_CLOSE, 0, 0L);
  274.         }
  275.  
  276.     return NOERROR;
  277.     }
  278.  
  279.  
  280.  
  281.  
  282. /*
  283.  * CImpIOleObject::DoVerb
  284.  *
  285.  * Purpose:
  286.  *  Executes an object-defined action.
  287.  *
  288.  * Parameters:
  289.  *  iVerb           LONG index of the verb to execute.
  290.  *  pMSG            LPMSG describing the event causing the
  291.  *                  activation.
  292.  *  pActiveSite     LPOLECLIENTSITE to the site involved.
  293.  *  lIndex          LONG the piece on which execution is happening.
  294.  *  hWndParent      HWND of the window in which the object can play
  295.  *                  in-place.
  296.  *  pRectPos        LPRECT of the object in hWndParent where the
  297.  *                  object can play in-place if desired.
  298.  *
  299.  * Return Value:
  300.  *  HRESULT         NOERROR or a general error value.
  301.  */
  302.  
  303. STDMETHODIMP CImpIOleObject::DoVerb(LONG iVerb, LPMSG pMSG
  304.     , LPOLECLIENTSITE pActiveSite, LONG lIndex, HWND hWndParent
  305.     , LPCRECT pRectPos)
  306.     {
  307.     HRESULT     hr;
  308.     //CHAPTER24MOD
  309.     CAUUID      caGUID;
  310.     //End CHAPTER24MOD
  311.  
  312.     switch (iVerb)
  313.         {
  314.         case OLEIVERB_HIDE:
  315.             if (NULL!=m_pObj->m_pIOleIPSite)
  316.                 {
  317.                 if (NULL!=m_pObj->m_pHW)
  318.                     ShowWindow(m_pObj->m_pHW->Window(), SW_HIDE);
  319.                 }
  320.             else
  321.                 {
  322.                 if (NULL!=m_pObj->m_hDlg)
  323.                     ShowWindow(m_pObj->m_hDlg, SW_HIDE);
  324.                 }
  325.  
  326.             m_pObj->SendAdvise(OBJECTCODE_HIDEWINDOW);
  327.             m_pObj->m_fAllowInPlace=TRUE;
  328.             break;
  329.  
  330.         case OLEIVERB_PRIMARY:
  331.         case OLEIVERB_SHOW:
  332.             if (NULL!=m_pObj->m_pIOleIPSite)
  333.                 {
  334.                 if (NULL!=m_pObj->m_pHW)
  335.                     ShowWindow(m_pObj->m_pHW->Window(), SW_HIDE);
  336.  
  337.                 return NOERROR; //Already active
  338.                 }
  339.  
  340.             if (m_pObj->m_fAllowInPlace)
  341.                 {
  342.                 if (SUCCEEDED(m_pObj->InPlaceActivate(pActiveSite
  343.                     , TRUE)))
  344.                     return NOERROR;
  345.                 }
  346.             //FALL THROUGH
  347.  
  348.         case OLEIVERB_OPEN:
  349.             if (NULL!=m_pObj->m_pIOleIPSite)
  350.                 {
  351.                 m_pObj->InPlaceDeactivate();
  352.                 m_pObj->m_fAllowInPlace=FALSE;
  353.                 }
  354.  
  355.             /*
  356.              * If we're not running, make sure we are.  In any
  357.              * case, make the dialog visible and insure it has
  358.              * the right parent now.
  359.              */
  360.             hr=NOERROR;
  361.             if (NULL==m_pObj->m_hDlg)
  362.                 hr=m_pObj->m_pImpIRunnableObject->Run(NULL);
  363.  
  364.             if (FAILED(hr) || NULL==m_pObj->m_hDlg)
  365.                 return ResultFromScode(E_OUTOFMEMORY);
  366.  
  367.             ShowWindow(m_pObj->m_hDlg, SW_SHOW);
  368.             SetFocus(m_pObj->m_hDlg);
  369.             m_pObj->SendAdvise(OBJECTCODE_SHOWOBJECT);
  370.             m_pObj->SendAdvise(OBJECTCODE_SHOWWINDOW);
  371.  
  372.             break;
  373.  
  374.         case OLEIVERB_INPLACEACTIVATE:
  375.             if (NULL!=m_pObj->m_pHW)
  376.                 {
  377.                 HWND    hWndHW=m_pObj->m_pHW->Window();
  378.  
  379.                 ShowWindow(hWndHW, SW_SHOW);
  380.                 SetFocus(hWndHW);
  381.  
  382.                 return NOERROR;
  383.                 }
  384.  
  385.             /*
  386.              * Only inside-out supporting containers will use
  387.              * this verb.
  388.              */
  389.             m_pObj->m_fContainerKnowsInsideOut=TRUE;
  390.             m_pObj->InPlaceActivate(pActiveSite, FALSE);
  391.             break;
  392.  
  393.         case OLEIVERB_UIACTIVATE:
  394.             m_pObj->InPlaceActivate(pActiveSite, TRUE);
  395.             break;
  396.  
  397.         //CHAPTER24MOD
  398.         case OLEIVERB_PROPERTIES:
  399.         case POLYLINEVERB_PROPERTIES:
  400.             /*
  401.              * Let the container try first if there are
  402.              * extended controls.  Otherwise we'll display
  403.              * our own pages.
  404.              */
  405.             if (NULL!=m_pObj->m_pIOleControlSite)
  406.                 {
  407.                 hr=m_pObj->m_pIOleControlSite->ShowPropertyFrame();
  408.  
  409.                 if (NOERROR==hr)
  410.                     break;      //All done
  411.                 }
  412.  
  413.  
  414.             //Put up our property pages.
  415.             hr=m_pObj->m_pImpISpecifyPP->GetPages(&caGUID);
  416.  
  417.             if (FAILED(hr))
  418.                 return FALSE;
  419.  
  420.             hr=OleCreatePropertyFrame(m_pObj->m_hWnd, 10, 10
  421.                 , OLETEXT("Polyline"), 1, (IUnknown **)&m_pObj
  422.                 , caGUID.cElems, caGUID.pElems
  423.                 , LANG_NEUTRAL, 0L, NULL);
  424.  
  425.             //Free the GUIDs
  426.             CoTaskMemFree((void *)caGUID.pElems);
  427.             break;
  428.             //End CHAPTER24MOD
  429.  
  430.         default:
  431.             return ResultFromScode(OLEOBJ_S_INVALIDVERB);
  432.         }
  433.  
  434.     return NOERROR;
  435.     }
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  
  442. /*
  443.  * CImpIOleObject::GetUserClassID
  444.  *
  445.  * Purpose:
  446.  *  Used for linked objects, this returns the class ID of what end
  447.  *  users think they are editing.
  448.  *
  449.  * Parameters:
  450.  *  pClsID          LPCLSID in which to store the CLSID.
  451.  *
  452.  * Return Value:
  453.  *  HRESULT         NOERROR or a general error value.
  454.  */
  455.  
  456. STDMETHODIMP CImpIOleObject::GetUserClassID(LPCLSID pClsID)
  457.     {
  458.     /*
  459.      * If you are not registered to handle data other than yourself,
  460.      * then you can just return your class ID here.  If you are
  461.      * registered as usable from Treat-As dialogs, then you need to
  462.      * return the CLSID of what you are really editing.
  463.      */
  464.  
  465.     *pClsID=CLSID_Polyline19;
  466.     return NOERROR;
  467.     }
  468.  
  469.  
  470.  
  471.  
  472.  
  473. /*
  474.  * CImpIOleObject::SetExtent
  475.  *
  476.  * Purpose:
  477.  *  Sets the size of the object in HIMETRIC units.  Since we're in
  478.  *  a dialog, the size of the object in us is fixed, so we ignore
  479.  *  this call.
  480.  *
  481.  * Parameters:
  482.  *  dwAspect        DWORD of the aspect affected.
  483.  *  pszl            LPSIZEL containing the new size.
  484.  *
  485.  * Return Value:
  486.  *  HRESULT         NOERROR or a general error value.
  487.  */
  488.  
  489. STDMETHODIMP CImpIOleObject::SetExtent(DWORD dwAspect
  490.     , LPSIZEL pszl)
  491.     {
  492.     //Ignored:  no size change in the dialog.
  493.     return NOERROR;
  494.     }
  495.  
  496.  
  497.  
  498.  
  499.  
  500. /*
  501.  * CImpIOleObject::GetExtent
  502.  *
  503.  * Purpose:
  504.  *  Retrieves the size of the object in HIMETRIC units.
  505.  *
  506.  * Parameters:
  507.  *  dwAspect        DWORD of the aspect requested
  508.  *  pszl            LPSIZEL into which to store the size.
  509.  *
  510.  * Return Value:
  511.  *  HRESULT         NOERROR or a general error value.
  512.  */
  513.  
  514. STDMETHODIMP CImpIOleObject::GetExtent(DWORD dwAspect, LPSIZEL pszl)
  515.     {
  516.     //Delegate directly to IViewObject2::GetExtent
  517.     return m_pObj->m_pImpIViewObject->GetExtent(dwAspect, -1
  518.         , NULL, pszl);
  519.     }
  520.  
  521.  
  522.  
  523.  
  524.  
  525. /*
  526.  * CImpIOleObject::Advise
  527.  * CImpIOleObject::Unadvise
  528.  * CImpIOleObject::EnumAdvise
  529.  *
  530.  * Purpose:
  531.  *  Advisory connection functions.
  532.  */
  533.  
  534. STDMETHODIMP CImpIOleObject::Advise(LPADVISESINK pIAdviseSink
  535.     , LPDWORD pdwConn)
  536.     {
  537.     if (NULL==m_pObj->m_pIOleAdviseHolder)
  538.         {
  539.         HRESULT     hr;
  540.  
  541.         hr=CreateOleAdviseHolder(&m_pObj->m_pIOleAdviseHolder);
  542.  
  543.         if (FAILED(hr))
  544.             return hr;
  545.         }
  546.  
  547.     return m_pObj->m_pIOleAdviseHolder->Advise(pIAdviseSink
  548.         , pdwConn);
  549.     }
  550.  
  551.  
  552. STDMETHODIMP CImpIOleObject::Unadvise(DWORD dwConn)
  553.     {
  554.     if (NULL!=m_pObj->m_pIOleAdviseHolder)
  555.         return m_pObj->m_pIOleAdviseHolder->Unadvise(dwConn);
  556.  
  557.     return ResultFromScode(E_FAIL);
  558.     }
  559.  
  560.  
  561. STDMETHODIMP CImpIOleObject::EnumAdvise(LPENUMSTATDATA *ppEnum)
  562.     {
  563.     if (NULL!=m_pObj->m_pIOleAdviseHolder)
  564.         return m_pObj->m_pIOleAdviseHolder->EnumAdvise(ppEnum);
  565.  
  566.     return ResultFromScode(E_FAIL);
  567.     }
  568.  
  569.  
  570.  
  571. /*
  572.  * CImpIOleObject::SetMoniker
  573.  *
  574.  * Purpose:
  575.  *  Informs the object of its moniker or its container's moniker
  576.  *  depending on dwWhich.
  577.  *
  578.  * Parameters:
  579.  *  dwWhich         DWORD describing whether the moniker is the
  580.  *                  object's or the container's.
  581.  *  pmk             LPMONIKER with the name.
  582.  *
  583.  * Return Value:
  584.  *  HRESULT         NOERROR or a general error value.
  585.  */
  586.  
  587. STDMETHODIMP CImpIOleObject::SetMoniker(DWORD dwWhich
  588.     , LPMONIKER pmk)
  589.     {
  590.     LPMONIKER       pmkFull;
  591.     HRESULT         hr=ResultFromScode(E_FAIL);
  592.  
  593.     if (NULL!=m_pObj->m_pIOleClientSite)
  594.         {
  595.         hr=m_pObj->m_pIOleClientSite->GetMoniker
  596.             (OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_OBJFULL
  597.             , &pmkFull);
  598.         }
  599.  
  600.     if (SUCCEEDED(hr))
  601.         {
  602.         if (NOERROR==pmkFull->IsRunning(NULL, NULL, NULL))
  603.             {
  604.             pmkFull->Release();
  605.             return NOERROR;
  606.             }
  607.  
  608.         //This will revoke the old one if m_dwRegROT is nonzero.
  609.         INOLE_RegisterAsRunning(m_pObj, pmkFull, 0
  610.             , &m_pObj->m_dwRegROT);
  611.  
  612.         //Inform clients of the new moniker
  613.         if (NULL!=m_pObj->m_pIOleAdviseHolder)
  614.             m_pObj->m_pIOleAdviseHolder->SendOnRename(pmkFull);
  615.  
  616.         pmkFull->Release();
  617.         }
  618.  
  619.     return hr;
  620.     }
  621.  
  622.  
  623.  
  624. /*
  625.  * CImpIOleObject::GetMoniker
  626.  *
  627.  * Purpose:
  628.  *  Asks the object for a moniker that can later be used to
  629.  *  reconnect to it.
  630.  *
  631.  * Parameters:
  632.  *  dwAssign        DWORD determining how to assign the moniker to
  633.  *                  to the object.
  634.  *  dwWhich         DWORD describing which moniker the caller wants.
  635.  *  ppmk            LPMONIKER * into which to store the moniker.
  636.  *
  637.  * Return Value:
  638.  *  HRESULT         NOERROR or a general error value.
  639.  */
  640.  
  641. STDMETHODIMP CImpIOleObject::GetMoniker(DWORD dwAssign
  642.     , DWORD dwWhich, LPMONIKER *ppmk)
  643.     {
  644.     HRESULT         hr=ResultFromScode(E_FAIL);
  645.  
  646.     *ppmk=NULL;
  647.  
  648.     /*
  649.      * Since we only support embedded objects, our moniker
  650.      * is always the full moniker from the contianer.
  651.      */
  652.  
  653.     if (NULL!=m_pObj->m_pIOleClientSite)
  654.         {
  655.         hr=m_pObj->m_pIOleClientSite->GetMoniker
  656.             (OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_OBJFULL, ppmk);
  657.         }
  658.  
  659.     return (NULL!=*ppmk) ? NOERROR : hr;
  660.     }
  661.  
  662.  
  663.  
  664. //Methods not implemented or trivial
  665. STDMETHODIMP CImpIOleObject::InitFromData(LPDATAOBJECT pIDataObject
  666.     , BOOL fCreation, DWORD dw)
  667.     {
  668.     return ResultFromScode(E_NOTIMPL);
  669.     }
  670.  
  671. STDMETHODIMP CImpIOleObject::GetClipboardData(DWORD dwReserved
  672.     , LPDATAOBJECT *ppIDataObj)
  673.     {
  674.     return ResultFromScode(E_NOTIMPL);
  675.     }
  676.  
  677. STDMETHODIMP CImpIOleObject::Update(void)
  678.     {
  679.     return NOERROR;
  680.     }
  681.  
  682. STDMETHODIMP CImpIOleObject::IsUpToDate(void)
  683.     {
  684.     return NOERROR;
  685.     }
  686.  
  687. STDMETHODIMP CImpIOleObject::SetColorScheme(LPLOGPALETTE pLP)
  688.     {
  689.     return ResultFromScode(E_NOTIMPL);
  690.     }
  691.  
  692.  
  693.  
  694. //Methods implemented using registry helper functions in OLE.
  695.  
  696. STDMETHODIMP CImpIOleObject::EnumVerbs(LPENUMOLEVERB *ppEnum)
  697.     {
  698.     return OleRegEnumVerbs(m_pObj->m_clsID, ppEnum);
  699.     }
  700.  
  701. STDMETHODIMP CImpIOleObject::GetUserType(DWORD dwForm
  702.     , LPOLESTR *ppszType)
  703.     {
  704.     return OleRegGetUserType(m_pObj->m_clsID, dwForm, ppszType);
  705.     }
  706.  
  707. STDMETHODIMP CImpIOleObject::GetMiscStatus(DWORD dwAspect
  708.     , LPDWORD pdwStatus)
  709.     {
  710.     return OleRegGetMiscStatus(m_pObj->m_clsID, dwAspect
  711.         , pdwStatus);
  712.     }
  713.