⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 olelink.cpp

📁 vc6.0完整版
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	--m_bDeferErrors;
	if (m_pLastException != NULL)
	{
		ASSERT_VALID(m_pLastException);
		if (sc == S_OK)
			sc = COleException::Process(m_pLastException);

		// Note: See note above in ReportSaveLoadException for
		// a comment regarding the special treatment of m_bAutoDelete.

		++m_pLastException->m_bAutoDelete;

		// now get rid of the exception that we saved
		m_pLastException->Delete();
		m_pLastException = NULL;
	}
	return sc;
}

/////////////////////////////////////////////////////////////////////////////
// COleLinkingDoc OLE interface implementation

BEGIN_INTERFACE_MAP(COleLinkingDoc, COleDocument)
	INTERFACE_PART(COleLinkingDoc, IID_IPersist, PersistFile)
	INTERFACE_PART(COleLinkingDoc, IID_IPersistFile, PersistFile)
	INTERFACE_PART(COleLinkingDoc, IID_IParseDisplayName, OleItemContainer)
	INTERFACE_PART(COleLinkingDoc, IID_IOleContainer, OleItemContainer)
	INTERFACE_PART(COleLinkingDoc, IID_IOleItemContainer, OleItemContainer)
END_INTERFACE_MAP()

/////////////////////////////////////////////////////////////////////////////
// COleLinkingDoc::XPersistFile implementation

STDMETHODIMP_(ULONG) COleLinkingDoc::XPersistFile::AddRef()
{
	METHOD_PROLOGUE_EX_(COleLinkingDoc, PersistFile)
	return pThis->ExternalAddRef();
}

STDMETHODIMP_(ULONG) COleLinkingDoc::XPersistFile::Release()
{
	METHOD_PROLOGUE_EX_(COleLinkingDoc, PersistFile)
	return pThis->ExternalRelease();
}

STDMETHODIMP COleLinkingDoc::XPersistFile::QueryInterface(
	REFIID iid, LPVOID* ppvObj)
{
	METHOD_PROLOGUE_EX_(COleLinkingDoc, PersistFile)
	return pThis->ExternalQueryInterface(&iid, ppvObj);
}

STDMETHODIMP COleLinkingDoc::XPersistFile::GetClassID(LPCLSID lpClassID)
{
	METHOD_PROLOGUE_EX_(COleLinkingDoc, PersistFile)

	// this is sometimes called for documents not attached to servers!
	if (pThis->m_pFactory == NULL)
	{
		*lpClassID = CLSID_NULL;
		return E_FAIL;
	}

	// get the class ID from the connected server object
	ASSERT_VALID(pThis->m_pFactory);
	*lpClassID = pThis->m_pFactory->GetClassID();
	return S_OK;
}

STDMETHODIMP COleLinkingDoc::XPersistFile::IsDirty()
{
	METHOD_PROLOGUE_EX(COleLinkingDoc, PersistFile)
	return pThis->IsModified() ? S_OK : S_FALSE;
}

STDMETHODIMP COleLinkingDoc::XPersistFile::Load(
	LPCOLESTR lpszFileName, DWORD /*dwMode*/)
{
	METHOD_PROLOGUE_EX(COleLinkingDoc, PersistFile)
	ASSERT_VALID(pThis);

	USES_CONVERSION;

	CString strFileName;
	SCODE sc = E_FAIL;
	pThis->BeginDeferErrors();
	LPCTSTR lpszFileNameT = OLE2CT(lpszFileName);
	TRY
	{
		BOOL bUserCtrl = AfxOleGetUserCtrl();

		// delegate to file-based Open implementation
		if (!pThis->OnOpenDocument(lpszFileNameT))
		{
			AfxOleSetUserCtrl(bUserCtrl);
			return sc;
		}
		pThis->SendInitialUpdate();

		// set the path name, but don't add to MRU list
		pThis->SetPathName(lpszFileNameT, FALSE);
		AfxOleSetUserCtrl(bUserCtrl);

		sc = S_OK;
	}
	END_TRY
	sc = pThis->EndDeferErrors(sc);

	ASSERT_VALID(pThis);
	return sc;
}

STDMETHODIMP COleLinkingDoc::XPersistFile::Save(
	LPCOLESTR lpszFileName, BOOL fRemember)
{
	METHOD_PROLOGUE_EX(COleLinkingDoc, PersistFile)
	ASSERT_VALID(pThis);

	USES_CONVERSION;

	CString strFileName;
	SCODE sc = E_FAIL;
	pThis->BeginDeferErrors();
	TRY
	{
		// delegate to file-based Save/Save As implementation
		ASSERT(pThis->m_bRemember);
		pThis->m_bRemember = fRemember;
		pThis->OnSaveDocument(OLE2CT(lpszFileName));
		sc = S_OK;
	}
	END_TRY
	sc = pThis->EndDeferErrors(sc);

	ASSERT_VALID(pThis);
	return sc;
}

STDMETHODIMP COleLinkingDoc::XPersistFile::SaveCompleted(LPCOLESTR lpszFileName)
{
	METHOD_PROLOGUE_EX(COleLinkingDoc, PersistFile)
	ASSERT_VALID(pThis);

	USES_CONVERSION;

	TRY
	{
		// set the path name, but don't add to MRU list
		pThis->SetPathName(OLE2CT(lpszFileName), FALSE);
	}
	END_TRY

	ASSERT_VALID(pThis);
	return S_OK;
}

STDMETHODIMP COleLinkingDoc::XPersistFile::GetCurFile(LPOLESTR* lplpszFileName)
{
	METHOD_PROLOGUE_EX_(COleLinkingDoc, PersistFile)

	*lplpszFileName = NULL;

	// use title if no document
	LPCTSTR lpszResult;
	if (pThis->m_strPathName.IsEmpty())
		lpszResult = pThis->m_strTitle;
	else
		lpszResult = pThis->m_strPathName;
	ASSERT(lpszResult != NULL);

	// allocate memory for the file name
	*lplpszFileName = AfxAllocTaskOleString(lpszResult);
	if (*lplpszFileName == NULL)
		return E_OUTOFMEMORY;

	ASSERT_VALID(pThis);
	return S_OK;
}

/////////////////////////////////////////////////////////////////////////////
// Implementation of IOleItemContainer
//  (supports linking to embeddings and linking to pseudo-objects)

STDMETHODIMP_(ULONG) COleLinkingDoc::XOleItemContainer::AddRef()
{
	METHOD_PROLOGUE_EX_(COleLinkingDoc, OleItemContainer)
	return pThis->ExternalAddRef();
}

STDMETHODIMP_(ULONG) COleLinkingDoc::XOleItemContainer::Release()
{
	METHOD_PROLOGUE_EX_(COleLinkingDoc, OleItemContainer)
	return pThis->ExternalRelease();
}

STDMETHODIMP COleLinkingDoc::XOleItemContainer::QueryInterface(
	REFIID iid, LPVOID* ppvObj)
{
	METHOD_PROLOGUE_EX_(COleLinkingDoc, OleItemContainer)
	return pThis->ExternalQueryInterface(&iid, ppvObj);
}

STDMETHODIMP COleLinkingDoc::XOleItemContainer::EnumObjects(
	DWORD /*grfFlags*/, LPENUMUNKNOWN* ppEnumUnknown)
{
	*ppEnumUnknown = NULL;
	return E_NOTIMPL;
}

STDMETHODIMP COleLinkingDoc::XOleItemContainer::ParseDisplayName(LPBC lpbc,
	LPOLESTR lpszDisplayName, ULONG* cchEaten, LPMONIKER* ppMoniker)
{
	METHOD_PROLOGUE_EX_(COleLinkingDoc, OleItemContainer)

	USES_CONVERSION;

	// reset all OUT parameters
	*ppMoniker = NULL;

	TCHAR szItemName[OLE_MAXNAMESIZE];
	LPTSTR lpszDest = szItemName;
	LPCTSTR lpszSrc = OLE2CT(lpszDisplayName);

	// skip leading delimiters
	int cEaten = 0;
	while (*lpszSrc != '\0' && (*lpszSrc == '\\' || *lpszSrc == '/' ||
		*lpszSrc == ':' || *lpszSrc == '!' || *lpszSrc == '['))
	{
		if (_istlead(*lpszSrc))
			++lpszSrc, ++cEaten;
		++lpszSrc;
		++cEaten;
	}

	// parse next token in szItemName
	while (*lpszSrc != '\0' && *lpszSrc != '\\' && *lpszSrc != '/' &&
		*lpszSrc != ':' && *lpszSrc != '!' && *lpszSrc != '[' &&
		cEaten < OLE_MAXNAMESIZE-1)
	{
		if (_istlead(*lpszSrc))
			*lpszDest++ = *lpszSrc++, ++cEaten;
		*lpszDest++ = *lpszSrc++;
		++cEaten;
	}
	*cchEaten = cEaten;
	*lpszDest = 0;

	// attempt to get the object
	LPUNKNOWN lpUnknown;
	SCODE sc = GetObject(T2OLE(szItemName), BINDSPEED_INDEFINITE, lpbc,
		IID_IUnknown, (LPLP)&lpUnknown);
	if (sc != S_OK)
		return sc;

	// item name found -- create item moniker for it
	lpUnknown->Release();
	return CreateItemMoniker(OLESTDDELIMOLE, T2COLE(szItemName), ppMoniker);
}

STDMETHODIMP COleLinkingDoc::XOleItemContainer::LockContainer(BOOL fLock)
{
	METHOD_PROLOGUE_EX_(COleLinkingDoc, OleItemContainer)

	pThis->LockExternal(fLock, TRUE);
	return S_OK;
}

STDMETHODIMP COleLinkingDoc::XOleItemContainer::GetObject(
	LPOLESTR lpszItem, DWORD dwSpeedNeeded, LPBINDCTX /*pbc*/, REFIID riid,
	LPVOID* ppvObject)
{
	METHOD_PROLOGUE_EX(COleLinkingDoc, OleItemContainer)
	ASSERT_VALID(pThis);

	USES_CONVERSION;

	*ppvObject = NULL;

	SCODE sc = MK_E_NOOBJECT;
	TRY
	{
		LPCTSTR lpszItemT = OLE2CT(lpszItem);
		// check for link to embedding
		COleClientItem* pClientItem = pThis->OnFindEmbeddedItem(lpszItemT);
		if (pClientItem != NULL)
		{
			ASSERT_VALID(pClientItem);
			sc = S_OK;

			// item found -- make sure it is running
			if (!::OleIsRunning(pClientItem->m_lpObject))
			{
				// should not run the object if bind-speed is immediate
				if (dwSpeedNeeded != BINDSPEED_INDEFINITE)
					sc = MK_E_EXCEEDEDDEADLINE;
				else
				{
					// bind speed is not immediate -- so run the object
					sc = OleRun(pClientItem->m_lpObject);
				}
			}

			if (sc == S_OK)
			{
				// return the object with appropriate interface
				sc = pClientItem->m_lpObject->QueryInterface(riid, ppvObject);
			}
		}
		else
		{
			// check for link to pseudo object
			COleServerItem* pServerItem = pThis->OnGetLinkedItem(lpszItemT);
			if (pServerItem != NULL)
			{
				if (!pServerItem->m_bNeedUnlock)
				{
					// when a link is bound, the document must be kept alive
					pThis->LockExternal(TRUE, FALSE);
					pServerItem->m_bNeedUnlock = TRUE;
				}

				// matching item found -- query for the requested interface
				sc = pServerItem->ExternalQueryInterface(&riid, ppvObject);
			}
		}
	}
	END_TRY

	return sc;
}

STDMETHODIMP COleLinkingDoc::XOleItemContainer::GetObjectStorage(
	LPOLESTR lpszItem, LPBINDCTX /*pbc*/, REFIID riid, LPVOID* ppvStorage)
{
	METHOD_PROLOGUE_EX(COleLinkingDoc, OleItemContainer)
	ASSERT_VALID(pThis);

	USES_CONVERSION;

	*ppvStorage = NULL;

	// only IStorage is supported
	if (riid != IID_IStorage)
		return E_UNEXPECTED;

	// check for link to embedding
	COleClientItem* pClientItem = pThis->OnFindEmbeddedItem(OLE2CT(lpszItem));
	if (pClientItem != NULL)
	{
		ASSERT_VALID(pClientItem);

		// if object has no storage, can't return it!
		if (pClientItem->m_lpStorage != NULL)
		{
			// found matching item -- return the storage
			*ppvStorage = pClientItem->m_lpStorage;
			pClientItem->m_lpStorage->AddRef();
			return S_OK;
		}
	}
	return MK_E_NOSTORAGE;
}

STDMETHODIMP COleLinkingDoc::XOleItemContainer::IsRunning(LPOLESTR lpszItem)
{
	METHOD_PROLOGUE_EX(COleLinkingDoc, OleItemContainer)
	ASSERT_VALID(pThis);

	USES_CONVERSION;

	// check for link to embedding
	LPCTSTR lpszItemT = OLE2CT(lpszItem);
	COleClientItem* pClientItem = pThis->OnFindEmbeddedItem(lpszItemT);
	if (pClientItem != NULL)
	{
		ASSERT_VALID(pClientItem);
		if (!::OleIsRunning(pClientItem->m_lpObject))
			return S_FALSE;

		return S_OK; // item is in document and is running
	}

	// check for link to pseudo object
	SCODE sc = MK_E_NOOBJECT;
	TRY
	{
		COleServerItem* pServerItem = pThis->OnGetLinkedItem(lpszItemT);
		if (pServerItem != NULL)
			sc = S_OK;
	}
	END_TRY

	return sc;
}

/////////////////////////////////////////////////////////////////////////////
// COleLinkingDoc diagnostics

#ifdef _DEBUG
void COleLinkingDoc::AssertValid() const
{
	COleDocument::AssertValid();
	if (m_pFactory != NULL)
		m_pFactory->AssertValid();
}

void COleLinkingDoc::Dump(CDumpContext& dc) const
{
	COleDocument::Dump(dc);

	dc << "\nm_dwRegister = " << m_dwRegister;
	dc << "\nm_bVisibleLock = " << m_bVisibleLock;
	if (m_pFactory != NULL)
		dc << "\nwith factory: " << m_pFactory;
	else
		dc << "\nwith no factory";

	dc << "\n";
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -