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

📄 olesvr2.cpp

📁 vc6.0完整版
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		if (lpRectStartDrag == NULL)
		{
			rectDrag.SetRect(lpItemRect->left, lpItemRect->top, lpItemRect->left,
				lpItemRect->top);
			lpRectStartDrag = &rectDrag;
		}

		// do drag drop operation
		dropEffect = pDataSource->DoDragDrop(dwEffects, lpRectStartDrag);
		pDataSource->InternalRelease();
	}
	CATCH_ALL(e)
	{
		if (pDataSource != NULL)
			pDataSource->InternalRelease();

		THROW_LAST();
	}
	END_CATCH_ALL

	return dropEffect;
}

void COleServerItem::GetClipboardData(COleDataSource* pDataSource,
	BOOL bIncludeLink, LPPOINT lpOffset, LPSIZE lpSize)
{
	ASSERT_VALID(this);
	ASSERT_VALID(pDataSource);
	ASSERT(lpOffset == NULL ||
		AfxIsValidAddress(lpOffset, sizeof(POINT), FALSE));

	// add CF_EMBEDDEDOBJECT by creating memory storage copy of the object
	STGMEDIUM stgMedium;
	GetEmbedSourceData(&stgMedium);
	pDataSource->CacheData((CLIPFORMAT)_oleData.cfEmbedSource, &stgMedium);

	// add CF_OBJECTDESCRIPTOR
	GetObjectDescriptorData(lpOffset, lpSize, &stgMedium);
	pDataSource->CacheData((CLIPFORMAT)_oleData.cfObjectDescriptor,
		&stgMedium);

	// add any presentation entries/conversion formats that the item
	//  can produce.
	AddOtherClipboardData(pDataSource);

	// add CF_LINKSOURCE if supporting links to pseudo objects
	if (bIncludeLink && GetLinkSourceData(&stgMedium))
	{
		pDataSource->CacheData((CLIPFORMAT)_oleData.cfLinkSource, &stgMedium);

		// add CF_LINKSOURCEDESCRIPTOR
		GetObjectDescriptorData(lpOffset, lpSize, &stgMedium);
		pDataSource->CacheData((CLIPFORMAT)_oleData.cfLinkSourceDescriptor,
			&stgMedium);
	}
}

void COleServerItem::GetEmbedSourceData(LPSTGMEDIUM lpStgMedium)
{
	ASSERT_VALID(this);
	ASSERT(AfxIsValidAddress(lpStgMedium, sizeof(STGMEDIUM)));

	LPLOCKBYTES lpLockBytes;
	SCODE sc = ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes);
	if (sc != S_OK)
		AfxThrowOleException(sc);
	ASSERT(lpLockBytes != NULL);

	LPSTORAGE lpStorage;
	sc = ::StgCreateDocfileOnILockBytes(lpLockBytes,
		STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &lpStorage);
	if (sc != S_OK)
	{
		VERIFY(lpLockBytes->Release() == 0);
		AfxThrowOleException(sc);
	}
	ASSERT(lpStorage != NULL);

	// setup for save copy as
	COleServerDoc* pDoc = GetDocument();
	pDoc->m_bSameAsLoad = FALSE;
	pDoc->m_bRemember = FALSE;

	TRY
	{
		OnSaveEmbedding(lpStorage);
		pDoc->CommitItems(FALSE);
	}
	CATCH_ALL(e)
	{
		// release storage and lock bytes
		VERIFY(lpStorage->Release() == 0);
		VERIFY(lpLockBytes->Release() == 0);
		pDoc->m_bSameAsLoad = TRUE;
		pDoc->m_bRemember = TRUE;
		THROW_LAST();
	}
	END_CATCH_ALL

	pDoc->m_bSameAsLoad = TRUE;
	pDoc->m_bRemember = TRUE;
	lpLockBytes->Release();

	// add it to the data source
	lpStgMedium->tymed = TYMED_ISTORAGE;
	lpStgMedium->pstg = lpStorage;
	lpStgMedium->pUnkForRelease = NULL;
}

void COleServerItem::AddOtherClipboardData(COleDataSource* pDataSource)
{
	ASSERT_VALID(this);
	ASSERT_VALID(pDataSource);

	// get IEnumFORMATETC interface for the IDataObject
	LPDATAOBJECT lpDataObject = GetDataObject();
	LPENUMFORMATETC lpEnumFORMATETC;
	if (lpDataObject->EnumFormatEtc(DATADIR_GET, &lpEnumFORMATETC) != S_OK)
		return;
	ASSERT(lpEnumFORMATETC != NULL);

	// get all formats that the object will give us
	FORMATETC formatEtc;
	while (lpEnumFORMATETC->Next(1, &formatEtc, NULL) == S_OK)
	{
		STGMEDIUM stgMedium;
		if (lpDataObject->GetData(&formatEtc, &stgMedium) != S_OK)
		{
			// data is not available
			CoTaskMemFree(formatEtc.ptd);
		}
		else if (stgMedium.pUnkForRelease != NULL)
		{
			// don't cache data with pUnkForRelease != NULL
			::ReleaseStgMedium(&stgMedium);
			CoTaskMemFree(formatEtc.ptd);
		}
		else
		{
			// cache the data (now we own the stgMedium)
			pDataSource->CacheData(0, &stgMedium, &formatEtc);
		}
	}

	// cleanup
	lpEnumFORMATETC->Release();
}

LPMONIKER COleServerItem::GetMoniker(OLEGETMONIKER nAssign)
{
	// get IOleObject interface for this item
	LPOLEOBJECT lpOleObject = GetOleObject();
	ASSERT(lpOleObject != NULL);

	// get moniker from OLE object
	LPMONIKER lpMoniker = NULL;
	lpOleObject->GetMoniker(nAssign, OLEWHICHMK_OBJFULL, &lpMoniker);
	return lpMoniker;
}

BOOL COleServerItem::GetLinkSourceData(LPSTGMEDIUM lpStgMedium)
{
	ASSERT_VALID(this);
	ASSERT(AfxIsValidAddress(lpStgMedium, sizeof(STGMEDIUM)));

	LPOLEOBJECT lpOleObject = GetOleObject();
	ASSERT(lpOleObject != NULL);

	// get moniker from ole object
	LPMONIKER lpMoniker;
	SCODE sc = lpOleObject->GetMoniker(OLEGETMONIKER_TEMPFORUSER,
		OLEWHICHMK_OBJFULL, &lpMoniker);
	if (sc != S_OK)
	{
		TRACE0("Warning: unable to get moniker for object.\n");
		return FALSE;
	}
	ASSERT(lpMoniker != NULL);

	// create a memory based stream to write the moniker to
	LPSTREAM lpStream;
	if (::CreateStreamOnHGlobal(NULL, TRUE, &lpStream) != S_OK)
	{
		lpMoniker->Release();
		AfxThrowMemoryException();
	}
	ASSERT(lpStream != NULL);

	// write the moniker to the stream, and add it to the clipboard
	sc = ::OleSaveToStream(lpMoniker, lpStream);
	lpMoniker->Release();
	if (sc != S_OK)
	{
		lpStream->Release();
		AfxThrowOleException(sc);
	}

	// write the class ID of the document to the stream as well
	COleLinkingDoc* pDoc = GetDocument();
	ASSERT(pDoc->m_pFactory != NULL);
	sc = WriteClassStm(lpStream, pDoc->m_pFactory->GetClassID());
	if (sc != S_OK)
	{
		lpStream->Release();
		AfxThrowOleException(sc);
	}

	// setup the STGMEDIUM
	lpStgMedium->tymed = TYMED_ISTREAM;
	lpStgMedium->pstm = lpStream;
	lpStgMedium->pUnkForRelease = NULL;
	return TRUE;
}

void COleServerItem::GetObjectDescriptorData(
	LPPOINT lpOffset, LPSIZE lpSize, LPSTGMEDIUM lpStgMedium)
{
	ASSERT_VALID(this);
	ASSERT(AfxIsValidAddress(lpStgMedium, sizeof(STGMEDIUM)));
	ASSERT(lpOffset == NULL ||
		AfxIsValidAddress(lpOffset, sizeof(POINT), FALSE));

	LPOLEOBJECT lpOleObject = GetOleObject();
	ASSERT(lpOleObject != NULL);

	// get the object descriptor for the IOleObject
	POINTL pointl = { 0, 0 };
	if (lpOffset != NULL)
	{
		CSize ptOffset(lpOffset->x, lpOffset->y);
		((CDC*)NULL)->DPtoHIMETRIC(&ptOffset);
		pointl.x = ptOffset.cx;
		pointl.y = ptOffset.cy;
	}
	SIZEL sizel;
	if (lpSize != NULL)
	{
		sizel.cx = lpSize->cx;
		sizel.cy = lpSize->cy;
		((CDC*)NULL)->DPtoHIMETRIC(&sizel);
	}
	else
	{
		sizel.cx = 0;
		sizel.cy = 0;
	}

	InterlockedIncrement(&m_dwRef);  // protect against destruction during this call
	HGLOBAL hGlobal = _AfxOleGetObjectDescriptorData(
		lpOleObject, NULL, DVASPECT_CONTENT, pointl, &sizel);
	InterlockedDecrement(&m_dwRef);

	if (hGlobal == NULL)
		AfxThrowMemoryException();

	// setup the STGMEDIUM
	lpStgMedium->tymed = TYMED_HGLOBAL;
	lpStgMedium->hGlobal = hGlobal;
	lpStgMedium->pUnkForRelease = NULL;
}

void COleServerItem::OnSaveEmbedding(LPSTORAGE lpStorage)
{
	ASSERT(lpStorage != NULL);

	// always (logically) a "File.Save Copy As" operation
	COleServerDoc* pDoc = GetDocument();
	LPSTORAGE lpOrigStg = pDoc->m_lpRootStg;
	pDoc->m_lpRootStg = lpStorage;

	TRY
	{
		ASSERT(pDoc->m_lpRootStg != NULL);
		pDoc->SaveToStorage(this);  // use helper to serialize to storage
	}
	CATCH_ALL(e)
	{
		// save as failed: re-attach original storage
		pDoc->m_lpRootStg = lpOrigStg;
		THROW_LAST();
	}
	END_CATCH_ALL

	// re-attach original storage
	pDoc->m_lpRootStg = lpOrigStg;
}

/////////////////////////////////////////////////////////////////////////////
// COleServerItem data-object callback default implementation

BOOL COleServerItem::OnRenderGlobalData(
	LPFORMATETC /*lpFormatEtc*/, HGLOBAL* /*phGlobal*/)
{
	ASSERT_VALID(this);

	return FALSE;   // default does nothing
}

BOOL COleServerItem::OnRenderFileData(
	LPFORMATETC /*lpFormatEtc*/, CFile* /*pFile*/)
{
	ASSERT_VALID(this);

	return FALSE;   // default does nothing
}

BOOL COleServerItem::OnRenderData(LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium)
{
	ASSERT_VALID(this);
	ASSERT(AfxIsValidAddress(lpFormatEtc, sizeof(FORMATETC), FALSE));
	ASSERT(AfxIsValidAddress(lpStgMedium, sizeof(STGMEDIUM)));

	// default implementation does not support extended layout
	if (lpFormatEtc->lindex != -1)
		return FALSE;

	// default implementation supports both types of metafiles
	if (lpFormatEtc->cfFormat == CF_METAFILEPICT)
		return GetMetafileData(lpFormatEtc, lpStgMedium);

	return FALSE;   // cfFormat not supported
}

BOOL COleServerItem::OnSetData(
	LPFORMATETC /*lpFormatEtc*/, LPSTGMEDIUM /*lpStgMedium*/, BOOL /*bRelease*/)
{
	ASSERT_VALID(this);

	return FALSE;   // default does nothing
}

/////////////////////////////////////////////////////////////////////////////
// COleServerItem OLE interface implementation

BEGIN_INTERFACE_MAP(COleServerItem, CDocItem)
	INTERFACE_PART(COleServerItem, IID_IOleObject, OleObject)
	INTERFACE_PART(COleServerItem, IID_IDataObject, DataObject)
END_INTERFACE_MAP()

/////////////////////////////////////////////////////////////////////////////
// COleServerItem::XOleObject

STDMETHODIMP_(ULONG) COleServerItem::XOleObject::AddRef()
{
	METHOD_PROLOGUE_EX_(COleServerItem, OleObject)
	return pThis->ExternalAddRef();
}

STDMETHODIMP_(ULONG) COleServerItem::XOleObject::Release()
{
	METHOD_PROLOGUE_EX_(COleServerItem, OleObject)
	return pThis->ExternalRelease();
}

STDMETHODIMP COleServerItem::XOleObject::QueryInterface(
	REFIID iid, LPVOID* ppvObj)
{
	METHOD_PROLOGUE_EX_(COleServerItem, OleObject)
	return pThis->ExternalQueryInterface(&iid, ppvObj);
}

// COleServerItem has special Release semantics.  In particular, the item
//  is only deleted from memory if m_bAutoDelete is TRUE.
//  Also, it unlocks the document if the reference count reaches zero.

void COleServerItem::OnFinalRelease()
{
	ASSERT_VALID(this);

	COleServerDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	pDoc->InternalAddRef(); // make document stable

	// if connected to a document -- remove external lock from it
	if (m_bNeedUnlock)
	{
		pDoc->LockExternal(FALSE, TRUE);
		m_bNeedUnlock = FALSE;
	}

	// delete this item if no longer needed
	if (m_bAutoDelete)
		delete this;

	// release artificial reference (may destroy the document)
	pDoc->InternalRelease();
}

STDMETHODIMP COleServerItem::XOleObject::SetClientSite(
	LPOLECLIENTSITE /*pClientSite*/)
{
	// linked objects do not support SetClientSite

	return E_NOTIMPL;
}

STDMETHODIMP COleServerItem::XOleObject::GetClientSite(
	LPOLECLIENTSITE* ppClientSite)
{
	// linked objects do not support GetClientSite

	*ppClientSite = NULL;
	return E_NOTIMPL;
}

STDMETHODIMP COleServerItem::XOleObject::SetHostNames(
	LPCOLESTR /*szContainerApp*/, LPCOLESTR /*szContainerObj*/)
{
	// linked objects do not support SetHostNames

	return E_NOTIMPL;
}

STDMETHODIMP COleServerItem::XOleObject::Close(DWORD /*dwSaveOption*/)
{
	// linked objects do not support close

	return E_NOTIMPL;
}

STDMETHODIMP COleServerItem::XOleObject::SetMoniker(
	DWORD /*dwWhichMoniker*/, LPMONIKER /*pmk*/)
{
	// linked objects do not support SetMoniker

	return E_NOTIMPL;
}

STDMETHODIMP COleServerItem::XOleObject::GetMoniker(
	DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER* ppMoniker)
{
	USES_CONVERSION;

	METHOD_PROLOGUE_EX(COleServerItem, OleObject)
	ASSERT_VALID(pThis);

	COleServerDoc* pDoc = pThis->GetDocument();
	ASSERT_VALID(pDoc);
	ASSERT_KINDOF(COleServerDoc, pDoc);
	ASSERT(ppMoniker != NULL);
	*ppMoniker = NULL;

	switch (dwWhichMoniker)
	{
	case OLEWHICHMK_CONTAINER:
		// simply return the moniker of the container document
		*ppMoniker = pDoc->GetMoniker((OLEGETMONIKER)dwAssign);
		break;

	case OLEWHICHMK_OBJREL:
		{
			// no relative moniker if no item name
			if (pThis->m_strItemName.IsEmpty())
				break;

			// don't return relative moniker if no document moniker
			LPMONIKER lpMoniker = pDoc->GetMoniker((OLEGETMONIKER)dwAssign);
			if (lpMoniker == NULL)
				break;
			lpMoniker->Release();   // don't need document moniker

			// relative monikers have to handle assignment correctly
			switch (dwAssign)
			{
			case OLEGETMONIKER_TEMPFORUSER:
			case OLEGETMONIKER_ONLYIFTHERE:
			case OLEGETMONIKER_FORCEASSIGN:
				// create item moniker from name
				CreateItemMoniker(OLESTDDELIMOLE, T2COLE(pThis->m_strItemName),
					ppMoniker);
				break;

			case OLEGETMONIKER_UNASSIGN:
				ASSERT(FALSE);  // should never get UNASSIGN
				break;
			}
		}
		break;

	case OLEWHICHMK_OBJFULL:
		{
			// get each sub-moniker: item & document
			LPMONIKER lpMoniker1, lpMoniker2;
			GetMoniker(dwAssign, OLEWHICHMK_CONTAINER, &lpMoniker1);

⌨️ 快捷键说明

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