home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / BOCOLE.PAK / BOLESITE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  64.0 KB  |  2,444 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectComponents
  3. // Copyright (c) 1994, 1996 by Borland International, All Rights Reserved
  4. //
  5. // $Revision:   2.10  $
  6. //
  7. //  Implements the Bolero half of the OLE2 server object. BOleSite objects 
  8. //  impersonate the client application from the point of view of the Bolero 
  9. //  customer who's writing a server object (IPart)
  10. //----------------------------------------------------------------------------
  11. #include "BOle.h"
  12. #include "BOleSite.h"
  13. #include "BOleDoc.h"
  14. #include "BOleCMan.h"
  15.  
  16. extern "C" {
  17.   #include "ole2ui.h"
  18. }
  19.  
  20. // System/RTL headers
  21. //
  22.  
  23.  
  24.  
  25. #define NOT_IMPLEMENTED OLERET(E_NOTIMPL);
  26.  
  27.  
  28. HRESULT _IFUNC BOleSite::QueryInterfaceMain(REFIID iid, LPVOID FAR *ppv)
  29. {
  30.   HRESULT hr = ResultFromScode(E_NOINTERFACE);
  31.   *ppv = NULL;
  32.  
  33.   // Self
  34.   //
  35.   if (IID_BOleSite == iid) {
  36.     (BOleSite *)*ppv = this;
  37.     AddRef();
  38.     return NOERROR;
  39.   }
  40.   // nested interface class
  41.  
  42.   if (IID_IBApplication == iid) {
  43.     ((IBApplication *)*ppv) = &iApplication;
  44.     AddRef();
  45.     return NOERROR;
  46.   }
  47.  
  48.   // interfaces
  49.   if (SUCCEEDED(hr = IBContainer_QueryInterface(this, iid, ppv))) {
  50.   }
  51.   else if (SUCCEEDED(hr = IBLinkable_QueryInterface(this, iid, ppv))) {
  52.   }
  53.   else if (SUCCEEDED(hr = IPersistStorage_QueryInterface(this, iid, ppv))) {
  54.   }
  55.   else if (SUCCEEDED(hr = IDataObject_QueryInterface(this, iid, ppv))) {
  56.   }
  57.   else if (SUCCEEDED(hr = IDropSource_QueryInterface(this, iid, ppv))) {
  58.   }
  59.   else if (SUCCEEDED(hr = IOleObject_QueryInterface(this, iid, ppv))) {
  60.   }
  61.   else if (SUCCEEDED(hr = IOleInPlaceObject_QueryInterface(this, iid, ppv))) {
  62.   }
  63.   else if (SUCCEEDED(hr = IOleInPlaceActiveObject_QueryInterface(this, iid, ppv))) {
  64.   }
  65.   else if (SUCCEEDED(hr = IBSite_QueryInterface(this, iid, ppv))) {
  66.   }
  67.   else if (SUCCEEDED(hr = IEnumFORMATETC_QueryInterface(this, iid, ppv))) {
  68.   }
  69.   else if (SUCCEEDED(hr = IBDataState_QueryInterface(this, iid, ppv))) {
  70.   }
  71.  
  72.   // base classes
  73.   else if (SUCCEEDED(hr = BOleComponent::QueryInterfaceMain(iid, ppv))) {
  74.   }
  75.  
  76.   return hr;
  77. };
  78.  
  79.  
  80. //
  81. // BOleSite implementation --    These functions aren't part of an inherited
  82. //             interface, but are part of the private
  83. //             implementation of BOleSite
  84. //
  85.  
  86. BOleSite::BOleSite(BOleClassManager * pFact, IBUnknownMain *pOuter,
  87.        BOleService *pSvc)
  88.   : BOleComponent (pFact, pOuter) , iApplication(this, pOuter),
  89.     cid (CLSID_NULL)
  90. {
  91.   pService = pSvc;
  92.  
  93. #ifdef OLEDBG
  94.   DebugMode = 0;
  95. #endif
  96.  
  97.   pClientSite = NULL;
  98.   pStg = NULL;
  99.   pDAdvHolder = NULL;
  100.   pAdvHolder = NULL;
  101.   pPart = NULL;  //    (IPart *) pOuter->InterfaceGet(IID(IPart));
  102.   pProvider = NULL;
  103.   pIPSite = 0;
  104.   pIPFrame = 0;
  105.   pIPDoc = 0;
  106.   fShown = FALSE;
  107.   fInPlaceActive = FALSE;
  108.   fInPlaceVisible = FALSE;
  109.   fInsideOut = FALSE;
  110.   fUIActive = FALSE;
  111.   fInHelpMode = FALSE;
  112.   fInClose = FALSE;
  113.   hWndParent = 0;
  114.   pHatchWnd = NULLP;
  115.   hWndInPlace = 0;
  116.   hOleMenu = 0;
  117.   hMenuShared = 0;
  118.   pszProgID = NULLP;
  119.   pmkDoc = NULLP;
  120.   hatchOffset.x = hatchOffset.y = 0;
  121.   pFactory->ServerCount(+1L);
  122.   regLink = 0L;
  123.   pszInstName = NULL;
  124.   pWindowTitle = NULL;
  125.   pAppName = NULL;
  126.   fHandsOff = FALSE;
  127.   fIsDirty = TRUE;
  128.   formatList = NULL;
  129.   formatCount = 0;
  130.   formatLink = TRUE;     // default pending moniker existence
  131.   formatEmbed = TRUE;
  132.   pInPlaceName = NULL;
  133.   pDocument = NULL;
  134. }
  135.  
  136. HRESULT _IFUNC BOleSite::Init (PIBDataProvider pProv, PIBPart ppart, LPCOLESTR psz, BOOL fHatchWnd)
  137. {
  138.   // If the provider also supports IBPart, then it's a full-fledged
  139.   // server object capable of inplace activation. If it doesn't, this
  140.   // BOleSite will only be used for data transfer.
  141.   //
  142.   pProvider = pProv;
  143.   pPart = ppart;
  144.  
  145.   // Bind to BOleFact so we can get the CLSID
  146.   //
  147.   if (pszProgID != NULLP)
  148.     delete pszProgID;
  149.   pszProgID = new OLECHAR [lstrlen(psz) + 1];
  150.   if (!pszProgID)
  151.     return ResultFromScode (E_OUTOFMEMORY);
  152.   lstrcpy (pszProgID, psz);
  153.  
  154.   CLSIDFromProgID(pszProgID, &cid);
  155.  
  156.   // Cache the available formats because OLE2 will ask for formats
  157.   // during link/embed from file, even though no Clip or Drag
  158.   // happened.
  159.   //
  160.   pService->FormatHelper (&formatList, &formatCount, formatLink,
  161.           formatEmbed, pProvider);
  162.  
  163.   // Create a hatched window which is visible during visual editing
  164.   //
  165.   if (pPart && fHatchWnd) {
  166.     //pHatchWnd = BOleHatchWindow::Create (NULL, boleInst, this);
  167.     pHatchWnd = new BOleHatchWindow(NULL, boleInst, this);
  168.     if (!pHatchWnd || !(HANDLE)pHatchWnd)
  169.       return ResultFromScode (E_OUTOFMEMORY);
  170.   }
  171.  
  172.   // Catenate the APPNAME and the SHORTUSERTYPENAME together. This seems
  173.   // to be the convention for SetActiveObject
  174.   //
  175.   LPOLESTR appname = NULL, shortname = NULL;
  176.   int c = 0;
  177.   OleRegGetUserType (cid, USERCLASSTYPE_APPNAME, &appname);
  178.   if (appname)
  179.     c += lstrlen (appname) + lstrlen (OLESTR (" - "));
  180.   OleRegGetUserType (cid, USERCLASSTYPE_SHORT, &shortname);
  181.   if (shortname)
  182.     c += lstrlen (shortname);
  183.  
  184.   pInPlaceName = new OLECHAR [c + 1]; // +1 for null term
  185.   if (!pInPlaceName)
  186.     return ResultFromScode (E_OUTOFMEMORY);
  187.   pInPlaceName[0] = 0;
  188.  
  189.   if (appname) {
  190.     lstrcat (pInPlaceName, appname);
  191.     lstrcat (pInPlaceName, OLESTR(" - ") );
  192.   }
  193.   if (shortname)
  194.     lstrcat (pInPlaceName, shortname);
  195.  
  196.   IMalloc *pMalloc;
  197.   if (SUCCEEDED(CoGetMalloc(MEMCTX_TASK, &pMalloc))) {
  198.     pMalloc->Free(appname);
  199.     pMalloc->Free(shortname);
  200.     pMalloc->Release();
  201.   }
  202.  
  203.   return NOERROR;
  204. }
  205.  
  206. BOleSite::~BOleSite ()
  207. {
  208.   // Don't translate any more accelerators through this helper
  209.   //
  210.   if (pService->pFocusedSite == this)
  211.     OnSetFocus (NULL);
  212.  
  213.   DoClose();
  214.  
  215.   // Release the client site here (not in DoClose) so that we can in place
  216.   // activate after an open-edit session  (Dll server case).
  217.   //
  218.   if (pClientSite) {
  219.     pClientSite->Release ();
  220.     pClientSite = NULL;
  221.   }
  222.   if (pWindowTitle) {
  223.     delete [] pWindowTitle;
  224.     pWindowTitle = NULL;
  225.   }
  226.   if (pAppName) {
  227.     delete [] pAppName;
  228.     pAppName = NULL;
  229.   }
  230.   if (pszProgID) {
  231.     delete pszProgID;
  232.     pszProgID = NULL;
  233.   }
  234.   if (pHatchWnd) {
  235.     delete pHatchWnd;
  236.     pHatchWnd = NULL;
  237.   }
  238.   if (pDocument) {  // Set in BOleContainer::GetObject
  239.     CoLockObjectExternal(pDocument, FALSE, FALSE);
  240.     pDocument = NULL;
  241.     }
  242.   if (pmkDoc) {
  243.     pmkDoc->Release();
  244.     pmkDoc = NULL;
  245.   }
  246.   if (pszInstName) {
  247.     delete [] pszInstName;
  248.     pszInstName = NULL;
  249.   }
  250.   if (pInPlaceName) {
  251.     delete [] pInPlaceName;
  252.     pInPlaceName = NULL;
  253.   }
  254.   if (formatList) {
  255.     delete [] formatList;
  256.   }
  257.   pFactory->ServerCount(-1L);
  258.  
  259. }
  260.  
  261. //
  262. // Accessor functions for format lists
  263. //
  264. void _IFUNC BOleSite::GetFormatFlags(BOOL *pfEmbed, BOOL *pfLink)
  265. {
  266.   if (pService->dropCount || (pService->clipCount && pService->IsOnClipboard(this))) {
  267.     *pfLink  = pService->fUseDropList ? pService->dropOkToLink  : pService->clipOkToLink;
  268.     *pfEmbed = pService->fUseDropList ? pService->dropOkToEmbed : pService->clipOkToEmbed;
  269.   }
  270.   else {
  271.     if (!formatList) {
  272.       // Cache the available formats because OLE2 will ask for formats
  273.       // during link/embed from file, even though no Clip or Drag
  274.       // happened.
  275.       pService->FormatHelper (&formatList, &formatCount, formatLink,
  276.             formatEmbed, pProvider);
  277.     }
  278.     *pfLink = formatLink;
  279.     *pfEmbed = formatEmbed;
  280.   }
  281.  
  282.   if (fInClose) 
  283.     *pfLink = FALSE; // no link format available after shutdown
  284.  
  285. }
  286.  
  287. void _IFUNC BOleSite::GetFormatList(LPFORMATETC *ppList, UINT *pCount)
  288. {
  289.   if (pService->dropCount || (pService->clipCount && pService->IsOnClipboard(this))) {
  290.     *ppList = pService->fUseDropList ? pService->dropList : pService->clipList;
  291.     *pCount = pService->fUseDropList ? pService->dropCount : pService->clipCount;
  292.   }
  293.   else {
  294.     if (!formatList) {
  295.       // Cache the available formats because OLE2 will ask for formats
  296.       // during link/embed from file, even though no Clip or Drag
  297.       // happened.
  298.       pService->FormatHelper (&formatList, &formatCount, formatLink,
  299.             formatEmbed, pProvider);
  300.     }
  301.     *ppList = formatList;
  302.     *pCount = formatCount;
  303.   }
  304. }
  305.  
  306. void _IFUNC BOleSite::GetFormatCount(UINT *pCount)
  307. {
  308.   if (pService->dropCount || (pService->clipCount && pService->IsOnClipboard(this))) {
  309.     *pCount = pService->fUseDropList ? pService->dropCount : pService->clipCount;
  310.   }
  311.   else {
  312.     if (!formatList) {
  313.       // Cache the available formats because OLE2 will ask for formats
  314.       // during link/embed from file, even though no Clip or Drag
  315.       // happened.
  316.       pService->FormatHelper (&formatList, &formatCount, formatLink,
  317.             formatEmbed, pProvider);
  318.     }
  319.     *pCount = formatCount;
  320.   }
  321. }
  322.  
  323. void _IFUNC BOleSite::GetFormatInfo(BOOL *pfEmbed, BOOL *pfLink, LPFORMATETC *ppList, UINT *pCount)
  324. {
  325.   if (pService->dropCount || (pService->clipCount && pService->IsOnClipboard(this))) {
  326.     *pfLink = pService->fUseDropList ? pService->dropOkToLink : pService->clipOkToLink;
  327.     *pfEmbed = pService->fUseDropList ? pService->dropOkToEmbed : pService->clipOkToEmbed;
  328.     *ppList = pService->fUseDropList ? pService->dropList : pService->clipList;
  329.     *pCount = pService->fUseDropList ? pService->dropCount : pService->clipCount;
  330.   }
  331.   else {
  332.     if (!formatList) {
  333.       // Cache the available formats because OLE2 will ask for formats
  334.       // during link/embed from file, even though no Clip or Drag
  335.       // happened.
  336.       pService->FormatHelper (&formatList, &formatCount, formatLink,
  337.                   formatEmbed, pProvider);
  338.     }
  339.     *pfLink = formatLink;
  340.     *pfEmbed = formatEmbed;
  341.     *ppList = formatList;
  342.     *pCount = formatCount;
  343.   }
  344. }
  345.  
  346. // Render this server object onto a storage medium.
  347. //
  348. HRESULT _IFUNC BOleSite::GetEmbeddedObjectData (LPFORMATETC pFmt, LPSTGMEDIUM pMed)
  349. {
  350.   LPSTORAGE   lpstg = NULL;
  351.   SCODE       sc = S_OK;
  352.   HRESULT     hrErr;
  353.  
  354.   pMed->pUnkForRelease = NULL;
  355.  
  356.   if (pMed->tymed == TYMED_NULL) {
  357.  
  358.     // If the tymed passed in is NULL, we will create a temporary storage
  359.     // in memory in order to render the object
  360.     //
  361.     if (pFmt->tymed & TYMED_ISTORAGE) {
  362.       lpstg = CreateStorageInMemory (STGM_READWRITE
  363.         | STGM_TRANSACTED | STGM_SHARE_EXCLUSIVE /*| STGM_DELETEONRELEASE??*/);
  364.       if (!lpstg)
  365.         return ResultFromScode(E_OUTOFMEMORY);
  366.  
  367.       pMed->pstg = lpstg;
  368.       pMed->tymed = TYMED_ISTORAGE;
  369.       pMed->pUnkForRelease = NULL;
  370.     }
  371.     else
  372.       return ResultFromScode(DATA_E_FORMATETC);
  373.   }
  374.  
  375.   // If the tymed passed in is non-NULL, we will use the storage they
  376.   // gave us. If it's not a storage, return failure.
  377.   //
  378.   else if (pMed->tymed & TYMED_ISTORAGE) {
  379.     pMed->tymed = TYMED_ISTORAGE;
  380.  
  381.     // The online dox say that OleSave does this, but there's no
  382.     // CompObj stream without WriteFmtUseTypeStg and no CLSID in the
  383.     // stream without WriteClassStg
  384.     //
  385.     CLSID clsid = CLSID_NULL;
  386.     CLSIDFromProgID (pszProgID, &clsid);
  387.     if ((hrErr = WriteClassStg (pMed->pstg, clsid)) != NOERROR)
  388.       return hrErr;
  389.     LPOLESTR lpLongType = NULL;
  390.     OleRegGetUserType (clsid, USERCLASSTYPE_FULL, &lpLongType);
  391.     hrErr = WriteFmtUserTypeStg (pMed->pstg, pFmt->cfFormat, lpLongType);
  392.   }
  393.   else
  394.     return ResultFromScode(DATA_E_FORMATETC);
  395.  
  396.   // We don't really expect anyone to respond to this call, but WPWin
  397.   // is going to try to decide whether a new object is linked or embedded
  398.   // based on this notification.
  399.   //
  400.   BOleFormat f;
  401.   f.fmtId = BOleDocument::oleEmbSrcClipFmt;
  402.   f.fmtMedium = BOLE_MED_STORAGE;
  403.   f.fmtName[0] = 0;
  404.   f.fmtResultName[0] = 0;
  405.   f.fmtIsLinkable = FALSE;
  406.   pProvider->GetFormatData (&f);
  407.  
  408.   hrErr = OleSave(this, pMed->pstg, FALSE /* fSameAsLoad */);
  409.   if (hrErr != NOERROR)
  410.     sc = GetScode(hrErr);
  411.  
  412.   // Always call SaveCompleted, but don't stomp the error code if
  413.   // OleSave failed
  414.   //
  415.   hrErr = SaveCompleted (NULL);
  416.   if (hrErr != NOERROR && sc == S_OK)
  417.     sc = GetScode(hrErr);
  418.  
  419.   return ResultFromScode(sc);
  420. }
  421.  
  422. // Render the data for a link source into a stream medium
  423. //
  424. HRESULT _IFUNC BOleSite::GetLinkSourceData(LPMONIKER lpmk, REFCLSID cid,
  425.     LPFORMATETC lpformatetc, LPSTGMEDIUM lpMedium)
  426. {
  427.   LPSTREAM    lpstm = NULL;
  428.   HRESULT     hrErr;
  429.  
  430.   // We don't really expect anyone to respond to this call, but WPWin
  431.   // is going to try to decide whether a new object is linked or embedded
  432.   // based on this notification.
  433.   //
  434.   BOleFormat f;
  435.   f.fmtId = BOleDocument::oleLinkSrcClipFmt;
  436.   f.fmtMedium = BOLE_MED_STREAM;
  437.   f.fmtName[0] = 0;
  438.   f.fmtResultName[0] = 0;
  439.   f.fmtIsLinkable = TRUE;
  440.   pProvider->GetFormatData (&f);
  441.  
  442.   if (lpMedium->tymed == TYMED_NULL) {
  443.     if (lpformatetc->tymed & TYMED_ISTREAM) {
  444.       hrErr = CreateStreamOnHGlobal(
  445.           NULL, // auto allocate
  446.           TRUE, // delete on release
  447.           (LPSTREAM FAR*)&lpstm
  448.       );
  449.       if (hrErr != NOERROR) {
  450.         lpMedium->pUnkForRelease = NULL;
  451.         return ResultFromScode (E_OUTOFMEMORY);
  452.       }
  453.       lpMedium->pstm = lpstm;
  454.       lpMedium->tymed = TYMED_ISTREAM;
  455.       lpMedium->pUnkForRelease = NULL;
  456.     }
  457.     else {
  458.       lpMedium->pUnkForRelease = NULL;
  459.       return ResultFromScode (DATA_E_FORMATETC);
  460.     }
  461.   }
  462.   else {
  463.     if (lpMedium->tymed & TYMED_ISTREAM) {
  464.       lpMedium->tymed = TYMED_ISTREAM;
  465.       lpMedium->pstm = lpMedium->pstm;
  466.       lpMedium->pUnkForRelease = NULL;
  467.     }
  468.     else {
  469.       lpMedium->pUnkForRelease = NULL;
  470.       return ResultFromScode (DATA_E_FORMATETC);
  471.     }
  472.   }
  473.  
  474.   hrErr = OleSaveToStream((LPPERSISTSTREAM)lpmk, lpMedium->pstm);
  475.   if (hrErr != NOERROR)
  476.     return hrErr;
  477.   return WriteClassStm (lpMedium->pstm, cid);
  478. }
  479.  
  480. // Creates an LPSTORAGE with the specified flags on a memory lockbytes
  481. //
  482. LPSTORAGE _IFUNC BOleSite::CreateStorageInMemory (DWORD grfMode)
  483. {
  484.   DWORD grfCreateMode =grfMode | STGM_CREATE;
  485.   HRESULT hrErr;
  486.   LPLOCKBYTES lpLockBytes = NULL;
  487.   DWORD reserved = 0;
  488.   LPSTORAGE lpStg = NULL;
  489.  
  490.   hrErr = CreateILockBytesOnHGlobal(NULL, TRUE /*delete on release*/,
  491.     &lpLockBytes);
  492.   if (hrErr != NOERROR)
  493.     return NULL;
  494.  
  495.   hrErr = StgCreateDocfileOnILockBytes(lpLockBytes, grfCreateMode,
  496.     reserved, &lpStg);
  497.   if (hrErr != NOERROR) {
  498.     lpLockBytes->Release();
  499.     return NULL;
  500.   }
  501.   lpLockBytes->Release();
  502.   return lpStg;
  503. }
  504.  
  505. //**************************************************************************
  506. //
  507. // IDataObject implementation
  508. //
  509. //**************************************************************************
  510.  
  511. HRESULT _IFUNC BOleSite::GetData (LPFORMATETC pFormatEtcIn, LPSTGMEDIUM pMedium)
  512. {
  513.   TCHAR name[32];
  514.   GetClipboardFormatName (pFormatEtcIn->cfFormat, name, sizeof(name));
  515.  
  516.   HRESULT hrErr = ResultFromScode (DATA_E_FORMATETC);
  517.  
  518.   BOOL fLink = TRUE;
  519.   BOOL fEmbed = TRUE;
  520.  
  521.   GetFormatFlags(&fEmbed, &fLink);
  522.     
  523.   if (pFormatEtcIn->dwAspect & (DVASPECT_CONTENT | DVASPECT_DOCPRINT)) {
  524.  
  525.     pMedium->tymed    = 0L;
  526.     pMedium->pUnkForRelease = NULL;
  527.     pMedium->hGlobal  = NULL;
  528.  
  529.     if (pFormatEtcIn->cfFormat == BOleDocument::oleEmbSrcClipFmt) {
  530.       if( fEmbed )
  531.         hrErr = GetEmbeddedObjectData (pFormatEtcIn, pMedium);
  532.     }
  533.     else if (pFormatEtcIn->cfFormat == BOleDocument::oleObjectDescFmt) {
  534.       if( fEmbed )
  535.         goto _getobjdesc;
  536.     }
  537.     else if (pFormatEtcIn->cfFormat == BOleDocument::oleLinkSrcClipFmt) {
  538.       if( fLink ) {
  539.         LPMONIKER pMon;
  540.         hrErr = GetMoniker(OLEGETMONIKER_ONLYIFTHERE,OLEWHICHMK_OBJFULL, &pMon);
  541.         if (SUCCEEDED(hrErr)) {
  542.           CLSID id;
  543.           hrErr = GetUserClassID(&id);
  544.           pMedium->tymed = TYMED_NULL;    // for GetLinkSourceData
  545.           pFormatEtcIn->cfFormat = BOleDocument::oleLinkSrcClipFmt; // per Brockshmit's suggestion
  546.           pFormatEtcIn->tymed = TYMED_ISTREAM;    // pg. 773
  547.           if (SUCCEEDED(hrErr)) {
  548.             hrErr = GetLinkSourceData(pMon, id, pFormatEtcIn, pMedium);
  549.           }
  550.         pMon->Release();
  551.         }
  552.       }
  553.     }
  554.     else if (pFormatEtcIn->cfFormat == BOleDocument::oleLinkSrcDescFmt) {
  555.       if( fLink ) {
  556. _getobjdesc:;
  557.         // Object descriptors *must* be returned in a memory handle
  558.         //
  559.         if (pFormatEtcIn->tymed & TYMED_HGLOBAL) {
  560.           pMedium->hGlobal = GetObjDescData ();
  561.           if (pMedium->hGlobal) {
  562.             pMedium->tymed = TYMED_HGLOBAL;
  563.             hrErr = ResultFromScode (S_OK);
  564.           }
  565.           else
  566.             hrErr = ResultFromScode (E_OUTOFMEMORY);
  567.         }
  568.       }
  569.     }
  570.     else if (pFormatEtcIn->cfFormat == CF_METAFILEPICT && (pFormatEtcIn->tymed & TYMED_MFPICT)) {
  571.       hrErr = GetMetaFileData (pMedium->hGlobal);
  572.       if (hrErr == NOERROR)
  573.         pMedium->tymed = TYMED_MFPICT;
  574.     }
  575.     // It's not an OLE2 format, maybe it's a regular clipboard format
  576.     // the client would know.
  577.     //
  578.     else {
  579.       BOleFormat boleFmt;
  580.       memset(&boleFmt, 0, sizeof(boleFmt));
  581.       boleFmt.fmtId = pFormatEtcIn->cfFormat;
  582.       boleFmt.fmtMedium = (BOleMedium) pFormatEtcIn->tymed;
  583.  
  584.       //PHP It would be more efficient to use our list of formats
  585.       //from enumFormatEtc to check before calling GetFormatData
  586.  
  587.       if (pMedium) {
  588.         pMedium->hGlobal = pProvider->GetFormatData (&boleFmt);
  589.         if (pMedium->hGlobal) {
  590.           pMedium->tymed = boleFmt.fmtMedium & ~BOLE_MED_STATIC;
  591.         }
  592.       }
  593.  
  594.       if (pMedium->hGlobal)
  595.         hrErr = ResultFromScode (S_OK);
  596.     }
  597.   }
  598.  
  599.   return hrErr;
  600. }
  601.  
  602. #ifdef TESTMETAFILE
  603. extern HINSTANCE boleInst;
  604.  
  605. void RenderMetaFile(HGLOBAL hMFPict)
  606. {
  607.   LPMETAFILEPICT pMFPict = (LPMETAFILEPICT)    GlobalLock (hMFPict);
  608.   int xPix = MAP_LOGHIM_TO_PIX (pMFPict->xExt, BOleService::pixPerIn.x);
  609.   int yPix = MAP_LOGHIM_TO_PIX (pMFPict->yExt, BOleService::pixPerIn.y);
  610.  
  611.   HWND w = GetDesktopWindow();
  612.  
  613.   if (w) {
  614.     HDC dc = GetDC (w);
  615.     UINT oldMapMode = SetMapMode(dc, MM_ANISOTROPIC);
  616.     SetWindowExt (dc, 1000, 1000);
  617.     SetViewportExt (dc, xPix, yPix);
  618.     PlayMetaFile (dc, pMFPict->hMF);
  619.     SetMapMode (dc, oldMapMode);
  620.     ReleaseDC(w, dc);
  621.     GlobalUnlock (hMFPict);
  622.     }
  623. }
  624.  
  625. #endif
  626.  
  627. HRESULT _IFUNC BOleSite::GetMetaFileData (HGLOBAL& hMem)
  628. {
  629.   HRESULT hrErr = NOERROR;
  630.   HDC hDC = CreateMetaFile(NULL);
  631.   if (hDC) {
  632.     // Get server size in pixels
  633.     SIZE s;
  634.     pProvider->GetPartSize (&s);
  635.     // Convert server size to himetric, and set up dc for drawing
  636.     //
  637.     SIZEL sl;
  638.     sl.cx = MAP_PIX_TO_LOGHIM (s.cx, BOleService::pixPerIn.x);
  639.     sl.cy = MAP_PIX_TO_LOGHIM (s.cy, BOleService::pixPerIn.y);
  640.  
  641.     SetMapMode(hDC, MM_ANISOTROPIC);
  642.     SetWindowOrg(hDC, 0, 0);
  643.     SetWindowExt(hDC, sl.cx, sl.cy);
  644.  
  645.     RECTL rPos = {0L, 0L, sl.cx, sl.cy}, rExt = {0L, 0L, sl.cx, sl.cy};
  646.     pProvider->Draw (hDC, &rPos, &rExt, BOLE_CONTENT);
  647.     HMETAFILE hMF = CloseMetaFile (hDC);
  648.  
  649.     if (hMF) {
  650.       HGLOBAL hMFPict = ::GlobalAlloc (GMEM_SHARE|GMEM_ZEROINIT, sizeof (METAFILEPICT));
  651.       if (hMFPict) {
  652.   LPMETAFILEPICT pPict = (LPMETAFILEPICT) ::GlobalLock (hMFPict);
  653.   if (pPict) {
  654.     pPict->mm   =  MM_ANISOTROPIC;
  655.     pPict->hMF  =  hMF;
  656.     pPict->xExt =  sl.cx;
  657.     pPict->yExt =  sl.cy;  // add minus sign to make it +ve
  658.     GlobalUnlock (hMFPict);
  659.     hMem = hMFPict;
  660.   }
  661.   else {
  662.     GlobalFree (hMFPict);
  663.     DeleteMetaFile (hMF);
  664.     hrErr = ResultFromScode (E_OUTOFMEMORY);
  665.   }
  666.       }
  667.       else {
  668.   DeleteMetaFile (hMF);
  669.   hrErr = ResultFromScode (E_OUTOFMEMORY);
  670.       }
  671.     }
  672.     else
  673.       hrErr = ResultFromScode (E_OUTOFMEMORY);
  674.   }
  675. #ifdef TESTMETAFILE
  676.   if (SUCCEEDED(hrErr))
  677.     RenderMetaFile(hMem);
  678. #endif
  679.  
  680.   return hrErr;
  681. }
  682.  
  683. HRESULT _IFUNC BOleSite::GetDataHere (LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium)
  684. {
  685.   TCHAR name[32];
  686.   GetClipboardFormatName(pFormatEtc->cfFormat, name, sizeof(name));
  687.  
  688.   BOOL fLink = TRUE;
  689.   BOOL fEmbed = TRUE;
  690.  
  691.   GetFormatFlags(&fEmbed, &fLink);
  692.  
  693.   HRESULT hr = ResultFromScode(DATA_E_FORMATETC);
  694.  
  695.   if (pFormatEtc->cfFormat == BOleDocument::oleEmbSrcClipFmt)  {
  696.     if( fEmbed )
  697.       hr = GetEmbeddedObjectData (pFormatEtc, pMedium);
  698.   }
  699.   else
  700.     if (pFormatEtc->cfFormat == BOleDocument::oleLinkSrcClipFmt) {
  701.       if (fLink) {
  702.         LPMONIKER pMon;
  703.         hr = GetMoniker(OLEGETMONIKER_ONLYIFTHERE,OLEWHICHMK_OBJFULL, &pMon);
  704.         if (SUCCEEDED(hr)) {
  705.           CLSID id;
  706.           hr = GetUserClassID (&id);
  707.           pMedium->tymed = TYMED_NULL;    // for GetLinkSourceData
  708.           pFormatEtc->cfFormat = BOleDocument::oleLinkSrcClipFmt; // per Brockshmit's suggestion
  709.           pFormatEtc->tymed = TYMED_ISTREAM;    // pg. 773
  710.           if (SUCCEEDED(hr))
  711.             hr = GetLinkSourceData(pMon, id, pFormatEtc, pMedium);
  712.           pMon->Release();
  713.         }
  714.       }
  715.     }
  716.  
  717.   return hr;
  718. }
  719.  
  720. HRESULT _IFUNC BOleSite::QueryGetData (LPFORMATETC pFormatEtc)
  721. {
  722.   TCHAR name[32];
  723.   GetClipboardFormatName(pFormatEtc->cfFormat, name, sizeof(name));
  724.  
  725.   BOOL fLink = TRUE;
  726.   BOOL fEmbed = TRUE;
  727.   LPFORMATETC pList;
  728.   UINT count;
  729.  
  730.   GetFormatInfo(&fEmbed, &fLink, &pList, &count);
  731.  
  732.   HRESULT hrErr = ResultFromScode (DV_E_FORMATETC);
  733.  
  734.   if (pFormatEtc->cfFormat == BOleDocument::oleObjectDescFmt) {
  735.     if (fEmbed) {
  736.       // Object Descriptors must be offered in global handles
  737.       //
  738.       if (pFormatEtc->tymed & TYMED_HGLOBAL)
  739.         hrErr = NOERROR;
  740.       else
  741.         hrErr = ResultFromScode (DV_E_FORMATETC);
  742.     }
  743.   }
  744.  
  745.   else if (pFormatEtc->cfFormat == BOleDocument::oleLinkSrcDescFmt) {
  746.     if (fLink) {
  747.       // Link Src Desc, like Obj Desc, must be offered in a global handle
  748.       //
  749.       if (pFormatEtc->tymed & TYMED_HGLOBAL)
  750.         hrErr = NOERROR;
  751.       else
  752.         hrErr = ResultFromScode (DV_E_FORMATETC);
  753.     }
  754.   }
  755.  
  756.   for (UINT i = 0; i < count; i++) {
  757.     if ((pList[i].cfFormat == pFormatEtc->cfFormat) &&
  758.       (pList[i].tymed & pFormatEtc->tymed)) {
  759.       return ResultFromScode(S_OK);
  760.     }
  761.   }
  762.  
  763.   return hrErr;
  764. }
  765.  
  766. HRESULT _IFUNC BOleSite::GetCanonicalFormatEtc (LPFORMATETC pFormatetc, LPFORMATETC pFormatetcOut)
  767. {
  768.   if (!pFormatetcOut)
  769.     return ResultFromScode( E_INVALIDARG );
  770.  
  771.   pFormatetcOut->ptd = NULL;
  772.  
  773.   if (!pFormatetc)
  774.     return ResultFromScode (E_INVALIDARG);
  775.  
  776.   HRESULT hrErr;
  777.  
  778.   hrErr = QueryGetData (pFormatetc);
  779.   if (hrErr != NOERROR)
  780.     return hrErr;
  781.  
  782.   *pFormatetcOut = *pFormatetc;
  783.   if (!pFormatetc->ptd)
  784.     return ResultFromScode (DATA_S_SAMEFORMATETC);
  785.  
  786.   pFormatetcOut->ptd = NULL;
  787.   return NOERROR;
  788. }
  789.  
  790. // Set data into the server
  791. //
  792. HRESULT _IFUNC BOleSite::SetData (LPFORMATETC pFormatEtc, STGMEDIUM FAR* pMedium, BOOL fRelease)
  793. {
  794.   PIBDataProvider2 pProvider2 = NULL;
  795.  
  796.   // Does client implement IBDataProvider2?
  797.   //
  798.   if (!SUCCEEDED(pObjOuter->QueryInterfaceMain (IID_IBDataProvider2,&(LPVOID)pProvider2)))
  799.     NOT_IMPLEMENTED
  800.  
  801.   HRESULT hr = ResultFromScode (DATA_E_FORMATETC);
  802.  
  803.   if ((BOleMedium) pFormatEtc->tymed == BOLE_MED_HGLOBAL) {
  804.     BOleFormat boleFmt;
  805.     memset(&boleFmt, 0, sizeof(boleFmt));
  806.     boleFmt.fmtId = pFormatEtc->cfFormat;
  807.     boleFmt.fmtMedium = (BOleMedium) pFormatEtc->tymed;
  808.  
  809.     if (pMedium) {
  810.       hr = pProvider2->SetFormatData(&boleFmt, pMedium->hGlobal, FALSE);
  811.  
  812.       // Always do release here instead of in SetFormatData
  813.       //
  814.       if (fRelease)
  815.         ReleaseStgMedium(pMedium);
  816.     }
  817.   }
  818.  
  819.   pProvider2->Release();
  820.   return hr;
  821. }
  822.  
  823. HRESULT _IFUNC BOleSite::EnumFormatEtc (DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc)
  824. {
  825.   if (dwDirection == DATADIR_GET) {
  826.     *ppenumFormatEtc = this;
  827.     enumFmtIndex = 0L;
  828.     AddRef();    // caller must release
  829.     return ResultFromScode(S_OK);
  830.   }
  831.  
  832.   // I'm not sure what it would mean to call IDataObject::SetData
  833.   // on the BOleSite so it's blank until I can do more research
  834.   //
  835.   return ResultFromScode (E_FAIL);
  836. }
  837.  
  838. HRESULT _IFUNC BOleSite::DAdvise (FORMATETC FAR* pFormatetc, DWORD advf, IAdviseSink* pAdvSink, DWORD FAR* pdwConnection)
  839. {
  840.   HRESULT hrErr;
  841.  
  842.   *pdwConnection = 0;
  843.   if (pDAdvHolder == 0)
  844.     hrErr = CreateDataAdviseHolder (&pDAdvHolder);
  845.   if (pDAdvHolder)
  846.     hrErr = pDAdvHolder->Advise (this, pFormatetc, advf, pAdvSink, pdwConnection);
  847.   else
  848.     hrErr = ResultFromScode (E_OUTOFMEMORY);
  849.  
  850.   return hrErr;
  851. }
  852.  
  853. HRESULT _IFUNC BOleSite::DUnadvise (DWORD dwConnection)
  854. {
  855.   HRESULT hrErr = ResultFromScode(E_FAIL);
  856.   if (pDAdvHolder)
  857.     hrErr = pDAdvHolder->Unadvise (dwConnection);
  858.   return hrErr;
  859. }
  860.  
  861. HRESULT _IFUNC BOleSite::EnumDAdvise (IEnumSTATDATA* FAR* ppenumAdvise)
  862. {
  863.   HRESULT hrErr = ResultFromScode(E_FAIL);
  864.   if (pDAdvHolder)
  865.     hrErr = pDAdvHolder->EnumAdvise (ppenumAdvise);
  866.   return hrErr;
  867. }
  868.  
  869. //**************************************************************************
  870. //
  871. // IEnumFORMATETC implementation
  872. //
  873. //**************************************************************************
  874.  
  875. HRESULT _IFUNC BOleSite::Next (ULONG celt, FORMATETC FAR * pFE, ULONG FAR* pceltFetched)
  876. {
  877.   LPFORMATETC pList;
  878.   UINT count;
  879.  
  880.   GetFormatList(&pList, &count);
  881.  
  882.   if (pceltFetched)
  883.     *pceltFetched = 0;
  884.  
  885.   if( !celt )
  886.     return ResultFromScode (E_INVALIDARG);
  887.  
  888.   short nCopied = 0;
  889.   while ( (enumFmtIndex < count) && (nCopied < celt) ) {
  890.     pFE[nCopied] = pList[enumFmtIndex];
  891.     enumFmtIndex++;
  892.     nCopied++;
  893.     if (pceltFetched)
  894.       (*pceltFetched)++;
  895.   }
  896.   return ResultFromScode( nCopied != celt ? S_FALSE : S_OK);
  897. }
  898.  
  899. HRESULT _IFUNC BOleSite::Skip (ULONG celt)
  900. {
  901.   UINT count;
  902.   GetFormatCount(&count);
  903.  
  904.   if( celt > count )
  905.     return ResultFromScode (E_INVALIDARG);
  906.  
  907.   if( enumFmtIndex < count ) {
  908.     int diff = count - enumFmtIndex;
  909.     enumFmtIndex += celt;
  910.     return ResultFromScode (diff < celt ? S_OK : S_FALSE);
  911.   }
  912.   return ResultFromScode (S_FALSE);
  913. }
  914.  
  915. HRESULT _IFUNC BOleSite::Reset ()
  916. {
  917.   enumFmtIndex = 0L;
  918.   return ResultFromScode(S_OK);
  919. }
  920.  
  921. HRESULT _IFUNC BOleSite::Clone (IEnumFORMATETC FAR* FAR* ppenum)
  922. {
  923.   return ResultFromScode (E_NOTIMPL);
  924. }
  925.  
  926.  
  927. //**************************************************************************
  928. //
  929. // IOleObject implementation
  930. //
  931. //**************************************************************************
  932.  
  933. HRESULT _IFUNC BOleSite::SetClientSite (IOleClientSite* pCS)
  934. {
  935.   if (pClientSite)
  936.     pClientSite->Release ();
  937.   pClientSite = pCS;
  938.   if (pClientSite)
  939.     pClientSite->AddRef ();
  940.   return ResultFromScode(S_OK);
  941. }
  942.  
  943. HRESULT _IFUNC BOleSite::GetClientSite (IOleClientSite* FAR* ppClientSite)
  944. {
  945.   if (pClientSite) {
  946.     pClientSite->AddRef ();
  947.     *ppClientSite = pClientSite;
  948.     return ResultFromScode(S_OK);
  949.   }
  950.   else {
  951.     *ppClientSite = NULL;
  952.     return ResultFromScode(E_FAIL);
  953.   }
  954. }
  955.  
  956. HRESULT _IFUNC BOleSite::SetHostNames (LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)
  957. {
  958.   // Delete the old ones if any
  959.   //
  960.   if (pAppName) {
  961.     delete [] pAppName;
  962.     pAppName = NULL;
  963.   }
  964.   if (pWindowTitle) {
  965.     delete [] pWindowTitle;
  966.     pWindowTitle = NULL;
  967.   }
  968.  
  969.   // Copy the new ones into member data so they're around in case
  970.   // the part object asks for them (through IBContainer or IBApplication)
  971.   //
  972.   short c = lstrlen (szContainerApp) + 1; //+1 for \0 terminator
  973.   pAppName = new OLECHAR[c];
  974.   if (!pAppName)
  975.     return ResultFromScode (E_OUTOFMEMORY);
  976.   lstrcpyn( pAppName, szContainerApp, c );
  977.   if (szContainerObj) {       // docs say this could be NULL
  978.     c = lstrlen (szContainerObj) + 1;    //+1 for \0 terminator
  979.     pWindowTitle = new OLECHAR[c];
  980.     if (!pWindowTitle)
  981.       return ResultFromScode (E_OUTOFMEMORY);
  982.     lstrcpyn ( pWindowTitle, szContainerObj, c);
  983.   }
  984.   return NOERROR;
  985. }
  986.  
  987.  
  988. HRESULT _IFUNC BOleSite::DoClose ()
  989. {
  990.   // If closed while open in place, exit in-place mode
  991.   //
  992.   if (fInPlaceActive) {
  993.     DoInPlaceDeactivate ();
  994.   }
  995.  
  996.   // If closed while open editing, exit open edit mode
  997.   //
  998.   if (fShown) {
  999.     // pass FALSE here to not allow Lock(FALSE) to cause ::Close to be
  1000.     // called recursively in in-proc server case.
  1001.     // Unlocking is done at the end of ::Close (see comments below).
  1002.     //
  1003.     HideWindow(FALSE);
  1004.   }
  1005.  
  1006.   //    If this object is on the clipboard, render all formats
  1007.   //
  1008.   if (pService->IsOnClipboard(this))
  1009.     pService->FlushClipboardData(FALSE);
  1010.  
  1011.   // Unregister for linking
  1012.   //
  1013.   if (regLink != 0L) {
  1014.     LPRUNNINGOBJECTTABLE pROT = NULL;
  1015.     HRESULT hr = OLE::GetRunningObjectTable (0, &pROT);
  1016.     if (SUCCEEDED(hr)) {
  1017.       pROT->Revoke(regLink);
  1018.       regLink = 0L;
  1019.       pROT->Release();
  1020.     }
  1021.   }
  1022.  
  1023.   // Notify containers of exit from "running state"
  1024.   //
  1025.   if (pDAdvHolder) {
  1026.     pDAdvHolder->SendOnDataChange (this, 0, ADVF_DATAONSTOP);
  1027.     pDAdvHolder->Release ();
  1028.     pDAdvHolder = NULL;
  1029.   }
  1030.   if (pAdvHolder) {
  1031.     BOOL tmp = fInClose;
  1032.     fInClose = TRUE;
  1033.     pAdvHolder->SendOnClose ();   // SendOnClose recursively calls Close!
  1034.     pAdvHolder->Release ();
  1035.     fInClose = tmp;
  1036.     pAdvHolder = NULL;
  1037.   }
  1038.  
  1039.   // Release some remaining references to others
  1040.   //
  1041.   if (pIPSite) {
  1042.     pIPSite->Release();
  1043.     pIPSite = NULL;
  1044.   }
  1045.   if (pIPFrame) {
  1046.     pIPFrame->Release();
  1047.     pIPFrame = NULL;
  1048.   }
  1049.   if (pIPDoc) {
  1050.     pIPDoc->Release();
  1051.     pIPDoc = NULL;
  1052.   }
  1053.   if (pStg) {
  1054.     pStg->Release ();
  1055.     pStg = NULL;
  1056.   }
  1057.   return NOERROR;
  1058. }
  1059.  
  1060. HRESULT _IFUNC BOleSite::Close (DWORD dwSaveOption)
  1061. {
  1062.   HRESULT hrErr = NOERROR;
  1063.   if (fInClose)
  1064.     return NOERROR;
  1065.   AddRef();
  1066.   fInClose = TRUE;
  1067.  
  1068.   if (fIsDirty) {
  1069.     if (dwSaveOption == OLECLOSE_PROMPTSAVE) {
  1070.       if (pAppName) {
  1071.         TCHAR text[64];
  1072.         ::LoadString (boleInst, IDS_SAVEOBJ, text, sizeof text);
  1073.         UINT nResponse = MessageBox(NULL, text,
  1074.             NULL /* pAppName */, MB_ICONQUESTION | MB_YESNOCANCEL );  // rayk - fix title pAppName for win95
  1075.         switch (nResponse) {
  1076.           case IDNO:
  1077.             dwSaveOption = OLECLOSE_NOSAVE;
  1078.             break;
  1079.           case IDCANCEL:
  1080.             hrErr = ResultFromScode(OLE_E_PROMPTSAVECANCELLED); // don't close
  1081.             fInClose = FALSE;
  1082.             return hrErr;
  1083.           case IDYES:
  1084.             dwSaveOption = OLECLOSE_SAVEIFDIRTY;
  1085.             break;
  1086.         }
  1087.       }
  1088.     }
  1089.     switch (dwSaveOption) {
  1090.       case OLECLOSE_SAVEIFDIRTY:
  1091.         if (pClientSite) {
  1092.           pClientSite->SaveObject();
  1093.           fIsDirty = FALSE;
  1094.         }
  1095.         break;
  1096.       case OLECLOSE_NOSAVE:
  1097.         break;
  1098.     }
  1099.   }
  1100.  
  1101.   DoClose();
  1102.  
  1103.   // Might not have a pPart if this helper object was only used by a
  1104.   // pProvider for data transfer
  1105.   //
  1106.   if (pPart) {
  1107.     pPart->Close();
  1108.   }
  1109.  
  1110.   // This allows self embedded apps to in place activate and still shutdown
  1111.   // properly.  In self embed in place activation, default handler aggregator
  1112.   // seems to have interfaces that don't go away until a last unlock releases.
  1113.   //
  1114.   // Unfortunately, the default handler also calls IOleObject::Close
  1115.   // recursively.  Wish it would just drop those references without
  1116.   // calling Close!  or Release those references before calling close...
  1117.   //
  1118.   CoDisconnectObject(AsPIUnknown(pObjOuter), 0);
  1119.   fInClose = FALSE;
  1120.   Release();
  1121.  
  1122.   return hrErr;
  1123. }
  1124.  
  1125. HRESULT _IFUNC BOleSite::SetMoniker (DWORD dwWhichMoniker, IMoniker* pmk)
  1126. {
  1127.   HRESULT hr= ResultFromScode(E_FAIL);
  1128.   LPMONIKER pmkFull;
  1129.  
  1130.   // To play "link to embedding", we need to register this object
  1131.   // under the full moniker given by the client site.
  1132.  
  1133.   // get the running object table
  1134.   LPRUNNINGOBJECTTABLE pROT = NULL;
  1135.   hr = OLE::GetRunningObjectTable (0, &pROT);
  1136.   if (SUCCEEDED(hr)) {
  1137.     // Register the new moniker BEFORE revoking the old moniker.
  1138.     // Otherwise the object's "StubManager" gets hosed.
  1139.     //
  1140.     DWORD oldRegLink = regLink;
  1141.  
  1142.     hr = GetMoniker(OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_OBJFULL, &pmkFull);
  1143.     if (SUCCEEDED(hr)) {
  1144.       hr = pROT->Register (0, //ROTFLAGS_REGISTRATIONKEEPSALIVE,
  1145.                  AsPIUnknown(pObjOuter), pmkFull, ®Link);
  1146.       if (pAdvHolder) {
  1147.         pAdvHolder->SendOnRename (pmkFull);
  1148.       }
  1149.       pmkFull->Release();
  1150.     }
  1151.     else
  1152.       regLink = 0L;
  1153.  
  1154.     // release any old running object table registration
  1155.     if (oldRegLink != 0L) {
  1156.       pROT->Revoke(oldRegLink);
  1157.       oldRegLink = 0L;
  1158.     }
  1159.     pROT->Release();
  1160.   }
  1161.   return hr;
  1162. }
  1163.  
  1164.  
  1165. HRESULT _IFUNC BOleSite::GetMoniker (DWORD dwAssign, DWORD dwWhichMoniker, IMoniker* FAR* ppmk)
  1166. {
  1167.   // If we're open in a server doc its relative to the one in pmkDoc
  1168.   // If we're an embedding, its relative to the container's doc
  1169.   HRESULT hr = ResultFromScode(E_FAIL);
  1170.   *ppmk = NULL;
  1171.   if (pClientSite) {
  1172.     hr = pClientSite->GetMoniker(OLEGETMONIKER_ONLYIFTHERE,
  1173.       OLEWHICHMK_OBJFULL, ppmk);
  1174.   }
  1175.   else if (pmkDoc && pszInstName) {
  1176.     LPMONIKER pmkObj = NULL;
  1177.  
  1178.     if (SUCCEEDED(CreateItemMoniker (OLESTR("!"), pszInstName, &pmkObj))) {
  1179.       hr = CreateGenericComposite(pmkDoc, pmkObj, ppmk);
  1180.       pmkObj->Release();
  1181.     }
  1182.   }
  1183.   else if (pmkDoc && !pszInstName) {
  1184.     *ppmk = pmkDoc;
  1185.     pmkDoc->AddRef();
  1186.     hr = NOERROR;
  1187.   }
  1188.   return hr;
  1189. }
  1190.  
  1191. HRESULT _IFUNC BOleSite::InitFromData (IDataObject* pDataObject, BOOL fCreation, DWORD dwReserved)
  1192. {
  1193.   return ResultFromScode (E_NOTIMPL);
  1194. }
  1195.  
  1196. HRESULT _IFUNC BOleSite::GetClipboardData (DWORD dwReserved, IDataObject* FAR* ppDataObject)
  1197. {
  1198.   return ResultFromScode (E_NOTIMPL);
  1199. }
  1200.  
  1201. // Put external lock on document
  1202. HRESULT _IFUNC BOleSite::Lock (BOOL fLock, BOOL fLastUnlockReleases)
  1203. {
  1204.   return CoLockObjectExternal (AsPIUnknown(pObjOuter), fLock, fLastUnlockReleases);
  1205. }
  1206.  
  1207. HRESULT _IFUNC BOleSite::ShowWindow ()
  1208. {
  1209.   HRESULT hrErr = NOERROR;
  1210.   if (fShown)
  1211.     hrErr = pPart->Open(TRUE);    // show window and set focus anyway
  1212.   else {
  1213.     // If there's no pClientSite, this is a linked object
  1214.     //
  1215.     if (!pClientSite) {
  1216.       hrErr = pPart->Open(TRUE);
  1217.       fShown = SUCCEEDED(hrErr);
  1218.     }
  1219.     else {
  1220.       // This is an embedded object. ask container to show itself and object
  1221.       //
  1222.       pClientSite->ShowObject();
  1223.       if (!fInPlaceActive) {
  1224.         hrErr = pPart->Open(TRUE);    // show app main window
  1225.         fShown = SUCCEEDED(hrErr);
  1226.         if (fShown)       // show open edit hatching
  1227.           pClientSite->OnShowWindow (TRUE);
  1228.       }
  1229.       else
  1230.         fShown = TRUE;
  1231.     }
  1232.     if (fShown)
  1233.       Lock (TRUE, FALSE);    // lock document till window is hidden
  1234.   }
  1235.   return hrErr;
  1236. }
  1237.  
  1238. HRESULT _IFUNC BOleSite::HideWindow (BOOL fShutdown)
  1239. {
  1240.   HRESULT hrErr = NOERROR;
  1241.   if (fShown) {
  1242.     fShown = FALSE;
  1243.  
  1244.     // If there's no pClientSite, this is a linked object
  1245.     //
  1246.     if (!pClientSite)
  1247.       hrErr = pPart->Open(FALSE);
  1248.     else {
  1249.       // This is an embedded object.
  1250.       // inform container that our window is hiding
  1251.       //
  1252.       if (!fInPlaceVisible) {
  1253.         pClientSite->OnShowWindow (FALSE);    // hide open edit hatching
  1254.         hrErr = pPart->Open(FALSE);
  1255.       }
  1256.     }
  1257.  
  1258.     // Must unlock at the bottom in case object gets deleted
  1259.     //
  1260.     Lock (FALSE, fShutdown);
  1261.   }
  1262.   return hrErr;
  1263. }
  1264.  
  1265. HRESULT _IFUNC BOleSite::AssembleMenus ()
  1266. {
  1267.   HRESULT hrErr = NOERROR;
  1268.  
  1269.   hMenuShared = CreateMenu ();
  1270.   if (hMenuShared) {
  1271.       //\\// zero's menu descriptor
  1272.     for (int i = 0; i < 6; i++) {    menuGroupWidths.width[i] = 0; }
  1273.     hrErr = pIPFrame->InsertMenus (hMenuShared, &menuGroupWidths);
  1274.     if (hrErr == NOERROR) {
  1275.       hrErr = pPart->InsertMenus (hMenuShared, (BOleMenuWidths *)&menuGroupWidths);
  1276.     }
  1277.     else {
  1278.       // Even when the in-place container does not allow menu merging
  1279.       // the server must still call OleCreateMenuDescriptor(NULL)
  1280.       //
  1281.       DestroyMenu (hMenuShared);
  1282.       hMenuShared = NULL;
  1283.     }
  1284.   }
  1285.   hOleMenu = OleCreateMenuDescriptor (hMenuShared, &menuGroupWidths);
  1286.   if (!hOleMenu)
  1287.     hrErr = ResultFromScode (E_OUTOFMEMORY);
  1288.   return hrErr;
  1289. }
  1290.  
  1291. void _IFUNC BOleSite::DisassembleMenus ()
  1292. {
  1293.   if (hOleMenu) {
  1294.     OleDestroyMenuDescriptor (hOleMenu);
  1295.     hOleMenu = 0;
  1296.   }
  1297.   if (hMenuShared) {
  1298.     UINT uDeleteAt = 0;
  1299.     for (UINT uGroup = 0; uGroup < 6; uGroup++) {
  1300.       uDeleteAt += menuGroupWidths.width [uGroup++];
  1301.       for (UINT uCount = 0; uCount < menuGroupWidths.width [uGroup]; uCount++)
  1302.       DeleteMenu (hMenuShared, uDeleteAt, MF_BYPOSITION);
  1303.     }
  1304.     if (pIPFrame)
  1305.       pIPFrame->RemoveMenus (hMenuShared);
  1306.     DestroyMenu (hMenuShared);
  1307.     hMenuShared = 0;
  1308.   }
  1309. }
  1310.  
  1311. HRESULT _IFUNC BOleSite::DoInPlaceActivate (BOOL fActivateOnly)
  1312. {
  1313.   HRESULT hrErr = NOERROR;
  1314.   if (pClientSite && !fInPlaceActive /*&& !fShown*/) {
  1315.     hrErr = pClientSite->QueryInterface(IID_IOleInPlaceSite,&(void *)pIPSite);
  1316.     if (SUCCEEDED(hrErr)) {
  1317.       hrErr = pIPSite->CanInPlaceActivate ();
  1318.       if (GetScode(hrErr) == S_OK) { //returns S_FALSE instead of E_FAIL
  1319.         hrErr = pIPSite->OnInPlaceActivate ();
  1320.         if (SUCCEEDED(hrErr)) {
  1321.           fInPlaceActive = TRUE;
  1322.           hrErr = DoInPlaceShow (fActivateOnly);
  1323.           if (SUCCEEDED(hrErr))
  1324.             hrErr = DoUIActivate ();
  1325.         }
  1326.         else {
  1327.           pIPSite->Release();
  1328.           pIPSite = 0;
  1329.         }
  1330.       }
  1331.       else {
  1332.         pIPSite->Release();
  1333.         pIPSite = 0;
  1334.       }
  1335.     }
  1336.   }
  1337.   return hrErr;
  1338. }
  1339.  
  1340. HRESULT _IFUNC BOleSite::CalcZoom( LPCRECT rcPosRect )
  1341. {
  1342.   SIZE sCurrent;
  1343.   HRESULT hr = pProvider->GetPartSize (&sCurrent);
  1344.   if (SUCCEEDED(hr)) {
  1345.     if (sCurrent.cx == 0) {
  1346.       scale.xN = 1;
  1347.       scale.xD = 1;
  1348.     } else {
  1349.       scale.xN = rcPosRect->right - rcPosRect->left;
  1350.       scale.xD = sCurrent.cx;
  1351.     }
  1352.     if (sCurrent.cy == 0) {
  1353.       scale.yN = 1;
  1354.       scale.yD = 1;
  1355.     } else {
  1356.       scale.yN = rcPosRect->bottom - rcPosRect->top;
  1357.       scale.yD = sCurrent.cy;
  1358.     }
  1359.   }
  1360.   return hr;
  1361. }
  1362.  
  1363. HRESULT _IFUNC BOleSite::DoInPlaceShow (BOOL fActivateOnly)
  1364. {
  1365.   HRESULT hrErr = NOERROR;
  1366.   if (!fInPlaceVisible) {
  1367.     fInPlaceVisible = TRUE;
  1368.     hrErr = pIPSite->GetWindow (&hWndParent);
  1369.     if (SUCCEEDED(hrErr)) {
  1370.       frameInfo.cb = sizeof (frameInfo);
  1371.       hrErr = pIPSite->GetWindowContext (
  1372.         &pIPFrame, &pIPDoc, &rcPosRect, &rcClipRect, &frameInfo);
  1373.  
  1374.       CalcZoom( &rcPosRect );
  1375.  
  1376.       if (SUCCEEDED(hrErr) && pIPFrame) {
  1377.         // set message filter (ICS)
  1378.  
  1379.         hWndInPlace = pPart->OpenInPlace (hWndParent);
  1380.  
  1381.         AssembleMenus ();
  1382.         if (fInsideOut && fActivateOnly) {
  1383.           // show object without adornments and border
  1384.           pPart->SetPartPos (&rcPosRect);
  1385.         }
  1386.       }
  1387.       else {
  1388.         DoInPlaceDeactivate ();
  1389.       }
  1390.     }
  1391.     else {
  1392.       DoInPlaceDeactivate ();
  1393.     }
  1394.   }
  1395.   return hrErr;
  1396. }
  1397.  
  1398. HRESULT _IFUNC BOleSite::DoUIActivate ()
  1399. {
  1400.   HRESULT hrErr = NOERROR;
  1401.   if (!fUIActive) {
  1402.     fUIActive = TRUE;
  1403.     hrErr = pIPSite->OnUIActivate ();
  1404.     if (SUCCEEDED(hrErr)) {
  1405.  
  1406.       if (pHatchWnd) {
  1407.  
  1408.         // Put the hatch window around the inplace window. The offset
  1409.         // is necessary because we're reparenting the inplace window
  1410.         // behind the scenes, so the border of the hatch window would
  1411.         // throw rcPosRect off.
  1412.         //
  1413.         ::SetParent (hWndInPlace, *pHatchWnd);
  1414.         ::SetParent (*pHatchWnd, hWndParent);
  1415.         pHatchWnd->SetSize (&rcPosRect, &rcClipRect, &hatchOffset);
  1416.         pHatchWnd->Show (TRUE, pIPSite);
  1417.         ::OffsetRect (&rcPosRect, hatchOffset.x, hatchOffset.y);
  1418.       }
  1419.  
  1420.       pPart->SetPartPos (&rcPosRect);
  1421.       pPart->Show(TRUE); // Show after SetPos to prevent flashing
  1422.  
  1423.       // window position of part may need to move but the extent
  1424.       // should be the same
  1425.       pPart->Activate (TRUE);
  1426.       pIPFrame->SetActiveObject (this, pInPlaceName);
  1427.       if (pIPDoc)
  1428.         pIPDoc->SetActiveObject (this, pInPlaceName);
  1429.       pIPFrame->SetMenu (hMenuShared, hOleMenu, hWndInPlace);
  1430.       pPart->ShowTools (TRUE);
  1431.  
  1432.     }
  1433.     else {
  1434.       fUIActive = FALSE;
  1435.     }
  1436.   }
  1437.   return hrErr;
  1438. }
  1439.  
  1440. HRESULT _IFUNC BOleSite::DoInPlaceDeactivate ()
  1441. {
  1442.   HRESULT hrErr = NOERROR;
  1443.   if (fInPlaceActive) {
  1444.  
  1445.     hrErr = DoUIDeactivate ();
  1446.     if (SUCCEEDED(hrErr) && fInPlaceActive) {
  1447.       fInPlaceActive = FALSE;
  1448.  
  1449.       pIPSite->OnInPlaceDeactivate ();
  1450.       pIPSite->Release();
  1451.       pIPSite = 0;
  1452.     }
  1453.   }
  1454.   return hrErr;
  1455. }
  1456.  
  1457. HRESULT _IFUNC BOleSite::DoUIDeactivate ()
  1458. {
  1459.   if (!SUCCEEDED(pPart->Show (FALSE)))
  1460.     return ResultFromScode (E_FAIL); // Hide here to match Show which prevents flashing
  1461.  
  1462.   HRESULT hrErr = NOERROR;
  1463.   if (fUIActive) {
  1464.     fUIActive = FALSE;
  1465.     // remove shading and adornments
  1466.     if (pIPDoc)
  1467.       pIPDoc->SetActiveObject (NULL, NULL);
  1468.     if (pIPFrame)
  1469.       pIPFrame->SetActiveObject (NULL, NULL);
  1470.     pPart->ShowTools (FALSE);
  1471.     pIPSite->OnUIDeactivate (FALSE);
  1472.     // deactivate contained objects if any
  1473.     if (!fInsideOut) {
  1474.       DoInPlaceHide ();
  1475.       if (pIPFrame) {
  1476.         pIPFrame->Release();
  1477.         pIPFrame = 0;
  1478.       }
  1479.       if (pIPDoc) {
  1480.         pIPDoc->Release();
  1481.         pIPDoc = 0;
  1482.       }
  1483.     }
  1484.   }
  1485.   return hrErr;
  1486. }
  1487.  
  1488. HRESULT _IFUNC BOleSite::DoInPlaceHide ()
  1489. {
  1490.   HRESULT hrErr = NOERROR;
  1491.   if (fInPlaceVisible) {
  1492.     // deactivate contained objects (ICS)
  1493.     // remove shading and adornments (ICS)
  1494.     hrErr = pPart->OpenInPlace (0) == NULL ? ResultFromScode (E_FAIL) : NOERROR;
  1495.     if (pHatchWnd)
  1496.       // Hide the hatch window
  1497.       //
  1498.       pHatchWnd->Show (FALSE);
  1499.  
  1500.     // set filter ? (ICS)
  1501.     DisassembleMenus ();
  1502.     HideWindow (FALSE);
  1503.     fInPlaceVisible = FALSE;
  1504.   }
  1505.   return hrErr;
  1506. }
  1507.  
  1508. HRESULT _IFUNC BOleSite::DoVerb (LONG lVerb, LPMSG lpmsg, IOleClientSite* pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect)
  1509. {
  1510.   HRESULT hrErr = NOERROR;
  1511.  
  1512.   switch (lVerb) {
  1513.  
  1514.   case OLEIVERB_PRIMARY:
  1515.   default:
  1516.      // First ask the server app if it knows this verb
  1517.      //
  1518.      hrErr = pPart->DoVerb ((UINT)lVerb);
  1519.      if (SUCCEEDED(hrErr))
  1520.         return hrErr;
  1521.  
  1522.      // If the server app doesn't know it, and it's a predefined (<0)
  1523.      // verb, return an error
  1524.      //
  1525.      hrErr = ResultFromScode (OLEOBJ_S_INVALIDVERB);
  1526.      if (lVerb < 0)
  1527.         OLERES(hrErr);
  1528.  
  1529.      // If it's not a predefined verb and we don't know it, deliberately
  1530.      // fall through to Primary Verb
  1531.  
  1532.   case OLEIVERB_SHOW:
  1533.  
  1534.      // If the window is already open (primary verb has already been
  1535.      // run, just bring the window to the front
  1536.      //
  1537.      if (pClientSite && !fShown && !fInPlaceActive &&
  1538.       (S_OK == GetScode(pPart->CanOpenInPlace())))
  1539.       hrErr = DoInPlaceActivate (FALSE);
  1540.     else if (fInPlaceActive && !fInPlaceVisible) {
  1541.       if (SUCCEEDED(DoInPlaceShow (FALSE))) {
  1542.         hrErr = DoUIActivate ();
  1543.       }
  1544.     }
  1545.     hrErr = ShowWindow ();
  1546.     break;
  1547.   case 1:
  1548.   case OLEIVERB_OPEN:
  1549.     if (pClientSite && fInPlaceActive)
  1550.       hrErr = DoInPlaceDeactivate ();
  1551.     hrErr = ShowWindow ();
  1552.     break;
  1553.   case OLEIVERB_HIDE:
  1554.     if (pClientSite && fInPlaceActive)
  1555.       hrErr = DoInPlaceHide ();
  1556.     else
  1557.       hrErr = HideWindow (TRUE /*fShutdown*/);
  1558.     break;
  1559.   case OLEIVERB_UIACTIVATE:
  1560.   case OLEIVERB_INPLACEACTIVATE:
  1561.  
  1562.     // If our window is already open-editing we can't activate in-place.
  1563.     //
  1564.     if (pClientSite && !fShown && !fInPlaceActive &&
  1565.       (S_OK == GetScode(pPart->CanOpenInPlace())))
  1566.       hrErr = DoInPlaceActivate (lVerb == OLEIVERB_INPLACEACTIVATE);
  1567.     else
  1568.       hrErr = ResultFromScode (OLE_E_NOT_INPLACEACTIVE);
  1569.     break;
  1570.   }
  1571.   return hrErr;
  1572. }
  1573.  
  1574. HRESULT _IFUNC BOleSite::EnumVerbs (IEnumOLEVERB* FAR* ppenumOleVerb)
  1575. {
  1576.   return OleRegEnumVerbs(cid, ppenumOleVerb);
  1577. }
  1578.  
  1579. HRESULT _IFUNC BOleSite::Update ()
  1580. {
  1581.   return ResultFromScode(S_OK);
  1582. }
  1583.  
  1584. HRESULT _IFUNC BOleSite::IsUpToDate ()
  1585. {
  1586.   return ResultFromScode(MK_E_UNAVAILABLE);
  1587. }
  1588.  
  1589. HRESULT _IFUNC BOleSite::GetUserClassID (CLSID FAR* pClsid)
  1590. {
  1591.   *pClsid = cid;
  1592.   return NOERROR;
  1593. }
  1594.  
  1595. HRESULT _IFUNC BOleSite::GetUserType (DWORD dwFormOfType, LPOLESTR FAR* pszUserType)
  1596. {
  1597.   return ResultFromScode (OLE_S_USEREG);
  1598. }
  1599.  
  1600. HRESULT _IFUNC BOleSite::SetExtent (DWORD dwDrawAspect, LPSIZEL lpsizel)
  1601. {
  1602.   RECT pos;
  1603.   pos.left = pos.top = 0;
  1604.   pos.right = MAP_LOGHIM_TO_PIX (lpsizel->cx, BOleService::pixPerIn.x);
  1605.   pos.bottom = MAP_LOGHIM_TO_PIX (lpsizel->cy, BOleService::pixPerIn.y);
  1606.   SIZE size;
  1607.   size.cx = pos.right;
  1608.   size.cy = pos.bottom;
  1609.  
  1610.   HRESULT hr = pPart->SetPartSize(&size);
  1611.  
  1612.   if (SUCCEEDED(hr)) {
  1613.     Invalidate(BOLE_INVAL_VIEW);
  1614.     pPart->SetPartPos (&pos);
  1615.   }
  1616.  
  1617.   return hr;
  1618. }
  1619.  
  1620. HRESULT _IFUNC BOleSite::GetExtent (DWORD dwDrawAspect, LPSIZEL lpsizel)
  1621. {
  1622.   if (dwDrawAspect != DVASPECT_CONTENT) //PHP for now.
  1623.     return ResultFromScode (E_FAIL);
  1624.  
  1625.   if (!lpsizel)
  1626.     return ResultFromScode (E_INVALIDARG);
  1627.  
  1628.   SIZE s;
  1629.   HRESULT hr = pProvider->GetPartSize (&s); //PHP do we need aspect here?
  1630.  
  1631.   lpsizel->cx = MAP_PIX_TO_LOGHIM (s.cx, BOleService::pixPerIn.x);
  1632.   lpsizel->cy = MAP_PIX_TO_LOGHIM (s.cy, BOleService::pixPerIn.y);
  1633.  
  1634.   return hr;
  1635. }
  1636.  
  1637. HRESULT _IFUNC BOleSite::Advise (IAdviseSink* pAdvSink, DWORD FAR* pdwConnection)
  1638. {
  1639.   HRESULT hrErr;
  1640.  
  1641.   *pdwConnection = 0;
  1642.   if (pAdvHolder == 0)
  1643.     hrErr = CreateOleAdviseHolder (&pAdvHolder);
  1644.   if (pAdvHolder)
  1645.     hrErr = pAdvHolder->Advise (pAdvSink, pdwConnection);
  1646.   else
  1647.     hrErr = ResultFromScode (E_OUTOFMEMORY);
  1648.   return hrErr;
  1649. }
  1650.  
  1651. HRESULT _IFUNC BOleSite::Unadvise (DWORD dwConnection)
  1652. {
  1653.   HRESULT hrErr = ResultFromScode (E_FAIL);
  1654.   if (pAdvHolder)
  1655.     hrErr = pAdvHolder->Unadvise (dwConnection);
  1656.  
  1657.   return hrErr;
  1658. }
  1659.  
  1660. HRESULT _IFUNC BOleSite::EnumAdvise (IEnumSTATDATA* FAR* ppenumAdvise)
  1661. {
  1662.   HRESULT hrErr = ResultFromScode (E_FAIL);
  1663.   if (pAdvHolder)
  1664.     hrErr = pAdvHolder->EnumAdvise (ppenumAdvise);
  1665.  
  1666.   return hrErr;
  1667. }
  1668.  
  1669. HRESULT _IFUNC BOleSite::GetMiscStatus (DWORD dwAspect, DWORD FAR* pdwStatus)
  1670. {
  1671.   return ResultFromScode (OLE_S_USEREG);
  1672. }
  1673.  
  1674. HRESULT _IFUNC BOleSite::SetColorScheme (LPLOGPALETTE lpLogpal)
  1675. {
  1676.   return ResultFromScode (E_NOTIMPL);
  1677. }
  1678.  
  1679. //**************************************************************************
  1680. //
  1681. // IPersist implementation
  1682. //
  1683. //**************************************************************************
  1684.  
  1685. HRESULT _IFUNC BOleSite::GetClassID (LPCLSID lpClassID)
  1686. {
  1687.   *lpClassID = cid;
  1688.   return NOERROR;
  1689. }
  1690.  
  1691. HRESULT _IFUNC BOleSite::IsDirty ()
  1692. {
  1693.   return ResultFromScode((fIsDirty) ? S_OK : S_FALSE);
  1694. }
  1695.  
  1696. //**************************************************************************
  1697. //
  1698. // IPersistStorage implementation
  1699. //
  1700. //**************************************************************************
  1701.  
  1702. HRESULT _IFUNC BOleSite::InitNew (IStorage* pStgNew)
  1703. {
  1704.   if (pStg) {
  1705.     pStg->Release ();
  1706.     pStg = NULL;
  1707.   }
  1708.   pStg = pStgNew;
  1709.   if (pStg) {
  1710.     pStg->AddRef();
  1711.   }
  1712.   BOleInitInfo bi;
  1713.   bi.pContainer = NULL;
  1714.   bi.Where = BOLE_NEW;
  1715.   bi.How = BOLE_EMBED;
  1716.   bi.pStorage = pStgNew;
  1717.  
  1718.   HRESULT hr = pPart->Init(this, &bi);
  1719.   if (!SUCCEEDED(hr))
  1720.     return hr;
  1721.  
  1722.   Invalidate(BOLE_INVAL_DATA);
  1723.  
  1724.   return ResultFromScode(S_OK);
  1725. }
  1726.  
  1727. HRESULT _IFUNC BOleSite::Load (IStorage* pStgFrom)
  1728. {
  1729.   HRESULT hresult = NOERROR;
  1730.  
  1731.   fIsDirty = FALSE;       // data will be the same as what was saved
  1732.  
  1733.   if (pStg) {
  1734.     pStg->Release ();
  1735.     pStg= NULL;
  1736.   }
  1737.   pStg = pStgFrom;
  1738.   pStg->AddRef();
  1739.  
  1740.   BOleInitInfo bi;
  1741.   bi.pContainer = NULL;
  1742.   bi.Where = BOLE_STORAGE;
  1743.   bi.How = BOLE_EMBED;
  1744.   bi.pStorage = pStg;
  1745.   hresult = pPart->Init (this, &bi);
  1746.  
  1747.   return hresult;
  1748. }
  1749.  
  1750. HRESULT _IFUNC BOleSite::Save (IStorage* pStgSave, BOOL fSameAsLoad)
  1751. {
  1752. //      if (fSameAsLoad && !fIsDirty)  // don't bother, its up to date
  1753. //        return NOERROR;
  1754.  
  1755.   HRESULT hresult = ResultFromScode(S_OK);
  1756.  
  1757.   if (!pStgSave && fSameAsLoad)
  1758.     pStgSave = pStg;
  1759.  
  1760.   // The online dox say that OleSave does this, but there's no
  1761.   // CompObj stream without WriteFmtUseTypeStg and no CLSID in the
  1762.   // stream without WriteClassStg
  1763.   //
  1764.   CLSID clsid = CLSID_NULL;
  1765.   CLSIDFromProgID (pszProgID, &clsid);
  1766.   if ((hresult = WriteClassStg (pStgSave, clsid)) != NOERROR)
  1767.     return hresult;
  1768.   LPOLESTR lpLongType = NULL;
  1769.   OleRegGetUserType (clsid, USERCLASSTYPE_FULL, &lpLongType);
  1770.   hresult = WriteFmtUserTypeStg (pStgSave, BOleDocument::oleEmbSrcClipFmt, lpLongType);
  1771.  
  1772.   // We pass along the fHandsOff flag here to "fRemember"
  1773.   // If HandsOffStorage was called before it means SaveAs is happening
  1774.   // and objects need to remember their new substorages as they create them.
  1775.   // We use the fRemember flag to do what what HandsOffStorage and
  1776.   // SaveCompleted do (we can't scribble to storages between saves anyway)
  1777.  
  1778.   if (SUCCEEDED(pProvider->Save( pStgSave, fSameAsLoad, fHandsOff))) {
  1779.  
  1780.     // since we don't scribble, do the SaveCompleted stuff here
  1781.     // where we know fSameAsLoad
  1782.  
  1783.     if (fHandsOff || fSameAsLoad) {    // ! save copy as situation
  1784.       fIsDirty = FALSE;
  1785.       if (pAdvHolder)
  1786.         hresult = pAdvHolder->SendOnSave();
  1787.       if (fHandsOff) {
  1788.         fHandsOff = FALSE;
  1789.         pStg = pStgSave;  // pStg was Released in HandsOffStorage
  1790.         if (pStg)
  1791.           pStg->AddRef();
  1792.       }
  1793.     }
  1794.   }
  1795.   else
  1796.     hresult = ResultFromScode(STG_E_CANTSAVE);
  1797.  
  1798.   return hresult;
  1799. }
  1800.  
  1801. HRESULT _IFUNC BOleSite::SaveCompleted (IStorage* pStgNew)
  1802. {
  1803.   if (fHandsOff) {    // HandsOffStorage, SaveCompleted without Save
  1804.     Save(pStgNew, FALSE);
  1805.   }
  1806.   return ResultFromScode(S_OK);
  1807. }
  1808.  
  1809. HRESULT _IFUNC BOleSite::HandsOffStorage ()
  1810. {
  1811.   fHandsOff = TRUE;
  1812.   if (pStg) {
  1813.     pStg->Release();
  1814.     pStg = NULL;
  1815.   }
  1816.   return ResultFromScode(S_OK);
  1817. }
  1818.  
  1819.  
  1820. //**************************************************************************
  1821. //
  1822. // IDropSource implementation
  1823. //
  1824. //**************************************************************************
  1825.  
  1826. HRESULT _IFUNC BOleSite::QueryContinueDrag (BOOL fEscapePressed, DWORD grfKeyState)
  1827. {
  1828.   if (fEscapePressed) {
  1829.     OLERET (DRAGDROP_S_CANCEL);
  1830.   }
  1831.  
  1832.   if (!(grfKeyState & (MK_LBUTTON | MK_RBUTTON))) {
  1833.     OLERET (DRAGDROP_S_DROP);
  1834.   }
  1835.  
  1836.   return ResultFromScode(S_OK);
  1837. }
  1838.  
  1839. HRESULT _IFUNC BOleSite::GiveFeedback (DWORD dwEffect)
  1840. {
  1841.   POINT p = {0,0};
  1842.   BOOL fNearScroll = FALSE;
  1843.  
  1844.   // of IBDataProvider so we can do drag/drop with only a provider
  1845.   //
  1846.   if (!pPart)
  1847.     return ResultFromScode (DRAGDROP_S_USEDEFAULTCURSORS);
  1848.  
  1849.   if (S_OK == GetScode(pPart->DragFeedback (&p, fNearScroll))) {
  1850.     return ResultFromScode (DRAGDROP_S_USEDEFAULTCURSORS);
  1851.   }
  1852.   else {
  1853.     return ResultFromScode (S_OK);
  1854.   }
  1855. }
  1856.  
  1857. //**************************************************************************
  1858. //
  1859. // IOleWindow implementation
  1860. //
  1861. //**************************************************************************
  1862.  
  1863. HRESULT _IFUNC BOleSite::GetWindow (HWND FAR* lphwnd)
  1864. {
  1865.   if (lphwnd) {
  1866.     *lphwnd = hWndInPlace;
  1867.     return NOERROR;
  1868.   }
  1869.   return ResultFromScode (E_INVALIDARG);
  1870. }
  1871.  
  1872. HRESULT _IFUNC BOleSite::ContextSensitiveHelp (BOOL fEnterMode)
  1873. {
  1874.   return pService->ContextSensitiveHelp (fEnterMode);
  1875. }
  1876.  
  1877. //**************************************************************************
  1878. //
  1879. // IOleInPlaceObject implementation
  1880. //
  1881. //**************************************************************************
  1882.  
  1883. HRESULT _IFUNC BOleSite::InPlaceDeactivate ()
  1884. {
  1885.   return DoInPlaceDeactivate ();
  1886. }
  1887.  
  1888. HRESULT _IFUNC BOleSite::UIDeactivate ()
  1889. {
  1890.   return DoUIDeactivate ();
  1891. }
  1892.  
  1893. HRESULT _IFUNC BOleSite::SetObjectRects (LPCRECT lprcPosRect, LPCRECT lprcClipRect)
  1894. {
  1895.   rcPosRect = *lprcPosRect;
  1896.   rcClipRect = *lprcClipRect;
  1897.   RECT r;
  1898.  
  1899.   if (pHatchWnd) {
  1900. //        if (! fUIActive) // hatch and adornments should not be drawn
  1901. //          lprcClipRect = lprcPosRect;
  1902.  
  1903.     pHatchWnd->SetSize (&rcPosRect, &rcClipRect, &hatchOffset);
  1904.     r = rcPosRect;
  1905.  
  1906.     // offset hatch border
  1907.  
  1908.     ::OffsetRect (&r, hatchOffset.x, hatchOffset.y);
  1909.  
  1910.   }
  1911.   else
  1912.     r = rcPosRect;
  1913.  
  1914.  
  1915.   CalcZoom (lprcPosRect);
  1916.  
  1917.   pPart->SetPartPos (&r);
  1918.  
  1919.   return NOERROR;
  1920. }
  1921.  
  1922. HRESULT _IFUNC BOleSite::GetZoom( BOleScaleFactor *pScale)
  1923. {
  1924.   if (fInPlaceActive) {
  1925.     *pScale = scale;
  1926.   }
  1927.   else {
  1928.     pScale->xN = 1;
  1929.     pScale->yN = 1;
  1930.     pScale->xD = 1;
  1931.     pScale->yD = 1;
  1932.   }
  1933.   return NOERROR;
  1934. }
  1935.  
  1936. HRESULT _IFUNC BOleSite::ReactivateAndUndo ()
  1937. {
  1938.   HRESULT hrErr;
  1939.   if (pClientSite && !fShown && !fInPlaceActive &&
  1940.     (S_OK == GetScode(pPart->CanOpenInPlace())))
  1941.     hrErr = DoInPlaceActivate (OLEIVERB_INPLACEACTIVATE);
  1942.   else
  1943.     hrErr = ResultFromScode (OLE_E_NOT_INPLACEACTIVE);
  1944.  
  1945.   // do undo?
  1946.  
  1947.   return hrErr;
  1948. }
  1949.  
  1950. //**************************************************************************
  1951. //
  1952. // IOleInPlaceActiveObject implementation
  1953. //
  1954. //**************************************************************************
  1955.  
  1956. HRESULT _IFUNC BOleSite::TranslateAccelerator (LPMSG lpmsg)
  1957. {
  1958.   return ResultFromScode (E_NOTIMPL);
  1959. }
  1960.  
  1961. HRESULT _IFUNC BOleSite::OnFrameWindowActivate (BOOL fActivate)
  1962. {
  1963.   // post message to server app ? (ICS)
  1964.   return NOERROR;
  1965. }
  1966.  
  1967. HRESULT _IFUNC BOleSite::OnDocWindowActivate (BOOL fActivate)
  1968. {
  1969.   if (fActivate) {
  1970.     pIPFrame->SetActiveObject ((IOleInPlaceActiveObject *)this, pInPlaceName);
  1971.     pIPFrame->SetMenu (hMenuShared, hOleMenu, hWndInPlace);
  1972.     pPart->ShowTools (TRUE);
  1973.   }
  1974.   else {
  1975.     pIPFrame->SetActiveObject (NULL, NULL);
  1976.  
  1977.     pPart->ShowTools (FALSE);
  1978.     // deactivate contained objects if any (ICS)
  1979.   }
  1980.   return NOERROR;
  1981. }
  1982.  
  1983. HRESULT _IFUNC BOleSite::ResizeBorder (LPCRECT lprectBorder, LPOLEINPLACEUIWINDOW lpUIWindow, BOOL fFrameWindow)
  1984. {
  1985.   pPart->FrameResized(lprectBorder, fFrameWindow);
  1986.   return ResultFromScode(S_OK);
  1987. }
  1988.  
  1989. HRESULT _IFUNC BOleSite::EnableModeless (BOOL fEnable)
  1990. {
  1991.   return pService->GetApplication()->OnModalDialog (!fEnable);
  1992. }
  1993.  
  1994. //**************************************************************************
  1995. //
  1996. //    IContainer implementation
  1997. //
  1998. //**************************************************************************
  1999.  
  2000. HRESULT _IFUNC BOleSite::AllowInPlace()
  2001. {
  2002.   // anything we can use this for on server side??
  2003.   return ResultFromScode (E_NOTIMPL);
  2004. }
  2005.  
  2006. HRESULT _IFUNC BOleSite::BringToFront()
  2007. {
  2008.   // anything we can use this for on server side??
  2009.   return ResultFromScode (E_NOTIMPL);
  2010. }
  2011.  
  2012. HRESULT _IFUNC BOleSite::FindDropDest (LPPOINT, PIBDropDest FAR*)
  2013. {
  2014.   // anything we can use this for on server side??
  2015.   return ResultFromScode (E_NOTIMPL);
  2016. }
  2017.  
  2018. HWND _IFUNC BOleSite::GetWindow()
  2019. {
  2020.   HWND hWnd;
  2021.   return (pIPSite && pIPSite->GetWindow (&hWnd) == NOERROR) ? hWnd : 0;
  2022. }
  2023.  
  2024. HRESULT _IFUNC BOleSite::GetWindowRect(LPRECT pR)
  2025. {
  2026.   if (pIPDoc)
  2027.     return pIPDoc->GetBorder (pR);
  2028.  
  2029.   return ResultFromScode (E_FAIL);
  2030. }
  2031.  
  2032. HRESULT _IFUNC BOleSite::RequestBorderSpace(LPCRECT pR)
  2033. {
  2034.   BORDERWIDTHS r;
  2035.   if (pR) {
  2036.     r = *pR;  // Word bums modify our LPCRECT contents
  2037.     pR = &r;
  2038.   }
  2039.   if (pIPDoc)
  2040.     return pIPDoc->RequestBorderSpace (pR);
  2041.  
  2042.   return ResultFromScode (E_FAIL);
  2043. }
  2044.  
  2045. HRESULT _IFUNC BOleSite::SetBorderSpace(LPCRECT pR)
  2046. {
  2047.   BORDERWIDTHS r;
  2048.   if (pR) {
  2049.     r = *pR;  // Word bums modify our LPCRECT contents
  2050.     pR = &r;
  2051.   }
  2052.  
  2053.   if (pIPDoc)
  2054.     return pIPDoc->SetBorderSpace (pR);
  2055.  
  2056.   return ResultFromScode (E_FAIL);
  2057. }
  2058.  
  2059. LPCOLESTR _IFUNC BOleSite::GetWindowTitle()
  2060. {
  2061.   return pWindowTitle;
  2062. }
  2063.  
  2064. void _IFUNC BOleSite::AppendWindowTitle(LPCOLESTR)
  2065. {
  2066.   //PHP Do we need to call SetActiveObject???
  2067. }
  2068.  
  2069. //**************************************************************************
  2070. //
  2071. // ISite implementation
  2072. //
  2073. //**************************************************************************
  2074.  
  2075.  
  2076. HRESULT _IFUNC BOleSite::SiteShow(BOOL)
  2077. {
  2078.   return ResultFromScode (E_NOTIMPL);
  2079. }
  2080.  
  2081. HRESULT _IFUNC BOleSite::DiscardUndo()
  2082. {
  2083.   return ResultFromScode (E_NOTIMPL);
  2084. }
  2085.  
  2086. HRESULT _IFUNC BOleSite::GetSiteRect(LPRECT prcPos,LPRECT prcClip)
  2087. {
  2088.   if( prcPos )
  2089.     *prcPos = rcPosRect;
  2090.   if( prcClip )
  2091.     *prcClip = rcClipRect;
  2092.  
  2093.   return NOERROR;
  2094. }
  2095.  
  2096. HRESULT _IFUNC BOleSite::SetSiteRect(LPCRECT pR)
  2097. {
  2098.   // Can be useful for hatch window implementations or resizing
  2099.   // the server when in-place active
  2100.   HRESULT hr;
  2101.   SIZE s;
  2102.   s.cx = pR->right - pR->left;
  2103.   s.cy = pR->bottom - pR->top;
  2104.  
  2105.   if (SUCCEEDED(hr = SetSiteExtent(&s))) {
  2106.     // Ask the client to resize to the new size of the window
  2107.     if (pIPSite) {
  2108.       hr = pIPSite->OnPosRectChange (pR);
  2109.     }
  2110.   }
  2111.   return hr;
  2112. }
  2113.  
  2114. HRESULT _IFUNC BOleSite::SetSiteExtent (LPCSIZE pS)
  2115. {
  2116.   SIZE s = *pS;
  2117.   // Servers call this to update their own scaled size
  2118.   // and notify the container of the change
  2119.  
  2120.   BOleScaleFactor scale;
  2121.   GetZoom(&scale);
  2122.   s.cx = s.cx * scale.xD / scale.xN; // unscale
  2123.   s.cy = s.cy * scale.yD / scale.yN;
  2124.   HRESULT hr = pPart->SetPartSize(&s);
  2125.   if (SUCCEEDED(hr)) {
  2126.     // Invalidate the metafile since it's size has changed
  2127.     Invalidate(BOLE_INVAL_VIEW);
  2128.   }
  2129.   return hr;
  2130. }
  2131.  
  2132. void _IFUNC BOleSite::Invalidate(BOleInvalidate inval)
  2133. {
  2134.   // The PERSISTENT flag is used for servers "Update" menu.
  2135.   //
  2136.   if (inval & BOLE_INVAL_PERSISTENT && pClientSite) {
  2137.     pClientSite->SaveObject ();
  2138.     fIsDirty = FALSE;
  2139.   }
  2140.  
  2141.   // We're not distinguishing between the other two flags on the
  2142.   // server side
  2143.   //
  2144.   if (inval & BOLE_INVAL_VIEW || inval & BOLE_INVAL_DATA) {
  2145.     fIsDirty = TRUE;
  2146.     if (pDAdvHolder)
  2147.       pDAdvHolder->SendOnDataChange (this, 0, 0);
  2148.   }
  2149. }
  2150.  
  2151. void _IFUNC BOleSite::OnSetFocus(BOOL bSet)
  2152. {
  2153.   pService->SetFocusedSite( bSet ? this : NULL );
  2154. }
  2155.  
  2156. void _IFUNC BOleSite::Disconnect ()
  2157. {
  2158.  
  2159.   Close(OLECLOSE_SAVEIFDIRTY);
  2160. }
  2161.  
  2162. //**************************************************************************
  2163. //
  2164. // IApplication implementation
  2165. //
  2166. //**************************************************************************
  2167.  
  2168. LPCOLESTR _IFUNC BOleSite::IBApplicationImpl::GetAppName()
  2169. {
  2170.   return pThis->pAppName;
  2171. }
  2172.  
  2173. // This is called when an inplace active object receives a Shift-F1
  2174. // keystroke. We need to call our container so that other objects can
  2175. // be prepared to give context-sensitive help if clicked.
  2176. //
  2177. BOleHelp _IFUNC BOleSite::IBApplicationImpl::HelpMode (BOleHelp newMode)
  2178. {
  2179.   BOleHelp oldMode = (BOleHelp) pThis->fInHelpMode;
  2180.   if (newMode != BOLE_HELP_GET)
  2181.     if (pThis->pIPSite) {
  2182.       pThis->fInHelpMode = newMode == BOLE_HELP_ENTER;
  2183.       pThis->pIPSite->ContextSensitiveHelp (pThis->fInHelpMode);
  2184.     }
  2185.  
  2186.   return oldMode;
  2187. }
  2188.  
  2189. HRESULT _IFUNC BOleSite::IBApplicationImpl::InsertContainerMenus(HMENU hMenu,BOleMenuWidths FAR* pMW)
  2190. {
  2191.   return pThis->InsertContainerMenus(hMenu, pMW);
  2192. }
  2193.  
  2194. HRESULT _IFUNC BOleSite::IBApplicationImpl::SetFrameMenu (HMENU h)
  2195. {
  2196.   return pThis->SetFrameMenu(h);
  2197. }
  2198.  
  2199. HRESULT _IFUNC BOleSite::IBApplicationImpl::Accelerator(MSG FAR*pMsg)
  2200. {
  2201.   return pThis->Accelerator(pMsg);
  2202. }
  2203.  
  2204. HRESULT _IFUNC BOleSite::IBApplicationImpl::GetAccelerators (HACCEL FAR*, int FAR*)
  2205. {
  2206.   return ResultFromScode (E_NOTIMPL);
  2207. }
  2208.  
  2209. HRESULT _IFUNC BOleSite::IBApplicationImpl::CanLink()
  2210. {
  2211.   return ResultFromScode (E_NOTIMPL);
  2212. }
  2213.  
  2214. HRESULT _IFUNC BOleSite::IBApplicationImpl::CanEmbed()
  2215. {
  2216.   return ResultFromScode (E_NOTIMPL);
  2217. }
  2218.  
  2219.  
  2220. HWND  _IFUNC BOleSite::IBApplicationImpl::GetWindow ()
  2221. {
  2222.   HWND hWnd;
  2223.   return (pThis->pIPFrame && pThis->pIPFrame->GetWindow (&hWnd) == NOERROR) ? hWnd : 0;
  2224. }
  2225.  
  2226. HRESULT _IFUNC BOleSite::IBApplicationImpl::RequestBorderSpace (LPCRECT pR)
  2227. {
  2228.   BORDERWIDTHS r;
  2229.   if (pR) {
  2230.     r = *pR;      // Word modifies our LPCRECT contents
  2231.     pR = &r;
  2232.   }
  2233.  
  2234.   if (pThis->pIPFrame)
  2235.     return pThis->pIPFrame->RequestBorderSpace (pR);
  2236.  
  2237.   return ResultFromScode (E_FAIL);
  2238. }
  2239.  
  2240. HRESULT  _IFUNC BOleSite::IBApplicationImpl::SetBorderSpace (LPCRECT pR)
  2241. {
  2242.   BORDERWIDTHS r;
  2243.   if (pR) {
  2244.     r = *pR;  // Word bums modify our LPCRECT contents
  2245.     pR = &r;
  2246.   }
  2247.  
  2248.   if (pThis->pIPFrame)
  2249.     return pThis->pIPFrame->SetBorderSpace (pR);
  2250.  
  2251.   return ResultFromScode (E_FAIL);
  2252. }
  2253.  
  2254.  
  2255. void  _IFUNC BOleSite::IBApplicationImpl::AppendWindowTitle (LPCOLESTR s)
  2256. {
  2257.   if (pThis->pIPFrame)
  2258.     pThis->pIPFrame->SetActiveObject(pThis, s);
  2259. }
  2260.  
  2261. HRESULT  _IFUNC BOleSite::IBApplicationImpl::SetStatusText (LPCOLESTR s)
  2262. {
  2263.   if (pThis->pIPFrame)
  2264.     return pThis->pIPFrame->SetStatusText(s);
  2265.   return ResultFromScode(E_FAIL);
  2266. }
  2267.  
  2268. HRESULT _IFUNC BOleSite::IBApplicationImpl::IsMDI ()
  2269. {
  2270.   if (pThis->pIPDoc)
  2271.     return ResultFromScode (S_OK);
  2272.   else
  2273.     return ResultFromScode (S_FALSE);
  2274. }
  2275.  
  2276. HRESULT _IFUNC BOleSite::IBApplicationImpl::OnModalDialog (BOOL fDialogComingActive)
  2277. {
  2278.   return (pThis->pIPFrame) ?
  2279.     pThis->pIPFrame->EnableModeless (!fDialogComingActive) :
  2280.     NOERROR;
  2281. }
  2282.  
  2283. void _IFUNC BOleSite::IBApplicationImpl::RestoreUI ()
  2284. {
  2285.   //PHP Server object should use this instead of SetBorderSpace(NULL)
  2286.   //    and AppendWindowTitle(NULL). Semantics are much cleaner.
  2287. }
  2288.  
  2289. void _IFUNC BOleSite::IBApplicationImpl::DialogHelpNotify (BOleDialogHelp helpCode)
  2290. {
  2291.   // unimplemented in server side helper
  2292. }
  2293.  
  2294. void _IFUNC BOleSite::IBApplicationImpl::ShutdownMaybe ()
  2295. {
  2296.   // unimplemented in server side helper
  2297. }
  2298.  
  2299. //
  2300. // ILinkable
  2301. //
  2302.  
  2303. HRESULT _IFUNC BOleSite::GetMoniker(IMoniker FAR* FAR* ppMon)
  2304. {
  2305.   return GetMoniker(OLEGETMONIKER_ONLYIFTHERE,
  2306.     OLEWHICHMK_OBJFULL, ppMon);
  2307. }
  2308.  
  2309. HRESULT _IFUNC BOleSite::OnRename(PIBLinkable pCont, LPCOLESTR szName)
  2310. {
  2311.   HRESULT ret = NOERROR;
  2312.  
  2313.   if (pCont)
  2314.     pCont->GetMoniker(&pmkDoc);
  2315.   else if (pmkDoc) {
  2316.     // Reset cached format list to cause it to be updated next time
  2317.     // (now that link format is enabled/disabled).
  2318.     if (formatList) {
  2319.       delete [] formatList;
  2320.       formatLink = FALSE;
  2321.       formatEmbed = FALSE;
  2322.       formatList = NULL;
  2323.       formatCount = 0;
  2324.     }
  2325.  
  2326.     if (pService->IsOnClipboard(this)) {
  2327.       // remove the linking capability from this object if one calls
  2328.       // OnRename(NULL, NULL) before Close rather during Close
  2329.       //
  2330.       AddRef();
  2331.       pService->Clip(NULL, FALSE, FALSE, FALSE);
  2332.       pService->Clip(pProvider, FALSE, pService->clipOkToEmbed, FALSE);
  2333.       Release();
  2334.     }
  2335.  
  2336.     if (pmkDoc) {
  2337.       pmkDoc->Release();
  2338.       pmkDoc = NULL;
  2339.     }
  2340.   }
  2341.  
  2342.   if (pszInstName) {
  2343.     delete [] pszInstName;
  2344.     pszInstName = NULL;
  2345.   }
  2346.   if (szName) {
  2347.     pszInstName = new OLECHAR [lstrlen (szName) +1];
  2348.     lstrcpy(pszInstName, szName);
  2349.   }
  2350.  
  2351.   // Don't register if this is a clone (pPart is NULL)
  2352.   // otherwise we would link to what's on the clipboard...
  2353.   //
  2354.   // Also don't bother if it is only a document (no item name)
  2355.   // (pszInstName may be NULL and pmkDoc valid, in that case
  2356.   // we shouldn't register here. BOleContainer already registered it.
  2357.   //
  2358.   if (pPart && pmkDoc && pszInstName)
  2359.     SetMoniker(OLEWHICHMK_OBJFULL, NULLP);  // register
  2360.  
  2361.   if (!pmkDoc && (regLink != 0L)) {
  2362.     // Unregister for linking if pmkDoc is NULL
  2363.     LPRUNNINGOBJECTTABLE pROT = NULL;
  2364.     HRESULT hr = OLE::GetRunningObjectTable (0, &pROT);
  2365.     if (SUCCEEDED(hr)) {
  2366.       pROT->Revoke(regLink);
  2367.       regLink = 0L;
  2368.       pROT->Release();
  2369.     }
  2370.   }
  2371.  
  2372.   return ret;
  2373. }
  2374.  
  2375.  
  2376. HRESULT     _IFUNC BOleSite::SetStatusText (LPCOLESTR s)
  2377. {
  2378.   if (pIPFrame)
  2379.     return pIPFrame->SetStatusText(s);
  2380.   return ResultFromScode(E_FAIL);
  2381. }
  2382.  
  2383.  
  2384.  
  2385. LPCOLESTR _IFUNC BOleSite::IBApplicationImpl::GetWindowTitle()
  2386. {
  2387.   return pThis->pWindowTitle;
  2388. }
  2389.  
  2390. HRESULT _IFUNC BOleSite::IBApplicationImpl::GetWindowRect(LPRECT pR)
  2391. {
  2392.   if (pThis->pIPFrame)
  2393.     return pThis->pIPFrame->GetBorder (pR);
  2394.   return ResultFromScode(CO_E_OBJNOTCONNECTED);
  2395. }
  2396.  
  2397. HRESULT _IFUNC BOleSite::GetAccelerators( HACCEL FAR *,int far*)
  2398. {
  2399.   return ResultFromScode (E_NOTIMPL);
  2400. }
  2401.  
  2402. HRESULT _IFUNC BOleSite::Accelerator(MSG FAR*pMsg)
  2403. {
  2404.   // Give the container a chance to handle its accelerators.
  2405.   // Returns S_OK if processed or S_FALSE if no accelerator was met.
  2406.   if (pIPFrame)
  2407.     return OleTranslateAccelerator( pIPFrame, &frameInfo, pMsg );
  2408.   return ResultFromScode(S_FALSE);
  2409. }
  2410.  
  2411. void _IFUNC BOleSite::RestoreUI()
  2412. {
  2413. }
  2414.  
  2415. // This little trick allows Bolero servers to dynamically renegotiate
  2416. // the menu bar in case some state changes while they're inplace active
  2417. //
  2418. HRESULT _IFUNC BOleSite::SetFrameMenu(HMENU)
  2419. {
  2420.   // First get the client to let go of the menus so we can put new ones up
  2421.   //
  2422.   if (pIPFrame)
  2423.     pIPFrame->SetMenu (NULL, hOleMenu, hWndInPlace);
  2424.  
  2425.   DisassembleMenus ();       // Tear down the old shared menu
  2426.   HRESULT hr = AssembleMenus ();   // Put together a new shared menu
  2427.   if (!SUCCEEDED(hr))
  2428.     return hr;
  2429.                   // Tell the client to install it
  2430.   return pIPFrame->SetMenu (hMenuShared, hOleMenu, hWndInPlace);
  2431. }
  2432.  
  2433. HRESULT _IFUNC BOleSite::InsertContainerMenus(HMENU hMenu,BOleMenuWidths far*)
  2434. {
  2435.   if (pIPFrame)
  2436.     return pIPFrame->InsertMenus (hMenu, &menuGroupWidths);
  2437.   return ResultFromScode (CO_E_OBJNOTCONNECTED);
  2438. }
  2439.  
  2440. void _IFUNC BOleSite::SetDirty (BOOL fDirty)
  2441. {
  2442.     fIsDirty = fDirty;
  2443. }    
  2444.