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

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