IOLEOBJ.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:16k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*
  2.  * IOLEOBJ.CPP
  3.  * Polyline Component Chapter 23
  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. #include "polyline.h"
  16. /*
  17.  * CImpIOleObject::CImpIOleObject
  18.  * CImpIOleObject::~CImpIOleObject
  19.  *
  20.  * Parameters (Constructor):
  21.  *  pObj            PCPolyline of the object we're in.
  22.  *  pUnkOuter       LPUNKNOWN to which we delegate.
  23.  */
  24. CImpIOleObject::CImpIOleObject(PCPolyline pObj
  25.     , LPUNKNOWN pUnkOuter)
  26.     {
  27.     m_cRef=0;
  28.     m_pObj=pObj;
  29.     m_pUnkOuter=pUnkOuter;
  30.     return;
  31.     }
  32. CImpIOleObject::~CImpIOleObject(void)
  33.     {
  34.     return;
  35.     }
  36. /*
  37.  * CImpIOleObject::QueryInterface
  38.  * CImpIOleObject::AddRef
  39.  * CImpIOleObject::Release
  40.  *
  41.  * Purpose:
  42.  *  IUnknown members for CImpIOleObject object.
  43.  */
  44. STDMETHODIMP CImpIOleObject::QueryInterface(REFIID riid, PPVOID ppv)
  45.     {
  46.     return m_pUnkOuter->QueryInterface(riid, ppv);
  47.     }
  48. STDMETHODIMP_(ULONG) CImpIOleObject::AddRef(void)
  49.     {
  50.     ++m_cRef;
  51.     return m_pUnkOuter->AddRef();
  52.     }
  53. STDMETHODIMP_(ULONG) CImpIOleObject::Release(void)
  54.     {
  55.     --m_cRef;
  56.     return m_pUnkOuter->Release();
  57.     }
  58. /*
  59.  * CImpIOleObject::SetClientSite
  60.  * CImpIOleObject::GetClientSite
  61.  *
  62.  * Purpose:
  63.  *  Manages the IOleClientSite pointer of our container.
  64.  */
  65. STDMETHODIMP CImpIOleObject::SetClientSite
  66.     (LPOLECLIENTSITE pIOleClientSite)
  67.     {
  68.     if (NULL!=m_pObj->m_pIOleClientSite)
  69.         m_pObj->m_pIOleClientSite->Release();
  70.     m_pObj->m_pIOleClientSite=pIOleClientSite;
  71.     if (NULL!=m_pObj->m_pIOleClientSite)
  72.         {
  73.         HRESULT         hr;
  74.         LPMONIKER       pmk;
  75.         LPOLECONTAINER  pIOleCont;
  76.         m_pObj->m_pIOleClientSite->AddRef();
  77.         /*
  78.          * Within IRunnableObject::Run we're supposed to register
  79.          * ourselves as running...however, the moniker has to come
  80.          * from the container's IOleClientSite::GetMoniker.  But
  81.          * Run is called before SetClientSite here, so we have to
  82.          * register now that we do have the client site as well
  83.          * as lock the container.
  84.          */
  85.         hr=m_pObj->m_pIOleClientSite->GetMoniker
  86.             (OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_OBJFULL, &pmk);
  87.         if (SUCCEEDED(hr))
  88.             {
  89.             INOLE_RegisterAsRunning(this, pmk, 0
  90.                 , &m_pObj->m_dwRegROT);
  91.             pmk->Release();
  92.             }
  93.         hr=m_pObj->m_pIOleClientSite->GetContainer(&pIOleCont);
  94.         if (SUCCEEDED(hr))
  95.             {
  96.             m_pObj->m_fLockContainer=TRUE;
  97.             pIOleCont->LockContainer(TRUE);
  98.             pIOleCont->Release();
  99.             }
  100.         }
  101.     return NOERROR;
  102.     }
  103. STDMETHODIMP CImpIOleObject::GetClientSite(LPOLECLIENTSITE *ppSite)
  104.     {
  105.     //Be sure to AddRef the new pointer you are giving away.
  106.     *ppSite=m_pObj->m_pIOleClientSite;
  107.     m_pObj->m_pIOleClientSite->AddRef();
  108.     return NOERROR;
  109.     }
  110. /*
  111.  * CImpIOleObject::SetHostNames
  112.  *
  113.  * Purpose:
  114.  *  Provides the object with names of the container application and
  115.  *  the object in the container to use in object user interface.
  116.  *
  117.  * Parameters:
  118.  *  pszApp          LPCOLESTR of the container application.
  119.  *  pszObj          LPCOLESTR of some name that is useful in window
  120.  *                  titles.
  121.  *
  122.  * Return Value:
  123.  *  HRESULT         NOERROR
  124.  */
  125. STDMETHODIMP CImpIOleObject::SetHostNames(LPCOLESTR pszApp
  126.     , LPCOLESTR pszObj)
  127.     {
  128.     if (NULL!=m_pObj->m_hDlg)
  129.         {
  130.         TCHAR       szTemp[128];
  131.        #ifdef WIN32ANSI
  132.         char        szObj[80];
  133.         WideCharToMultiByte(CP_ACP, 0, pszObj, -1, szObj, 80
  134.             , NULL, NULL);
  135.         wsprintf(szTemp, SZPOLYFRAMETITLE, szObj);
  136.        #else
  137.         wsprintf(szTemp, SZPOLYFRAMETITLE, pszObj);
  138.        #endif
  139.         SetWindowText(m_pObj->m_hDlg, szTemp);
  140.         }
  141.     return NOERROR;
  142.     }
  143. /*
  144.  * CImpIOleObject::Close
  145.  *
  146.  * Purpose:
  147.  *  Forces the object to close down its user interface and unload.
  148.  *
  149.  * Parameters:
  150.  *  dwSaveOption    DWORD describing the circumstances under which
  151.  *                  the object is being saved and closed.
  152.  *
  153.  * Return Value:
  154.  *  HRESULT         NOERROR or a general error value.
  155.  */
  156. STDMETHODIMP CImpIOleObject::Close(DWORD dwSaveOption)
  157.     {
  158.     HWND        hWnd;
  159.     BOOL        fSave=FALSE;
  160.     hWnd=m_pObj->m_hDlg;
  161.     //If object is dirty and we're asked to save, save it and close.
  162.     if (OLECLOSE_SAVEIFDIRTY==dwSaveOption && m_pObj->m_fDirty)
  163.         fSave=TRUE;
  164.     /*
  165.      * If asked to prompt, only do so if dirty, then if we get a
  166.      * YES, save as usual and close.  On NO, just close.  On
  167.      * CANCEL return OLE_E_PROMPTSAVECANCELLED.
  168.      */
  169.     if (OLECLOSE_PROMPTSAVE==dwSaveOption && m_pObj->m_fDirty)
  170.         {
  171.         TCHAR       szTitle[20];
  172.         TCHAR       szTemp[80];
  173.         UINT        uRet;
  174.         lstrcpy(szTitle, m_pObj->String(IDS_CLOSECAPTION));
  175.         lstrcpy(szTemp, m_pObj->String(IDS_CLOSEPROMPT));
  176.         uRet=MessageBox(hWnd, szTemp, szTitle, MB_YESNOCANCEL);
  177.         if (IDCANCEL==uRet)
  178.             return ResultFromScode(OLE_E_PROMPTSAVECANCELLED);
  179.         if (IDYES==uRet)
  180.             fSave=TRUE;
  181.         }
  182.     if (fSave)
  183.         {
  184.         m_pObj->SendAdvise(OBJECTCODE_SAVEOBJECT);
  185.         m_pObj->SendAdvise(OBJECTCODE_SAVED);
  186.         }
  187.     //We get directly here on OLECLOSE_NOSAVE.
  188.     if (m_pObj->m_fLockContainer)
  189.         {
  190.         //Match LockContainer call from SetClientSite
  191.         LPOLECONTAINER  pIOleCont;
  192.         if (SUCCEEDED(m_pObj->m_pIOleClientSite
  193.             ->GetContainer(&pIOleCont)))
  194.             {
  195.             pIOleCont->LockContainer(FALSE);
  196.             pIOleCont->Release();
  197.             }
  198.         }
  199.     if (NULL!=hWnd)
  200.         {
  201.         //This hides the window and sends the appropriate notify.
  202.         DoVerb(OLEIVERB_HIDE, NULL, NULL, -1, NULL, NULL);
  203.         m_pObj->SendAdvise(OBJECTCODE_CLOSED);
  204.         PostMessage(hWnd, POLYM_CLOSE, 0, 0L);
  205.         }
  206.     return NOERROR;
  207.     }
  208. /*
  209.  * CImpIOleObject::DoVerb
  210.  *
  211.  * Purpose:
  212.  *  Executes an object-defined action.
  213.  *
  214.  * Parameters:
  215.  *  iVerb           LONG index of the verb to execute.
  216.  *  pMSG            LPMSG describing the event causing the
  217.  *                  activation.
  218.  *  pActiveSite     LPOLECLIENTSITE to the site involved.
  219.  *  lIndex          LONG the piece on which execution is happening.
  220.  *  hWndParent      HWND of the window in which the object can play
  221.  *                  in-place.
  222.  *  pRectPos        LPRECT of the object in hWndParent where the
  223.  *                  object can play in-place if desired.
  224.  *
  225.  * Return Value:
  226.  *  HRESULT         NOERROR or a general error value.
  227.  */
  228. STDMETHODIMP CImpIOleObject::DoVerb(LONG iVerb, LPMSG pMSG
  229.     , LPOLECLIENTSITE pActiveSite, LONG lIndex, HWND hWndParent
  230.     , LPCRECT pRectPos)
  231.     {
  232.     HRESULT     hr;
  233.     switch (iVerb)
  234.         {
  235.         case OLEIVERB_HIDE:
  236.             //CHAPTER23MOD
  237.             if (NULL!=m_pObj->m_pIOleIPSite)
  238.                 {
  239.                 if (NULL!=m_pObj->m_pHW)
  240.                     ShowWindow(m_pObj->m_pHW->Window(), SW_HIDE);
  241.                 }
  242.             else
  243.                 {
  244.                 if (NULL!=m_pObj->m_hDlg)
  245.                     ShowWindow(m_pObj->m_hDlg, SW_HIDE);
  246.                 }
  247.             m_pObj->SendAdvise(OBJECTCODE_HIDEWINDOW);
  248.             m_pObj->m_fAllowInPlace=TRUE;
  249.             //End CHAPTER23MOD
  250.             break;
  251.         //CHAPTER23MOD
  252.         case OLEIVERB_PRIMARY:
  253.         case OLEIVERB_SHOW:
  254.             if (NULL!=m_pObj->m_pIOleIPSite)
  255.                 {
  256.                 if (NULL!=m_pObj->m_pHW)
  257.                     ShowWindow(m_pObj->m_pHW->Window(), SW_HIDE);
  258.                 return NOERROR; //Already active
  259.                 }
  260.             if (m_pObj->m_fAllowInPlace)
  261.                 {
  262.                 if (SUCCEEDED(m_pObj->InPlaceActivate(pActiveSite
  263.                     , TRUE)))
  264.                     return NOERROR;
  265.                 }
  266.             //FALL THROUGH
  267.         //End CHAPTER23MOD
  268.         case OLEIVERB_OPEN:
  269.             //CHAPTER23MOD
  270.             if (NULL!=m_pObj->m_pIOleIPSite)
  271.                 {
  272.                 m_pObj->InPlaceDeactivate();
  273.                 m_pObj->m_fAllowInPlace=FALSE;
  274.                 }
  275.             //End CHAPTER23MOD
  276.             /*
  277.              * If we're not running, make sure we are.  In any
  278.              * case, make the dialog visible and insure it has
  279.              * the right parent now.
  280.              */
  281.             hr=NOERROR;
  282.             if (NULL==m_pObj->m_hDlg)
  283.                 hr=m_pObj->m_pImpIRunnableObject->Run(NULL);
  284.             if (FAILED(hr) || NULL==m_pObj->m_hDlg)
  285.                 return ResultFromScode(E_OUTOFMEMORY);
  286.             ShowWindow(m_pObj->m_hDlg, SW_SHOW);
  287.             SetFocus(m_pObj->m_hDlg);
  288.             m_pObj->SendAdvise(OBJECTCODE_SHOWOBJECT);
  289.             m_pObj->SendAdvise(OBJECTCODE_SHOWWINDOW);
  290.             break;
  291.         //CHAPTER23MOD
  292.         case OLEIVERB_INPLACEACTIVATE:
  293.             if (NULL!=m_pObj->m_pHW)
  294.                 {
  295.                 HWND    hWndHW=m_pObj->m_pHW->Window();
  296.                 ShowWindow(hWndHW, SW_SHOW);
  297.                 SetFocus(hWndHW);
  298.                 return NOERROR;
  299.                 }
  300.             /*
  301.              * Only inside-out supporting containers will use
  302.              * this verb.
  303.              */
  304.             m_pObj->m_fContainerKnowsInsideOut=TRUE;
  305.             m_pObj->InPlaceActivate(pActiveSite, FALSE);
  306.             break;
  307.         case OLEIVERB_UIACTIVATE:
  308.             m_pObj->InPlaceActivate(pActiveSite, TRUE);
  309.             break;
  310.         //End CHAPTER23MOD
  311.         default:
  312.             return ResultFromScode(OLEOBJ_S_INVALIDVERB);
  313.         }
  314.     return NOERROR;
  315.     }
  316. /*
  317.  * CImpIOleObject::GetUserClassID
  318.  *
  319.  * Purpose:
  320.  *  Used for linked objects, this returns the class ID of what end
  321.  *  users think they are editing.
  322.  *
  323.  * Parameters:
  324.  *  pClsID          LPCLSID in which to store the CLSID.
  325.  *
  326.  * Return Value:
  327.  *  HRESULT         NOERROR or a general error value.
  328.  */
  329. STDMETHODIMP CImpIOleObject::GetUserClassID(LPCLSID pClsID)
  330.     {
  331.     /*
  332.      * If you are not registered to handle data other than yourself,
  333.      * then you can just return your class ID here.  If you are
  334.      * registered as usable from Treat-As dialogs, then you need to
  335.      * return the CLSID of what you are really editing.
  336.      */
  337.     *pClsID=CLSID_Polyline19;
  338.     return NOERROR;
  339.     }
  340. /*
  341.  * CImpIOleObject::SetExtent
  342.  *
  343.  * Purpose:
  344.  *  Sets the size of the object in HIMETRIC units.  Since we're in
  345.  *  a dialog, the size of the object in us is fixed, so we ignore
  346.  *  this call.
  347.  *
  348.  * Parameters:
  349.  *  dwAspect        DWORD of the aspect affected.
  350.  *  pszl            LPSIZEL containing the new size.
  351.  *
  352.  * Return Value:
  353.  *  HRESULT         NOERROR or a general error value.
  354.  */
  355. STDMETHODIMP CImpIOleObject::SetExtent(DWORD dwAspect
  356.     , LPSIZEL pszl)
  357.     {
  358.     //Ignored:  no size change in the dialog.
  359.     return NOERROR;
  360.     }
  361. /*
  362.  * CImpIOleObject::GetExtent
  363.  *
  364.  * Purpose:
  365.  *  Retrieves the size of the object in HIMETRIC units.
  366.  *
  367.  * Parameters:
  368.  *  dwAspect        DWORD of the aspect requested
  369.  *  pszl            LPSIZEL into which to store the size.
  370.  *
  371.  * Return Value:
  372.  *  HRESULT         NOERROR or a general error value.
  373.  */
  374. STDMETHODIMP CImpIOleObject::GetExtent(DWORD dwAspect, LPSIZEL pszl)
  375.     {
  376.     //Delegate directly to IViewObject2::GetExtent
  377.     return m_pObj->m_pImpIViewObject->GetExtent(dwAspect, -1
  378.         , NULL, pszl);
  379.     }
  380. /*
  381.  * CImpIOleObject::Advise
  382.  * CImpIOleObject::Unadvise
  383.  * CImpIOleObject::EnumAdvise
  384.  *
  385.  * Purpose:
  386.  *  Advisory connection functions.
  387.  */
  388. STDMETHODIMP CImpIOleObject::Advise(LPADVISESINK pIAdviseSink
  389.     , LPDWORD pdwConn)
  390.     {
  391.     if (NULL==m_pObj->m_pIOleAdviseHolder)
  392.         {
  393.         HRESULT     hr;
  394.         hr=CreateOleAdviseHolder(&m_pObj->m_pIOleAdviseHolder);
  395.         if (FAILED(hr))
  396.             return hr;
  397.         }
  398.     return m_pObj->m_pIOleAdviseHolder->Advise(pIAdviseSink
  399.         , pdwConn);
  400.     }
  401. STDMETHODIMP CImpIOleObject::Unadvise(DWORD dwConn)
  402.     {
  403.     if (NULL!=m_pObj->m_pIOleAdviseHolder)
  404.         return m_pObj->m_pIOleAdviseHolder->Unadvise(dwConn);
  405.     return ResultFromScode(E_FAIL);
  406.     }
  407. STDMETHODIMP CImpIOleObject::EnumAdvise(LPENUMSTATDATA *ppEnum)
  408.     {
  409.     if (NULL!=m_pObj->m_pIOleAdviseHolder)
  410.         return m_pObj->m_pIOleAdviseHolder->EnumAdvise(ppEnum);
  411.     return ResultFromScode(E_FAIL);
  412.     }
  413. /*
  414.  * CImpIOleObject::SetMoniker
  415.  *
  416.  * Purpose:
  417.  *  Informs the object of its moniker or its container's moniker
  418.  *  depending on dwWhich.
  419.  *
  420.  * Parameters:
  421.  *  dwWhich         DWORD describing whether the moniker is the
  422.  *                  object's or the container's.
  423.  *  pmk             LPMONIKER with the name.
  424.  *
  425.  * Return Value:
  426.  *  HRESULT         NOERROR or a general error value.
  427.  */
  428. STDMETHODIMP CImpIOleObject::SetMoniker(DWORD dwWhich
  429.     , LPMONIKER pmk)
  430.     {
  431.     LPMONIKER       pmkFull;
  432.     HRESULT         hr=ResultFromScode(E_FAIL);
  433.     if (NULL!=m_pObj->m_pIOleClientSite)
  434.         {
  435.         hr=m_pObj->m_pIOleClientSite->GetMoniker
  436.             (OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_OBJFULL
  437.             , &pmkFull);
  438.         }
  439.     if (SUCCEEDED(hr))
  440.         {
  441.         if (NOERROR==pmkFull->IsRunning(NULL, NULL, NULL))
  442.             {
  443.             pmkFull->Release();
  444.             return NOERROR;
  445.             }
  446.         //This will revoke the old one if m_dwRegROT is nonzero.
  447.         INOLE_RegisterAsRunning(m_pObj, pmkFull, 0
  448.             , &m_pObj->m_dwRegROT);
  449.         //Inform clients of the new moniker
  450.         if (NULL!=m_pObj->m_pIOleAdviseHolder)
  451.             m_pObj->m_pIOleAdviseHolder->SendOnRename(pmkFull);
  452.         pmkFull->Release();
  453.         }
  454.     return hr;
  455.     }
  456. /*
  457.  * CImpIOleObject::GetMoniker
  458.  *
  459.  * Purpose:
  460.  *  Asks the object for a moniker that can later be used to
  461.  *  reconnect to it.
  462.  *
  463.  * Parameters:
  464.  *  dwAssign        DWORD determining how to assign the moniker to
  465.  *                  to the object.
  466.  *  dwWhich         DWORD describing which moniker the caller wants.
  467.  *  ppmk            LPMONIKER * into which to store the moniker.
  468.  *
  469.  * Return Value:
  470.  *  HRESULT         NOERROR or a general error value.
  471.  */
  472. STDMETHODIMP CImpIOleObject::GetMoniker(DWORD dwAssign
  473.     , DWORD dwWhich, LPMONIKER *ppmk)
  474.     {
  475.     HRESULT         hr=ResultFromScode(E_FAIL);
  476.     *ppmk=NULL;
  477.     /*
  478.      * Since we only support embedded objects, our moniker
  479.      * is always the full moniker from the contianer.
  480.      */
  481.     if (NULL!=m_pObj->m_pIOleClientSite)
  482.         {
  483.         hr=m_pObj->m_pIOleClientSite->GetMoniker
  484.             (OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_OBJFULL, ppmk);
  485.         }
  486.     return (NULL!=*ppmk) ? NOERROR : hr;
  487.     }
  488. //Methods not implemented or trivial
  489. STDMETHODIMP CImpIOleObject::InitFromData(LPDATAOBJECT pIDataObject
  490.     , BOOL fCreation, DWORD dw)
  491.     {
  492.     return ResultFromScode(E_NOTIMPL);
  493.     }
  494. STDMETHODIMP CImpIOleObject::GetClipboardData(DWORD dwReserved
  495.     , LPDATAOBJECT *ppIDataObj)
  496.     {
  497.     return ResultFromScode(E_NOTIMPL);
  498.     }
  499. STDMETHODIMP CImpIOleObject::Update(void)
  500.     {
  501.     return NOERROR;
  502.     }
  503. STDMETHODIMP CImpIOleObject::IsUpToDate(void)
  504.     {
  505.     return NOERROR;
  506.     }
  507. STDMETHODIMP CImpIOleObject::SetColorScheme(LPLOGPALETTE pLP)
  508.     {
  509.     return ResultFromScode(E_NOTIMPL);
  510.     }
  511. //Methods implemented using registry helper functions in OLE.
  512. STDMETHODIMP CImpIOleObject::EnumVerbs(LPENUMOLEVERB *ppEnum)
  513.     {
  514.     return OleRegEnumVerbs(m_pObj->m_clsID, ppEnum);
  515.     }
  516. STDMETHODIMP CImpIOleObject::GetUserType(DWORD dwForm
  517.     , LPOLESTR *ppszType)
  518.     {
  519.     return OleRegGetUserType(m_pObj->m_clsID, dwForm, ppszType);
  520.     }
  521. STDMETHODIMP CImpIOleObject::GetMiscStatus(DWORD dwAspect
  522.     , LPDWORD pdwStatus)
  523.     {
  524.     return OleRegGetMiscStatus(m_pObj->m_clsID, dwAspect
  525.         , pdwStatus);
  526.     }