home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / BOCOLE.PAK / BOLESITE.CPP < prev    next >
C/C++ Source or Header  |  1995-08-29  |  83KB  |  2,602 lines

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