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 / chap21 / polyline / ioleobj.cpp < prev    next >
C/C++ Source or Header  |  1995-05-03  |  16KB  |  630 lines

  1. /*
  2.  * IOLEOBJ.CPP
  3.  * Polyline Component Chapter 21
  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.     //CHAPTER21MOD
  93.     if (NULL!=m_pObj->m_pIOleClientSite)
  94.         {
  95.         HRESULT         hr;
  96.         LPMONIKER       pmk;
  97.         LPOLECONTAINER  pIOleCont;
  98.  
  99.         m_pObj->m_pIOleClientSite->AddRef();
  100.  
  101.         /*
  102.          * Within IRunnableObject::Run we're supposed to register
  103.          * ourselves as running...however, the moniker has to come
  104.          * from the container's IOleClientSite::GetMoniker.  But
  105.          * Run is called before SetClientSite here, so we have to
  106.          * register now that we do have the client site as well
  107.          * as lock the container.
  108.          */
  109.  
  110.         hr=m_pObj->m_pIOleClientSite->GetMoniker
  111.             (OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_OBJFULL, &pmk);
  112.  
  113.         if (SUCCEEDED(hr))
  114.             {
  115.             INOLE_RegisterAsRunning(this, pmk, 0
  116.                 , &m_pObj->m_dwRegROT);
  117.             pmk->Release();
  118.             }
  119.  
  120.         hr=m_pObj->m_pIOleClientSite->GetContainer(&pIOleCont);
  121.  
  122.         if (SUCCEEDED(hr))
  123.             {
  124.             m_pObj->m_fLockContainer=TRUE;
  125.             pIOleCont->LockContainer(TRUE);
  126.             pIOleCont->Release();
  127.             }
  128.         }
  129.     //End CHAPTER21MOD
  130.  
  131.     return NOERROR;
  132.     }
  133.  
  134. STDMETHODIMP CImpIOleObject::GetClientSite(LPOLECLIENTSITE *ppSite)
  135.     {
  136.     //Be sure to AddRef the new pointer you are giving away.
  137.     *ppSite=m_pObj->m_pIOleClientSite;
  138.     m_pObj->m_pIOleClientSite->AddRef();
  139.  
  140.     return NOERROR;
  141.     }
  142.  
  143.  
  144.  
  145.  
  146.  
  147. /*
  148.  * CImpIOleObject::SetHostNames
  149.  *
  150.  * Purpose:
  151.  *  Provides the object with names of the container application and
  152.  *  the object in the container to use in object user interface.
  153.  *
  154.  * Parameters:
  155.  *  pszApp          LPCOLESTR of the container application.
  156.  *  pszObj          LPCOLESTR of some name that is useful in window
  157.  *                  titles.
  158.  *
  159.  * Return Value:
  160.  *  HRESULT         NOERROR
  161.  */
  162.  
  163. STDMETHODIMP CImpIOleObject::SetHostNames(LPCOLESTR pszApp
  164.     , LPCOLESTR pszObj)
  165.     {
  166.     if (NULL!=m_pObj->m_hDlg)
  167.         {
  168.         TCHAR       szTemp[128];
  169.  
  170.        #ifdef WIN32ANSI
  171.         char        szObj[80];
  172.         WideCharToMultiByte(CP_ACP, 0, pszObj, -1, szObj, 80
  173.             , NULL, NULL);
  174.         wsprintf(szTemp, SZPOLYFRAMETITLE, szObj);
  175.        #else
  176.         wsprintf(szTemp, SZPOLYFRAMETITLE, pszObj);
  177.        #endif
  178.         SetWindowText(m_pObj->m_hDlg, szTemp);
  179.         }
  180.  
  181.     return NOERROR;
  182.     }
  183.  
  184.  
  185.  
  186.  
  187.  
  188. /*
  189.  * CImpIOleObject::Close
  190.  *
  191.  * Purpose:
  192.  *  Forces the object to close down its user interface and unload.
  193.  *
  194.  * Parameters:
  195.  *  dwSaveOption    DWORD describing the circumstances under which
  196.  *                  the object is being saved and closed.
  197.  *
  198.  * Return Value:
  199.  *  HRESULT         NOERROR or a general error value.
  200.  */
  201.  
  202. STDMETHODIMP CImpIOleObject::Close(DWORD dwSaveOption)
  203.     {
  204.     HWND        hWnd;
  205.     BOOL        fSave=FALSE;
  206.  
  207.     hWnd=m_pObj->m_hDlg;
  208.  
  209.     //If object is dirty and we're asked to save, save it and close.
  210.     if (OLECLOSE_SAVEIFDIRTY==dwSaveOption && m_pObj->m_fDirty)
  211.         fSave=TRUE;
  212.  
  213.     /*
  214.      * If asked to prompt, only do so if dirty, then if we get a
  215.      * YES, save as usual and close.  On NO, just close.  On
  216.      * CANCEL return OLE_E_PROMPTSAVECANCELLED.
  217.      */
  218.     if (OLECLOSE_PROMPTSAVE==dwSaveOption && m_pObj->m_fDirty)
  219.         {
  220.         TCHAR       szTitle[20];
  221.         TCHAR       szTemp[80];
  222.         UINT        uRet;
  223.  
  224.         lstrcpy(szTitle, m_pObj->String(IDS_CLOSECAPTION));
  225.         lstrcpy(szTemp, m_pObj->String(IDS_CLOSEPROMPT));
  226.  
  227.         uRet=MessageBox(hWnd, szTemp, szTitle, MB_YESNOCANCEL);
  228.  
  229.         if (IDCANCEL==uRet)
  230.             return ResultFromScode(OLE_E_PROMPTSAVECANCELLED);
  231.  
  232.         if (IDYES==uRet)
  233.             fSave=TRUE;
  234.         }
  235.  
  236.     if (fSave)
  237.         {
  238.         m_pObj->SendAdvise(OBJECTCODE_SAVEOBJECT);
  239.         m_pObj->SendAdvise(OBJECTCODE_SAVED);
  240.         }
  241.  
  242.     //We get directly here on OLECLOSE_NOSAVE.
  243.     //CHAPTER21MOD
  244.     if (m_pObj->m_fLockContainer)
  245.         {
  246.         //Match LockContainer call from SetClientSite
  247.         LPOLECONTAINER  pIOleCont;
  248.  
  249.         if (SUCCEEDED(m_pObj->m_pIOleClientSite
  250.             ->GetContainer(&pIOleCont)))
  251.             {
  252.             pIOleCont->LockContainer(FALSE);
  253.             pIOleCont->Release();
  254.             m_pObj->m_fLockContainer=FALSE;
  255.             }
  256.         }
  257.     //End CHAPTER21MOD
  258.  
  259.     if (NULL!=hWnd)
  260.         {
  261.         //This hides the window and sends the appropriate notify.
  262.         DoVerb(OLEIVERB_HIDE, NULL, NULL, -1, NULL, NULL);
  263.  
  264.         m_pObj->SendAdvise(OBJECTCODE_CLOSED);
  265.         PostMessage(hWnd, POLYM_CLOSE, 0, 0L);
  266.         }
  267.  
  268.     return NOERROR;
  269.     }
  270.  
  271.  
  272.  
  273.  
  274. /*
  275.  * CImpIOleObject::DoVerb
  276.  *
  277.  * Purpose:
  278.  *  Executes an object-defined action.
  279.  *
  280.  * Parameters:
  281.  *  iVerb           LONG index of the verb to execute.
  282.  *  pMSG            LPMSG describing the event causing the
  283.  *                  activation.
  284.  *  pActiveSite     LPOLECLIENTSITE to the site involved.
  285.  *  lIndex          LONG the piece on which execution is happening.
  286.  *  hWndParent      HWND of the window in which the object can play
  287.  *                  in-place.
  288.  *  pRectPos        LPRECT of the object in hWndParent where the
  289.  *                  object can play in-place if desired.
  290.  *
  291.  * Return Value:
  292.  *  HRESULT         NOERROR or a general error value.
  293.  */
  294.  
  295. STDMETHODIMP CImpIOleObject::DoVerb(LONG iVerb, LPMSG pMSG
  296.     , LPOLECLIENTSITE pActiveSite, LONG lIndex, HWND hWndParent
  297.     , LPCRECT pRectPos)
  298.     {
  299.     HRESULT     hr;
  300.  
  301.     switch (iVerb)
  302.         {
  303.         case OLEIVERB_HIDE:
  304.             if (NULL!=m_pObj->m_hDlg)
  305.                 {
  306.                 ShowWindow(m_pObj->m_hDlg, SW_HIDE);
  307.                 m_pObj->SendAdvise(OBJECTCODE_HIDEWINDOW);
  308.                 }
  309.  
  310.             break;
  311.  
  312.         case OLEIVERB_PRIMARY:
  313.         case OLEIVERB_OPEN:
  314.         case OLEIVERB_SHOW:
  315.             /*
  316.              * If we're not running, make sure we are.  In any
  317.              * case, make the dialog visible and insure it has
  318.              * the right parent now.
  319.              */
  320.             hr=NOERROR;
  321.             if (NULL==m_pObj->m_hDlg)
  322.                 hr=m_pObj->m_pImpIRunnableObject->Run(NULL);
  323.  
  324.             if (FAILED(hr) || NULL==m_pObj->m_hDlg)
  325.                 return ResultFromScode(E_OUTOFMEMORY);
  326.  
  327.             ShowWindow(m_pObj->m_hDlg, SW_SHOW);
  328.             SetFocus(m_pObj->m_hDlg);
  329.             m_pObj->SendAdvise(OBJECTCODE_SHOWOBJECT);
  330.             m_pObj->SendAdvise(OBJECTCODE_SHOWWINDOW);
  331.  
  332.             break;
  333.  
  334.         default:
  335.             return ResultFromScode(OLEOBJ_S_INVALIDVERB);
  336.         }
  337.  
  338.     return NOERROR;
  339.     }
  340.  
  341.  
  342.  
  343.  
  344.  
  345.  
  346. /*
  347.  * CImpIOleObject::GetUserClassID
  348.  *
  349.  * Purpose:
  350.  *  Used for linked objects, this returns the class ID of what end
  351.  *  users think they are editing.
  352.  *
  353.  * Parameters:
  354.  *  pClsID          LPCLSID in which to store the CLSID.
  355.  *
  356.  * Return Value:
  357.  *  HRESULT         NOERROR or a general error value.
  358.  */
  359.  
  360. STDMETHODIMP CImpIOleObject::GetUserClassID(LPCLSID pClsID)
  361.     {
  362.     /*
  363.      * If you are not registered to handle data other than yourself,
  364.      * then you can just return your class ID here.  If you are
  365.      * registered as usable from Treat-As dialogs, then you need to
  366.      * return the CLSID of what you are really editing.
  367.      */
  368.  
  369.     *pClsID=CLSID_Polyline19;
  370.     return NOERROR;
  371.     }
  372.  
  373.  
  374.  
  375.  
  376.  
  377. /*
  378.  * CImpIOleObject::SetExtent
  379.  *
  380.  * Purpose:
  381.  *  Sets the size of the object in HIMETRIC units.  Since we're in
  382.  *  a dialog, the size of the object in us is fixed, so we ignore
  383.  *  this call.
  384.  *
  385.  * Parameters:
  386.  *  dwAspect        DWORD of the aspect affected.
  387.  *  pszl            LPSIZEL containing the new size.
  388.  *
  389.  * Return Value:
  390.  *  HRESULT         NOERROR or a general error value.
  391.  */
  392.  
  393. STDMETHODIMP CImpIOleObject::SetExtent(DWORD dwAspect
  394.     , LPSIZEL pszl)
  395.     {
  396.     //Ignored:  no size change in the dialog.
  397.     return NOERROR;
  398.     }
  399.  
  400.  
  401.  
  402.  
  403.  
  404. /*
  405.  * CImpIOleObject::GetExtent
  406.  *
  407.  * Purpose:
  408.  *  Retrieves the size of the object in HIMETRIC units.
  409.  *
  410.  * Parameters:
  411.  *  dwAspect        DWORD of the aspect requested
  412.  *  pszl            LPSIZEL into which to store the size.
  413.  *
  414.  * Return Value:
  415.  *  HRESULT         NOERROR or a general error value.
  416.  */
  417.  
  418. STDMETHODIMP CImpIOleObject::GetExtent(DWORD dwAspect, LPSIZEL pszl)
  419.     {
  420.     //Delegate directly to IViewObject2::GetExtent
  421.     return m_pObj->m_pImpIViewObject->GetExtent(dwAspect, -1
  422.         , NULL, pszl);
  423.     }
  424.  
  425.  
  426.  
  427.  
  428.  
  429. /*
  430.  * CImpIOleObject::Advise
  431.  * CImpIOleObject::Unadvise
  432.  * CImpIOleObject::EnumAdvise
  433.  *
  434.  * Purpose:
  435.  *  Advisory connection functions.
  436.  */
  437.  
  438. STDMETHODIMP CImpIOleObject::Advise(LPADVISESINK pIAdviseSink
  439.     , LPDWORD pdwConn)
  440.     {
  441.     if (NULL==m_pObj->m_pIOleAdviseHolder)
  442.         {
  443.         HRESULT     hr;
  444.  
  445.         hr=CreateOleAdviseHolder(&m_pObj->m_pIOleAdviseHolder);
  446.  
  447.         if (FAILED(hr))
  448.             return hr;
  449.         }
  450.  
  451.     return m_pObj->m_pIOleAdviseHolder->Advise(pIAdviseSink
  452.         , pdwConn);
  453.     }
  454.  
  455.  
  456. STDMETHODIMP CImpIOleObject::Unadvise(DWORD dwConn)
  457.     {
  458.     if (NULL!=m_pObj->m_pIOleAdviseHolder)
  459.         return m_pObj->m_pIOleAdviseHolder->Unadvise(dwConn);
  460.  
  461.     return ResultFromScode(E_FAIL);
  462.     }
  463.  
  464.  
  465. STDMETHODIMP CImpIOleObject::EnumAdvise(LPENUMSTATDATA *ppEnum)
  466.     {
  467.     if (NULL!=m_pObj->m_pIOleAdviseHolder)
  468.         return m_pObj->m_pIOleAdviseHolder->EnumAdvise(ppEnum);
  469.  
  470.     return ResultFromScode(E_FAIL);
  471.     }
  472.  
  473.  
  474.  
  475. //CHAPTER21MOD
  476. /*
  477.  * CImpIOleObject::SetMoniker
  478.  *
  479.  * Purpose:
  480.  *  Informs the object of its moniker or its container's moniker
  481.  *  depending on dwWhich.
  482.  *
  483.  * Parameters:
  484.  *  dwWhich         DWORD describing whether the moniker is the
  485.  *                  object's or the container's.
  486.  *  pmk             LPMONIKER with the name.
  487.  *
  488.  * Return Value:
  489.  *  HRESULT         NOERROR or a general error value.
  490.  */
  491.  
  492. STDMETHODIMP CImpIOleObject::SetMoniker(DWORD dwWhich
  493.     , LPMONIKER pmk)
  494.     {
  495.     LPMONIKER       pmkFull;
  496.     HRESULT         hr=ResultFromScode(E_FAIL);
  497.  
  498.     /*
  499.      * For an embedded object we might be living in a container that
  500.      * has given us away as a link.  This is our indication to
  501.      * register the full moniker for this object that we obtain from
  502.      * IOleClientSite::GetMoniker(OLEWHICHMK_FULL).
  503.      */
  504.  
  505.     if (NULL!=m_pObj->m_pIOleClientSite)
  506.         {
  507.         hr=m_pObj->m_pIOleClientSite->GetMoniker
  508.             (OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_OBJFULL
  509.             , &pmkFull);
  510.         }
  511.  
  512.     if (SUCCEEDED(hr))
  513.         {
  514.         /*
  515.          * If this moniker is already running then we don't
  516.          * need to revoke and re-register the same thing again.
  517.          */
  518.         if (NOERROR==pmkFull->IsRunning(NULL, NULL, NULL))
  519.             {
  520.             pmkFull->Release();
  521.             return NOERROR;
  522.             }
  523.  
  524.         //This will revoke the old one if m_dwRegROT is nonzero.
  525.         INOLE_RegisterAsRunning(m_pObj, pmkFull, 0
  526.             , &m_pObj->m_dwRegROT);
  527.  
  528.         //Inform clients of the new moniker
  529.         if (NULL!=m_pObj->m_pIOleAdviseHolder)
  530.             m_pObj->m_pIOleAdviseHolder->SendOnRename(pmkFull);
  531.  
  532.         pmkFull->Release();
  533.         }
  534.  
  535.     return hr;
  536.     }
  537.  
  538.  
  539.  
  540. /*
  541.  * CImpIOleObject::GetMoniker
  542.  *
  543.  * Purpose:
  544.  *  Asks the object for a moniker that can later be used to
  545.  *  reconnect to it.
  546.  *
  547.  * Parameters:
  548.  *  dwAssign        DWORD determining how to assign the moniker to
  549.  *                  to the object.
  550.  *  dwWhich         DWORD describing which moniker the caller wants.
  551.  *  ppmk            LPMONIKER * into which to store the moniker.
  552.  *
  553.  * Return Value:
  554.  *  HRESULT         NOERROR or a general error value.
  555.  */
  556.  
  557. STDMETHODIMP CImpIOleObject::GetMoniker(DWORD dwAssign
  558.     , DWORD dwWhich, LPMONIKER *ppmk)
  559.     {
  560.     HRESULT         hr=ResultFromScode(E_FAIL);
  561.  
  562.     *ppmk=NULL;
  563.  
  564.     /*
  565.      * Since we only support embedded objects, our moniker
  566.      * is always the full moniker from the contianer.
  567.      */
  568.  
  569.     if (NULL!=m_pObj->m_pIOleClientSite)
  570.         {
  571.         hr=m_pObj->m_pIOleClientSite->GetMoniker
  572.             (OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_OBJFULL, ppmk);
  573.         }
  574.  
  575.     return (NULL!=*ppmk) ? NOERROR : hr;
  576.     }
  577.  
  578.  
  579.  
  580. //Methods not implemented or trivial
  581. STDMETHODIMP CImpIOleObject::InitFromData(LPDATAOBJECT pIDataObject
  582.     , BOOL fCreation, DWORD dw)
  583.     {
  584.     return ResultFromScode(E_NOTIMPL);
  585.     }
  586.  
  587. STDMETHODIMP CImpIOleObject::GetClipboardData(DWORD dwReserved
  588.     , LPDATAOBJECT *ppIDataObj)
  589.     {
  590.     return ResultFromScode(E_NOTIMPL);
  591.     }
  592.  
  593. STDMETHODIMP CImpIOleObject::Update(void)
  594.     {
  595.     return NOERROR;
  596.     }
  597.  
  598. STDMETHODIMP CImpIOleObject::IsUpToDate(void)
  599.     {
  600.     return NOERROR;
  601.     }
  602.  
  603. STDMETHODIMP CImpIOleObject::SetColorScheme(LPLOGPALETTE pLP)
  604.     {
  605.     return ResultFromScode(E_NOTIMPL);
  606.     }
  607. //End CHAPTER21MOD
  608.  
  609.  
  610.  
  611. //Methods implemented using registry helper functions in OLE.
  612.  
  613. STDMETHODIMP CImpIOleObject::EnumVerbs(LPENUMOLEVERB *ppEnum)
  614.     {
  615.     return OleRegEnumVerbs(m_pObj->m_clsID, ppEnum);
  616.     }
  617.  
  618. STDMETHODIMP CImpIOleObject::GetUserType(DWORD dwForm
  619.     , LPOLESTR *ppszType)
  620.     {
  621.     return OleRegGetUserType(m_pObj->m_clsID, dwForm, ppszType);
  622.     }
  623.  
  624. STDMETHODIMP CImpIOleObject::GetMiscStatus(DWORD dwAspect
  625.     , LPDWORD pdwStatus)
  626.     {
  627.     return OleRegGetMiscStatus(m_pObj->m_clsID, dwAspect
  628.         , pdwStatus);
  629.     }
  630.