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

Windows编程

开发平台:

Visual C++

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