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 / cosmo / ioleobj.cpp < prev    next >
C/C++ Source or Header  |  1995-05-03  |  17KB  |  758 lines

  1. /*
  2.  * IOLEOBJ.CPP
  3.  * Cosmo Chapter 18
  4.  *
  5.  * Implementation of the IOleObject interface for Polyline.
  6.  *
  7.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  8.  *
  9.  * Kraig Brockschmidt, Microsoft
  10.  * Internet  :  kraigb@microsoft.com
  11.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  12.  */
  13.  
  14.  
  15. #include "cosmo.h"
  16.  
  17.  
  18. /*
  19.  * CImpIOleObject::CImpIOleObject
  20.  * CImpIOleObject::~CImpIOleObject
  21.  *
  22.  * Parameters (Constructor):
  23.  *  pObj            PCFigure of the object we're in.
  24.  *  pUnkOuter       LPUNKNOWN to which we delegate.
  25.  */
  26.  
  27. CImpIOleObject::CImpIOleObject(PCFigure pObj, LPUNKNOWN pUnkOuter)
  28.     {
  29.     m_cRef=0;
  30.     m_pObj=pObj;
  31.     m_pUnkOuter=pUnkOuter;
  32.     return;
  33.     }
  34.  
  35. CImpIOleObject::~CImpIOleObject(void)
  36.     {
  37.     return;
  38.     }
  39.  
  40.  
  41.  
  42. /*
  43.  * CImpIOleObject::QueryInterface
  44.  * CImpIOleObject::AddRef
  45.  * CImpIOleObject::Release
  46.  */
  47.  
  48. STDMETHODIMP CImpIOleObject::QueryInterface(REFIID riid, PPVOID ppv)
  49.     {
  50.     return m_pUnkOuter->QueryInterface(riid, ppv);
  51.     }
  52.  
  53. STDMETHODIMP_(ULONG) CImpIOleObject::AddRef(void)
  54.     {
  55.     ++m_cRef;
  56.     return m_pUnkOuter->AddRef();
  57.     }
  58.  
  59. STDMETHODIMP_(ULONG) CImpIOleObject::Release(void)
  60.     {
  61.     --m_cRef;
  62.     return m_pUnkOuter->Release();
  63.     }
  64.  
  65.  
  66.  
  67.  
  68.  
  69. /*
  70.  * CImpIOleObject::SetClientSite
  71.  *
  72.  * Purpose:
  73.  *  Provides the object with a pointer to the IOleClient site
  74.  *  representing the container in which this object resides.
  75.  *
  76.  * Parameters:
  77.  *  pIOleClientSite LPOLECLIENTSITE to the container's interface.
  78.  *
  79.  * Return Value:
  80.  *  HRESULT         NOERROR
  81.  */
  82.  
  83. STDMETHODIMP CImpIOleObject::SetClientSite
  84.     (LPOLECLIENTSITE pIOleClientSite)
  85.     {
  86.     if (NULL!=m_pObj->m_pIOleClientSite)
  87.         m_pObj->m_pIOleClientSite->Release();
  88.  
  89.     m_pObj->m_pIOleClientSite=pIOleClientSite;
  90.     m_pObj->m_pIOleClientSite->AddRef();
  91.     return NOERROR;
  92.     }
  93.  
  94.  
  95.  
  96.  
  97.  
  98. /*
  99.  * CImpIOleObject::GetClientSite
  100.  *
  101.  * Purpose:
  102.  *  Asks the object for the client site provided in SetClientSite.
  103.  *  If you have not seen SetClientSite yet, return a NULL in
  104.  *  ppIOleClientSite.
  105.  *
  106.  * Parameters:
  107.  *  ppSite          LPOLECLIENTSITE * in which to store the
  108.  *                  pointer.
  109.  *
  110.  * Return Value:
  111.  *  HRESULT         NOERROR
  112.  */
  113.  
  114. STDMETHODIMP CImpIOleObject::GetClientSite(LPOLECLIENTSITE
  115.     *ppSite)
  116.     {
  117.     //Be sure to AddRef the new pointer you are giving away.
  118.     *ppSite=m_pObj->m_pIOleClientSite;
  119.     m_pObj->m_pIOleClientSite->AddRef();
  120.  
  121.     return NOERROR;
  122.     }
  123.  
  124.  
  125.  
  126.  
  127.  
  128. /*
  129.  * CImpIOleObject::SetHostNames
  130.  *
  131.  * Purpose:
  132.  *  Provides the object with names of the container application and
  133.  *  the object in the container to use in object user interface.
  134.  *
  135.  * Parameters:
  136.  *  pszApp          LPCOLESTR of the container application.
  137.  *  pszObj          LPCOLESTR of some name useful in window titles.
  138.  *
  139.  * Return Value:
  140.  *  HRESULT         NOERROR
  141.  */
  142.  
  143. STDMETHODIMP CImpIOleObject::SetHostNames(LPCOLESTR pszApp
  144.     , LPCOLESTR pszObj)
  145.     {
  146.     m_pObj->m_fEmbedded=TRUE;
  147.    #ifdef WIN32ANSI
  148.     char        szApp[80], szObj[80];
  149.  
  150.     szApp[0]=0;
  151.     szObj[0]=0;
  152.  
  153.     if (NULL!=pszApp)
  154.         {
  155.         WideCharToMultiByte(CP_ACP, 0, pszApp, -1, szApp, 80
  156.             , NULL, NULL);
  157.         }
  158.  
  159.     if (NULL!=pszObj)
  160.         {
  161.         WideCharToMultiByte(CP_ACP, 0, pszObj, -1, szObj, 80
  162.             , NULL, NULL);
  163.         }
  164.  
  165.     m_pObj->m_pFR->UpdateEmbeddingUI(TRUE, m_pObj->m_pDoc
  166.         , szApp, szObj);
  167.    #else
  168.     m_pObj->m_pFR->UpdateEmbeddingUI(TRUE, m_pObj->m_pDoc
  169.         , pszApp, pszObj);
  170.    #endif
  171.     return NOERROR;
  172.     }
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179. /*
  180.  * CImpIOleObject::Close
  181.  *
  182.  * Purpose:
  183.  *  Forces the object to close down its user interface and unload.
  184.  *
  185.  * Parameters:
  186.  *  dwSaveOption    DWORD describing the circumstances under which
  187.  *                  the object is being saved and closed.
  188.  *
  189.  * Return Value:
  190.  *  HRESULT         NOERROR or a general error value.
  191.  */
  192.  
  193. STDMETHODIMP CImpIOleObject::Close(DWORD dwSaveOption)
  194.     {
  195.     HWND        hWnd;
  196.     BOOL        fSave=FALSE;
  197.  
  198.     hWnd=m_pObj->m_pDoc->Window();
  199.  
  200.     //If object is dirty and we're asked to save, save it and close.
  201.     if (OLECLOSE_SAVEIFDIRTY==dwSaveOption && m_pObj->FIsDirty())
  202.         fSave=TRUE;
  203.  
  204.     /*
  205.      * If asked to prompt, only do so if dirty, then if we get a
  206.      * YES, save as usual and close.  On NO, just close.  On
  207.      * CANCEL return OLE_E_PROMPTSAVECANCELLED.
  208.      */
  209.     if (OLECLOSE_PROMPTSAVE==dwSaveOption && m_pObj->FIsDirty())
  210.         {
  211.         UINT        uRet;
  212.  
  213.         uRet=MessageBox(hWnd, (*m_pObj->m_pST)[IDS_CLOSECAPTION]
  214.             , (*m_pObj->m_pST)[IDS_CLOSEPROMPT], MB_YESNOCANCEL);
  215.  
  216.         if (IDCANCEL==uRet)
  217.             return ResultFromScode(OLE_E_PROMPTSAVECANCELLED);
  218.  
  219.         if (IDYES==uRet)
  220.             fSave=TRUE;
  221.         }
  222.  
  223.     if (fSave)
  224.         {
  225.         m_pObj->SendAdvise(OBJECTCODE_SAVEOBJECT);
  226.         m_pObj->SendAdvise(OBJECTCODE_SAVED);
  227.         }
  228.  
  229.     //We get directly here on OLECLOSE_NOSAVE.
  230.     PostMessage(hWnd, WM_CLOSE, 0, 0L);
  231.     return NOERROR;
  232.     }
  233.  
  234.  
  235.  
  236.  
  237.  
  238. /*
  239.  * CImpIOleObject::SetMoniker
  240.  *
  241.  * Purpose:
  242.  *  Informs the object of its moniker or its container's moniker
  243.  *  depending on dwWhich.
  244.  *
  245.  * Parameters:
  246.  *  dwWhich         DWORD describing whether the moniker is the
  247.  *                  object's or the container's.
  248.  *  pmk             LPMONIKER with the name.
  249.  *
  250.  * Return Value:
  251.  *  HRESULT         NOERROR or a general error value.
  252.  */
  253.  
  254. STDMETHODIMP CImpIOleObject::SetMoniker(DWORD dwWhich
  255.     , LPMONIKER pmk)
  256.     {
  257.     //Uninteresting for embeddings only.
  258.     return ResultFromScode(E_NOTIMPL);
  259.     }
  260.  
  261.  
  262.  
  263.  
  264.  
  265. /*
  266.  * CImpIOleObject::GetMoniker
  267.  *
  268.  * Purpose:
  269.  *  Asks the object for a moniker that can later be used to
  270.  *  reconnect to it.
  271.  *
  272.  * Parameters:
  273.  *  dwAssign        DWORD determining how to assign the moniker to
  274.  *                  to the object.
  275.  *  dwWhich         DWORD describing which moniker the caller wants.
  276.  *  ppmk            LPMONIKER * into which to store the moniker.
  277.  *
  278.  * Return Value:
  279.  *  HRESULT         NOERROR or a general error value.
  280.  */
  281.  
  282. STDMETHODIMP CImpIOleObject::GetMoniker(DWORD dwAssign
  283.     , DWORD dwWhich, LPMONIKER * ppmk)
  284.     {
  285.     //Uninteresting for embeddings only.
  286.     return ResultFromScode(E_NOTIMPL);
  287.     }
  288.  
  289.  
  290.  
  291.  
  292.  
  293. /*
  294.  * CImpIOleObject::InitFromData
  295.  *
  296.  * Purpose:
  297.  *  Initializes the object from the contents of a data object.
  298.  *
  299.  * Parameters:
  300.  *  pIDataObject    LPDATAOBJECT containing the data.
  301.  *  fCreation       BOOL indicating if this is part of a new
  302.  *                  creation. If FALSE, the container is trying
  303.  *                  to paste here.
  304.  *  dwReserved      DWORD reserved.
  305.  *
  306.  * Return Value:
  307.  *  HRESULT         NOERROR or a general error value.
  308.  */
  309.  
  310. STDMETHODIMP CImpIOleObject::InitFromData(LPDATAOBJECT pIDataObject
  311.     , BOOL fCreation, DWORD dwReserved)
  312.     {
  313.     BOOL    fRet;
  314.  
  315.     /*
  316.      * If we get a data object here, try to paste from it.  If
  317.      * you've written clipboard code already, this is a snap.
  318.      * We don't really care about fCreation or not since pasting
  319.      * in us blasts away whatever is already here.
  320.      */
  321.     fRet=m_pObj->m_pDoc->PasteFromData(pIDataObject);
  322.     return fRet ? NOERROR : ResultFromScode(E_FAIL);
  323.     }
  324.  
  325.  
  326.  
  327.  
  328.  
  329. /*
  330.  * CImpIOleObject::GetClipboardData
  331.  *
  332.  * Purpose:
  333.  *  Returns an IDataObject pointer to the caller representing what
  334.  *  would be on the clipboard if the server did an Edit/Copy using
  335.  *  OleSetClipboard.
  336.  *
  337.  * Parameters:
  338.  *  dwReserved      DWORD reserved.
  339.  *  ppIDataObj      LPDATAOBJECT * into which to store the
  340.  *                  pointer.
  341.  *
  342.  * Return Value:
  343.  *  HRESULT         NOERROR or a general error value.
  344.  */
  345.  
  346. STDMETHODIMP CImpIOleObject::GetClipboardData(DWORD dwReserved
  347.     , LPDATAOBJECT *ppIDataObj)
  348.     {
  349.     /*
  350.      * Again, if you have a function to create a data object for the
  351.      * clipboard, this is a simple implementation.  The one we have
  352.      * does all the compound document formats already.
  353.      */
  354.     *ppIDataObj=m_pObj->m_pDoc->TransferObjectCreate(FALSE);
  355.     return (NULL!=*ppIDataObj) ? NOERROR : ResultFromScode(E_FAIL);
  356.     }
  357.  
  358.  
  359.  
  360.  
  361.  
  362. /*
  363.  * CImpIOleObject::DoVerb
  364.  *
  365.  * Purpose:
  366.  *  Executes an object-defined action.
  367.  *
  368.  * Parameters:
  369.  *  iVerb           LONG index of the verb to execute.
  370.  *  pMSG            LPMSG describing the event causing the
  371.  *                  activation.
  372.  *  pActiveSite     LPOLECLIENTSITE to the site involved.
  373.  *  lIndex          LONG the piece on which execution is happening.
  374.  *  hWndParent      HWND of window in which the object can play
  375.  *                  in-place.
  376.  *  pRectPos        LPRECT of the object in hWndParent where the
  377.  *                  object can play in-place if desired.
  378.  *
  379.  * Return Value:
  380.  *  HRESULT         NOERROR or a general error value.
  381.  */
  382.  
  383. STDMETHODIMP CImpIOleObject::DoVerb(LONG iVerb, LPMSG pMSG
  384.     , LPOLECLIENTSITE pActiveSite, LONG lIndex, HWND hWndParent
  385.     , LPCRECT pRectPos)
  386.     {
  387.     HWND            hWnd, hWndT;
  388.  
  389.     //Find the upper most window
  390.     hWndT=GetParent(m_pObj->m_pDoc->Window());
  391.  
  392.     while (NULL!=hWndT)
  393.         {
  394.         hWnd=hWndT;
  395.         hWndT=GetParent(hWndT);
  396.         }
  397.  
  398.     switch (iVerb)
  399.         {
  400.         case OLEIVERB_HIDE:
  401.             ShowWindow(hWnd, SW_HIDE);
  402.             m_pObj->SendAdvise(OBJECTCODE_HIDEWINDOW);
  403.             break;
  404.  
  405.         case OLEIVERB_PRIMARY:
  406.         case OLEIVERB_OPEN:
  407.         case OLEIVERB_SHOW:
  408.             ShowWindow(hWnd, SW_SHOW);
  409.             SetForegroundWindow(hWnd);
  410.             SetFocus(hWnd);
  411.  
  412.             m_pObj->SendAdvise(OBJECTCODE_SHOWOBJECT);
  413.             m_pObj->SendAdvise(OBJECTCODE_SHOWWINDOW);
  414.             break;
  415.  
  416.         default:
  417.             return ResultFromScode(OLEOBJ_S_INVALIDVERB);
  418.         }
  419.  
  420.     return NOERROR;
  421.     }
  422.  
  423.  
  424.  
  425.  
  426.  
  427. /*
  428.  * CImpIOleObject::EnumVerbs
  429.  *
  430.  * Purpose:
  431.  *  Creates an enumerator that knows the object's verbs.  If you
  432.  *  need to change the verb list dynamically, then you'll need to
  433.  *  implement this, otherwise you can return OLE_S_USEREG.
  434.  *
  435.  * Parameters:
  436.  *  ppEnum          LPENUMOLEVERB * into which to return the
  437.  *                  enum.
  438.  *
  439.  * Return Value:
  440.  *  HRESULT         NOERROR or a general error value.
  441.  */
  442.  
  443. STDMETHODIMP CImpIOleObject::EnumVerbs(LPENUMOLEVERB *ppEnum)
  444.     {
  445.     //Trivial implementation if you fill the regDB.
  446.     return ResultFromScode(OLE_S_USEREG);
  447.     }
  448.  
  449.  
  450.  
  451.  
  452.  
  453. /*
  454.  * CImpIOleObject::Update
  455.  *
  456.  * Purpose:
  457.  *  Insures that the object is up to date.  This is mostly used for
  458.  *  caching but you must make sure that you recursively call all
  459.  *  nested objects you contain as well.
  460.  *
  461.  * Parameters:
  462.  *  None
  463.  *
  464.  * Return Value:
  465.  *  HRESULT         NOERROR or a general error value.
  466.  */
  467.  
  468. STDMETHODIMP CImpIOleObject::Update(void)
  469.     {
  470.     //We're always updated since we don't contain.
  471.     return NOERROR;
  472.     }
  473.  
  474.  
  475.  
  476.  
  477.  
  478. /*
  479.  * CImpIOleObject::IsUpToDate
  480.  *
  481.  * Purpose:
  482.  *  Returns if the object is currently up to date, which involves
  483.  *  asking all contained object inside this object if they are up
  484.  *  to date as well.
  485.  *
  486.  * Parameters:
  487.  *  None
  488.  *
  489.  * Return Value:
  490.  *  HRESULT         NOERROR if successful, S_FALSE if dirty.
  491.  */
  492.  
  493. STDMETHODIMP CImpIOleObject::IsUpToDate(void)
  494.     {
  495.     //We're always updated since we don't contain.
  496.     return NOERROR;
  497.     }
  498.  
  499.  
  500.  
  501.  
  502.  
  503. /*
  504.  * CImpIOleObject::GetUserClassID
  505.  *
  506.  * Purpose:
  507.  *  Used for linked objects, this returns the class ID of what end
  508.  *  users think they are editing.
  509.  *
  510.  * Parameters:
  511.  *  pClsID          LPCLSID in which to store the CLSID.
  512.  *
  513.  * Return Value:
  514.  *  HRESULT         NOERROR or a general error value.
  515.  */
  516.  
  517. STDMETHODIMP CImpIOleObject::GetUserClassID(LPCLSID pClsID)
  518.     {
  519.     /*
  520.      * If you are not registered to handle data other than yourself,
  521.      * then you can just return your class ID here.  If you are
  522.      * registered as usable from Treat-As dialogs, then you need
  523.      * to return the CLSID of what you are really editing.
  524.      */
  525.  
  526.     *pClsID=m_pObj->m_clsID;
  527.     return NOERROR;
  528.     }
  529.  
  530.  
  531.  
  532.  
  533.  
  534. /*
  535.  * CImpIOleObject::GetUserType
  536.  *
  537.  * Purpose:
  538.  *  Determines the user-presentable name of the object.
  539.  *
  540.  * Parameters:
  541.  *  dwForm          DWORD describing which form of the string is
  542.  *                  desired.
  543.  *  pszType         LPOLESTR * into which to return the pointer to
  544.  *                  the type string.
  545.  *
  546.  * Return Value:
  547.  *  HRESULT         NOERROR or a general error value.
  548.  */
  549.  
  550. STDMETHODIMP CImpIOleObject::GetUserType(DWORD dwForm
  551.     , LPOLESTR *ppszType)
  552.     {
  553.     return ResultFromScode(OLE_S_USEREG);
  554.     }
  555.  
  556.  
  557.  
  558.  
  559.  
  560. /*
  561.  * CImpIOleObject::SetExtent
  562.  *
  563.  * Purpose:
  564.  *  Sets the size of the object in HIMETRIC units.
  565.  *
  566.  * Parameters:
  567.  *  dwAspect        DWORD of the aspect affected.
  568.  *  pszl            LPSIZEL containing the new size.
  569.  *
  570.  * Return Value:
  571.  *  HRESULT         NOERROR or a general error value.
  572.  */
  573.  
  574. STDMETHODIMP CImpIOleObject::SetExtent(DWORD dwAspect, LPSIZEL pszl)
  575.     {
  576.     RECT            rc;
  577.     SIZEL           szl;
  578.  
  579.     if (!(DVASPECT_CONTENT & dwAspect))
  580.         return ResultFromScode(E_FAIL);
  581.  
  582.     XformSizeInHimetricToPixels(NULL, pszl, &szl);
  583.  
  584.     //This resizes the window to match the container's size.
  585.     SetRect(&rc, 0, 0, (int)szl.cx, (int)szl.cy);
  586.     m_pObj->m_pPL->SizeSet(&rc, TRUE);
  587.  
  588.     return NOERROR;
  589.     }
  590.  
  591.  
  592.  
  593.  
  594.  
  595. /*
  596.  * CImpIOleObject::GetExtent
  597.  *
  598.  * Purpose:
  599.  *  Retrieves the size of the object in HIMETRIC units.
  600.  *
  601.  * Parameters:
  602.  *  dwAspect        DWORD of the aspect requested
  603.  *  pszl            LPSIZEL into which to store the size.
  604.  *
  605.  * Return Value:
  606.  *  HRESULT         NOERROR or a general error value.
  607.  */
  608.  
  609. STDMETHODIMP CImpIOleObject::GetExtent(DWORD dwAspect, LPSIZEL pszl)
  610.     {
  611.     RECT            rc;
  612.     SIZEL           szl;
  613.  
  614.     if (!(DVASPECT_CONTENT & dwAspect))
  615.         return ResultFromScode(E_FAIL);
  616.  
  617.     m_pObj->m_pPL->RectGet(&rc);
  618.     szl.cx=rc.right-rc.left;
  619.     szl.cy=rc.bottom-rc.top;
  620.  
  621.     XformSizeInPixelsToHimetric(NULL, &szl, pszl);
  622.     return NOERROR;
  623.     }
  624.  
  625.  
  626.  
  627.  
  628.  
  629. /*
  630.  * CImpIOleObject::Advise
  631.  *
  632.  * Purpose:
  633.  *  Provides an IAdviseSink to the object for notifications.
  634.  *
  635.  * Parameters:
  636.  *  pIAdviseSink    LPADVISESINK to notify.
  637.  *  pdwConn         LPDWORD into which to store a connection key.
  638.  *
  639.  * Return Value:
  640.  *  HRESULT         NOERROR or a general error value.
  641.  */
  642.  
  643. STDMETHODIMP CImpIOleObject::Advise(LPADVISESINK pIAdviseSink
  644.     , LPDWORD pdwConn)
  645.     {
  646.     if (NULL==m_pObj->m_pIOleAdviseHolder)
  647.         {
  648.         HRESULT     hr;
  649.  
  650.         hr=CreateOleAdviseHolder(&m_pObj->m_pIOleAdviseHolder);
  651.  
  652.         if (FAILED(hr))
  653.             return hr;
  654.         }
  655.  
  656.     return m_pObj->m_pIOleAdviseHolder->Advise(pIAdviseSink
  657.         , pdwConn);
  658.     }
  659.  
  660.  
  661.  
  662.  
  663.  
  664. /*
  665.  * CImpIOleObject::Unadvise
  666.  *
  667.  * Purpose:
  668.  *  Terminates a previous advise connection from Advise.
  669.  *
  670.  * Parameters:
  671.  *  dwConn          DWORD connection key from Advise.
  672.  *
  673.  * Return Value:
  674.  *  HRESULT         NOERROR or a general error value.
  675.  */
  676.  
  677. STDMETHODIMP CImpIOleObject::Unadvise(DWORD dwConn)
  678.     {
  679.     if (NULL!=m_pObj->m_pIOleAdviseHolder)
  680.         return m_pObj->m_pIOleAdviseHolder->Unadvise(dwConn);
  681.  
  682.     return ResultFromScode(E_FAIL);
  683.     }
  684.  
  685.  
  686.  
  687.  
  688.  
  689. /*
  690.  * CImpIOleObject::EnumAdvise
  691.  *
  692.  * Purpose:
  693.  *  Creates and returns a enumeration of the advises on this object.
  694.  *
  695.  * Parameters:
  696.  *  ppEnum          LPENUMSTATDATA * in which to return the
  697.  *                  enumerator.
  698.  *
  699.  * Return Value:
  700.  *  HRESULT         NOERROR or a general error value.
  701.  */
  702.  
  703. STDMETHODIMP CImpIOleObject::EnumAdvise(LPENUMSTATDATA *ppEnum)
  704.     {
  705.     if (NULL!=m_pObj->m_pIOleAdviseHolder)
  706.         return m_pObj->m_pIOleAdviseHolder->EnumAdvise(ppEnum);
  707.  
  708.     return ResultFromScode(E_FAIL);
  709.     }
  710.  
  711.  
  712.  
  713.  
  714.  
  715. /*
  716.  * CImpIOleObject::GetMiscStatus
  717.  *
  718.  * Purpose:
  719.  *  Returns a set of miscellaneous status flags for the object.
  720.  *
  721.  * Parameters:
  722.  *  dwAspect        DWORD of the aspect in question.
  723.  *  pdwStatus       LPDWORD in which to store the flags.
  724.  *
  725.  * Return Value:
  726.  *  HRESULT         NOERROR or a general error value.
  727.  */
  728.  
  729. STDMETHODIMP CImpIOleObject::GetMiscStatus(DWORD dwAspect
  730.     , LPDWORD pdwStatus)
  731.     {
  732.     return ResultFromScode(OLE_S_USEREG);
  733.     }
  734.  
  735.  
  736.  
  737.  
  738.  
  739. /*
  740.  * CImpIOleObject::SetColorScheme
  741.  *
  742.  * Purpose:
  743.  *  Provides the object with the color palette as recommended by
  744.  *  the container application that also knows the palettes of other
  745.  *  objects.  The object here is not required to use these colors.
  746.  *
  747.  * Parameters:
  748.  *  pLP             LPLOGPALETTE providing the colors.
  749.  *
  750.  * Return Value:
  751.  *  HRESULT         NOERROR or a general error value.
  752.  */
  753.  
  754. STDMETHODIMP CImpIOleObject::SetColorScheme(LPLOGPALETTE pLP)
  755.     {
  756.     return ResultFromScode(E_NOTIMPL);
  757.     }
  758.