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

  1. //----------------------------------------------------------------------------
  2. // ObjectComponents
  3. // Copyright (c) 1994, 1996 by Borland International, All Rights Reserved
  4. //
  5. // $Revision:   2.6  $
  6. //
  7. //  Implements the server helper for documents by masquerading as the 
  8. //  container object. Provides plumbing for server linking to documents 
  9. //  and items
  10. //----------------------------------------------------------------------------
  11. #include "BOleCont.h"
  12. #include "BOleFact.h"
  13. #include "BOleCMan.h"
  14. #include "BOlePart.h"    // for link or embed to embedding
  15.  
  16. HRESULT _IFUNC BOleContainer::QueryInterfaceMain(REFIID iid, LPVOID FAR *ppv)
  17. {
  18.     HRESULT hr = ResultFromScode(E_NOINTERFACE);
  19.     *ppv = NULL;
  20.  
  21.     // interfaces
  22.  
  23.        SUCCEEDED(hr = IBRootLinkable_QueryInterface(this, iid, ppv))
  24.     || SUCCEEDED(hr = IPersistFile_QueryInterface(this, iid, ppv))
  25.     || SUCCEEDED(hr = IOleItemContainer_QueryInterface(this, iid, ppv))
  26.     // base classes
  27.  
  28.     || SUCCEEDED(hr = BOleComponent::QueryInterfaceMain(iid, ppv))
  29.  
  30.     // helpers
  31.     ;
  32.     return hr;
  33. };
  34.  
  35. BOleContainer::BOleContainer (BOleClassManager *pF, IBUnknownMain * pObj) :
  36.     BOleComponent(pF, pObj)
  37. {
  38.     pDoc = NULL;
  39.     regId = 0L;
  40.     pMoniker = NULL;
  41.     pClassFact = NULLP;
  42. }
  43.  
  44. BOleContainer::~BOleContainer ()
  45. {
  46.     if (pClassFact) {
  47.         pClassFact->Release ();
  48.         pClassFact = NULL;
  49.     }
  50. }
  51.  
  52. /**************************************************************************/
  53. // IOleItemContainer
  54. /**************************************************************************/
  55.  
  56. HRESULT _IFUNC BOleContainer::GetClassID (LPCLSID lpClassID)
  57. {
  58.     HRESULT hrErr = ResultFromScode (E_FAIL);
  59.     // outer could have called IRootLinkable::Init.
  60.     if (lpClassID && pClassFact) {
  61.         hrErr = pClassFact->GetClassID(lpClassID);
  62.     }
  63.     else {
  64.         // this is sometimes called for documents not attached to servers!
  65.         *lpClassID = CLSID_NULL;
  66.     }
  67.     return hrErr;
  68. }
  69.  
  70. HRESULT _IFUNC BOleContainer::IsDirty ()
  71. {
  72.     HRESULT hrErr = ResultFromScode (S_OK);
  73.  
  74.     
  75.     return hrErr;
  76. }
  77.  
  78. #define OLE_MAXNAMESIZE     (256)
  79.  
  80. HRESULT _IFUNC BOleContainer::ParseDisplayName (IBindCtx *pbc, LPOLESTR pszDisplayName, 
  81.                                                 ULONG FAR* pchEaten, IMoniker* FAR* ppmk)
  82. {
  83.     *ppmk = NULL;
  84.  
  85.     OLECHAR   szItemName[OLE_MAXNAMESIZE];
  86.     OLECHAR  *pszDest = szItemName;
  87.     LPCOLESTR pszSrc = pszDisplayName;
  88.  
  89.     // skip leading delimiters
  90.     int cEaten = 0;
  91. #if defined(DBCS)
  92.     while (*pszSrc != '\0' && (*pszSrc == '\\' || *pszSrc == '/' ||
  93.         *pszSrc == '!' || *pszSrc == '['))
  94.     {
  95.         if(IsDBCSLeadByte(*pszSrc))
  96.         {
  97.             ++pszSrc;
  98.             ++cEaten;
  99.         }
  100.         
  101.         ++pszSrc;
  102.         ++cEaten;
  103.     }
  104. #else
  105.     while (*pszSrc != '\0' && (*pszSrc == '\\' || *pszSrc == '/' ||
  106.         *pszSrc == '!' || *pszSrc == '['))
  107.     {
  108.         ++pszSrc;
  109.         ++cEaten;
  110.     }
  111. #endif
  112.  
  113. #if defined(DBCS)
  114.     // parse next token into szItemName
  115.     while (*pszSrc != '\0' && *pszSrc != '\\' && *pszSrc != '/' &&
  116.         *pszSrc != '!' && *pszSrc != '[' &&    cEaten < OLE_MAXNAMESIZE-1)
  117.     {
  118.         if(IsDBCSLeadByte(*pszSrc))
  119.         {
  120.             *pszDest++ = *pszSrc++;
  121.             ++cEaten;
  122.         }
  123.         *pszDest++ = *pszSrc++;
  124.         ++cEaten;
  125.     }
  126. #else
  127.     // parse next token into szItemName
  128.     while (*pszSrc != '\0' && *pszSrc != '\\' && *pszSrc != '/' &&
  129.         *pszSrc != '!' && *pszSrc != '[' &&    cEaten < OLE_MAXNAMESIZE-1)
  130.     {
  131.         *pszDest++ = *pszSrc++;
  132.         ++cEaten;
  133.     }
  134. #endif
  135.     *pchEaten = cEaten;
  136.     *pszDest = 0;
  137.  
  138.     // attempt to get the object
  139.     LPUNKNOWN pUnknown;
  140.     HRESULT hr = GetObject(szItemName, BINDSPEED_INDEFINITE, pbc,
  141.         IID_IUnknown, &(LPVOID)pUnknown);
  142.     if (SUCCEEDED(hr))    {
  143.         pUnknown->Release();
  144.         // item name found -- create item moniker for it
  145.         return ::CreateItemMoniker (OLESTDDELIMW, szItemName, ppmk);
  146.     }
  147.     else {
  148.         return hr;
  149.     }
  150. }
  151.  
  152.  
  153. HRESULT _IFUNC BOleContainer::EnumObjects (DWORD, IEnumUnknown* FAR* ppenumUnknown)
  154. {
  155.     HRESULT hrErr = ResultFromScode(E_NOTIMPL);
  156.     *ppenumUnknown = NULLP;
  157.     return hrErr;
  158. }
  159.  
  160. HRESULT _IFUNC BOleContainer::LockContainer (BOOL fLock)
  161. {
  162.     //  Keep app from closing
  163.     //
  164.     pFactory->ServerCount(fLock ? +1 : -1);
  165.     //    Lock external, but pass FALSE as last arg, so in-proc "self" linking
  166.     //  work (otherwise, Close gets called).
  167.     //
  168.  
  169.     if (fLock)
  170.         AddRef();
  171.     else
  172.         Release();
  173.     
  174.     return NOERROR;
  175.  
  176. }
  177.  
  178. HRESULT _IFUNC BOleContainer::GetObject (LPOLESTR lpszItem,
  179.     DWORD  dwSpeedNeeded, IBindCtx* pbc, REFIID riid, LPVOID FAR* ppvObject)
  180. {
  181.     HRESULT hrErr = ResultFromScode(MK_E_NOOBJECT);
  182.     *ppvObject = NULL;
  183.     PIBPart pPart;
  184.     if (SUCCEEDED(pDoc->GetPart(& pPart, lpszItem))) {
  185.         // bind speed always INDEFINITE? p.803
  186.         IUnknown *pUnk = pPart;
  187.         BOleSite *pBOleSite;
  188.         BOlePart *pBOlePart;
  189.         if (SUCCEEDED(pUnk->QueryInterface(IID_BOlePart, &(LPVOID)pBOlePart))) {
  190.             // Link to embedding case give the real IOleObject
  191.             //
  192.             if (pBOlePart->pOleObject) {
  193.                 pUnk = pBOlePart->pOleObject;
  194.             }
  195.             // Links to items need to maintain locks on their document
  196.             // or the ProxyManager gets hosed.
  197.             // When the BOlePart goes away it unlocks this.
  198.             //
  199.             if (!pBOlePart->pDocument)    // only ONCE
  200.                 pBOlePart->pDocument = AsPIUnknown(pObjOuter);
  201.             CoLockObjectExternal(AsPIUnknown(pObjOuter), TRUE, TRUE);
  202.             pBOlePart->Release();
  203.         }
  204.         else if (SUCCEEDED(pUnk->QueryInterface(IID_BOleSite, &(LPVOID)pBOleSite))) {
  205.             // Links to items need maintain locks on their documents
  206.             // or the ProxyManager gets hosed.
  207.             // When the BOleSite goes away it unlocks this.
  208.             // 
  209.             if (!pBOleSite->pDocument)    // only ONCE
  210.                 pBOleSite->pDocument = AsPIUnknown(pObjOuter);
  211.             pBOleSite->pDocument = AsPIUnknown(pObjOuter);
  212.             CoLockObjectExternal(AsPIUnknown(pObjOuter), TRUE, TRUE);
  213.             pBOleSite->Release();
  214.         }
  215.         if (SUCCEEDED(hrErr=OleRun(pUnk))) {
  216.             hrErr = pUnk->QueryInterface( riid, ppvObject);
  217.         }
  218.         pPart->Release();
  219.         pPart = NULL;
  220.         }
  221.     return hrErr;
  222. }
  223.  
  224. HRESULT _IFUNC BOleContainer::GetObjectStorage (LPOLESTR lpszItem, IBindCtx* pbc, REFIID riid, LPVOID FAR* ppvStorage)
  225. {
  226.     *ppvStorage = NULL;
  227.  
  228.     if (riid != IID_IStorage)
  229.         return ResultFromScode(E_UNEXPECTED);
  230.  
  231.     // could get part and ask for BOlePart or BOleSite
  232.     // and get the pStorage out of there
  233.     // noone calls this
  234.     
  235.     return ResultFromScode(MK_E_NOSTORAGE);
  236. }
  237.  
  238. HRESULT _IFUNC BOleContainer::IsRunning (LPOLESTR lpszItem)
  239. {
  240.     HRESULT hrErr = ResultFromScode(MK_E_NOOBJECT);
  241.     IOleObject *pOleObj = NULL;
  242.     PIBPart pPart;
  243.     if (SUCCEEDED(pDoc->GetPart(&pPart, lpszItem))) {
  244.  
  245.         IUnknown *pUnk = pPart;
  246.         // check for link to embedding case!
  247.         // if so, get the IOleObject out of the Bolero helper and use that!
  248.         BOlePart *pBOlePart;
  249.         if (SUCCEEDED(pUnk->QueryInterface(IID_BOlePart, &(LPVOID)pBOlePart))) {
  250.             if (pBOlePart->pOleObject) {
  251.                 pUnk = pBOlePart->pOleObject;
  252.             }
  253.             pBOlePart->Release();
  254.         }
  255.         
  256.         if (SUCCEEDED(pUnk->QueryInterface(IID_IOleObject,&(LPVOID)pOleObj))) {
  257.             hrErr = OleIsRunning(pOleObj)
  258.                 ? NOERROR
  259.                 : ResultFromScode(S_FALSE);
  260.             pOleObj->Release();
  261.             pOleObj = NULL;
  262.         }
  263.         pPart->Release();
  264.     }
  265.     return hrErr;
  266. }
  267.  
  268. //**************************************************************************
  269. //
  270. // IPersistFile implementation
  271. //
  272. //**************************************************************************
  273.  
  274. HRESULT _IFUNC BOleContainer::Load (LPCOLESTR lpszFileName, DWORD grfMode)
  275. {
  276.     HRESULT hr = NOERROR;
  277.  
  278.     hr = pDoc->Init(lpszFileName);
  279.     
  280.     return hr;
  281. }
  282.  
  283. HRESULT _IFUNC BOleContainer::Save (LPCOLESTR lpszFileName, BOOL fRemember)
  284. {
  285.     return ResultFromScode (E_NOTIMPL);
  286. }
  287.  
  288. HRESULT _IFUNC BOleContainer::SaveCompleted (LPCOLESTR lpszFileName)
  289. {
  290.     return ResultFromScode (E_NOTIMPL);
  291. }
  292.  
  293. HRESULT _IFUNC BOleContainer::GetCurFile (LPOLESTR FAR* lplpszFileName)
  294. {
  295.     return ResultFromScode (E_NOTIMPL);
  296. }
  297.  
  298. HRESULT    _IFUNC BOleContainer::OnRename(PIBLinkable pContainer, LPCOLESTR pszName)
  299. {
  300.     HRESULT hr;
  301.     LPMONIKER pMon;
  302.  
  303.     if (pszName)  {
  304.         LPMONIKER pmkDoc = NULL;
  305.         if (pContainer && SUCCEEDED(pContainer->GetMoniker(&pmkDoc))) {
  306.             // intermediate moniker
  307.             LPMONIKER pmkObj = NULL;
  308.         
  309.             if (SUCCEEDED(CreateItemMoniker (OLESTR("!"), (LPOLESTR)pszName, &pmkObj))) {
  310.                 hr = CreateGenericComposite(pmkDoc, pmkObj, &pMon);
  311.                 pmkObj->Release();
  312.             }
  313.             pmkDoc->Release();
  314.         }
  315.         else {
  316.             // root moniker
  317.             hr = OLE::CreateFileMoniker ((LPOLESTR)pszName, &pMon);
  318.         }
  319.     }
  320.     else 
  321.         pMon = NULL;
  322.  
  323.     hr = SetMoniker (pMon);
  324.     if (pMon)
  325.         pMon->Release();
  326.  
  327.     return hr;
  328. }
  329.  
  330. //**************************************************************************
  331. //
  332. // IBLinkable implementation
  333. //
  334. //**************************************************************************
  335.  
  336. HRESULT _IFUNC BOleContainer::Init( PIBContains pC, LPCOLESTR pszProgId)
  337. {
  338.     pDoc = pC;
  339.     pFactory->GetService()->FindClassFactory( pszProgId, &pClassFact);
  340.     return pClassFact ? NOERROR : ResultFromScode (E_FAIL);
  341. }
  342.  
  343. HRESULT _IFUNC BOleContainer::SetMoniker(LPMONIKER pMon)
  344. {
  345.     HRESULT hr;
  346.     // get the running object table
  347.     LPRUNNINGOBJECTTABLE pROT = NULL;
  348.     hr = OLE::GetRunningObjectTable (0, &pROT);
  349.     if (SUCCEEDED(hr)) {
  350.         // Register the new moniker BEFORE revoking the old moniker.
  351.         // Otherwise the object's "StubManager" gets hosed.
  352.         //
  353.         DWORD oldRegId = regId;
  354.  
  355.         if (pMoniker) {
  356.             pMoniker->Release();
  357.             pMoniker = NULLP;
  358.         }
  359.         // Store the new moniker if any
  360.         if (pMon) {
  361.             pMoniker = pMon;
  362.             pMoniker->AddRef();
  363.  
  364.             // Register in the running object table 
  365.             //
  366.             hr = pROT->Register (0, //ROTFLAGS_REGISTRATIONKEEPSALIVE,
  367.                 AsPIUnknown(pObjOuter), pMoniker, ®Id);
  368.         }
  369.         else
  370.             regId = 0L;
  371.  
  372.         // release any old monikers and running object table registration
  373.         if (oldRegId != 0L) {
  374.             pROT->Revoke(oldRegId);
  375.             oldRegId = 0L;
  376.         }
  377.         pROT->Release();
  378.     }
  379.     return hr;
  380. }
  381.  
  382. HRESULT _IFUNC BOleContainer::GetMoniker(LPMONIKER *ppMon)
  383. {
  384.     HRESULT hrErr = ResultFromScode (E_FAIL);
  385.     if (pMoniker) {
  386.         pMoniker->AddRef();
  387.         *ppMon = pMoniker;
  388.         hrErr = NOERROR;
  389.     }
  390.     else {
  391.         // Must be a nested embedding. Ask the container for one.
  392.  
  393.         IOleObject *pOleObj;
  394.         if (SUCCEEDED(QueryInterface(IID_IOleObject, &(LPVOID)pOleObj))) {
  395.             hrErr = pOleObj->GetMoniker(OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_OBJFULL, ppMon);
  396.             pOleObj->Release();
  397.         }
  398.     }
  399.     return hrErr;
  400. }
  401.  
  402.  
  403.  
  404.  
  405.