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

📄 oledobj2.cpp

📁 vc6.0完整版
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	if (lpFormatEtc->tymed & TYMED_ISTREAM)
	{
		COleStreamFile file;
		if (lpStgMedium->tymed == TYMED_ISTREAM)
		{
			ASSERT(lpStgMedium->pstm != NULL);
			file.Attach(lpStgMedium->pstm);
		}
		else
		{
			if (!file.CreateMemoryStream())
				AfxThrowMemoryException();
		}
		// get data into the stream
		if (OnRenderFileData(lpFormatEtc, &file))
		{
			lpStgMedium->tymed = TYMED_ISTREAM;
			lpStgMedium->pstm = file.Detach();
			return TRUE;
		}
		if (lpStgMedium->tymed == TYMED_ISTREAM)
			file.Detach();
	}

	return FALSE;   // default does nothing
}

BOOL COleDataSource::OnSetData(
	LPFORMATETC /*lpFormatEtc*/, LPSTGMEDIUM /*lpStgMedium*/, BOOL /*bRelease*/)
{
	return FALSE;   // default does nothing
}

/////////////////////////////////////////////////////////////////////////////
// CEnumFormatEtc - enumerator for array for FORMATETC structures

class CEnumFormatEtc : public CEnumArray
{
// Constructors
public:
	CEnumFormatEtc();

// Operations
	void AddFormat(const FORMATETC* lpFormatEtc);

// Implementation
public:
	virtual ~CEnumFormatEtc();

protected:
	virtual BOOL OnNext(void* pv);

	UINT m_nMaxSize;    // number of items allocated (>= m_nSize)
	DECLARE_INTERFACE_MAP()
};

BEGIN_INTERFACE_MAP(CEnumFormatEtc, CEnumArray)
	INTERFACE_PART(CEnumFormatEtc, IID_IEnumFORMATETC, EnumVOID)
END_INTERFACE_MAP()

CEnumFormatEtc::CEnumFormatEtc()
	: CEnumArray(sizeof(FORMATETC), NULL, 0, TRUE)
{
	m_nMaxSize = 0;
}

CEnumFormatEtc::~CEnumFormatEtc()
{
	if (m_pClonedFrom == NULL)
	{
		// release all of the pointers to DVTARGETDEVICE
		LPFORMATETC lpFormatEtc = (LPFORMATETC)m_pvEnum;
		for (UINT nIndex = 0; nIndex < m_nSize; nIndex++)
			CoTaskMemFree(lpFormatEtc[nIndex].ptd);
	}
	// destructor will free the actual array (if it was not a clone)
}

BOOL CEnumFormatEtc::OnNext(void* pv)
{
	if (!CEnumArray::OnNext(pv))
		return FALSE;

	// any outgoing formatEtc may require the DVTARGETDEVICE to
	//  be copied (the caller has responsibility to free it)
	LPFORMATETC lpFormatEtc = (LPFORMATETC)pv;
	if (lpFormatEtc->ptd != NULL)
	{
		lpFormatEtc->ptd = _AfxOleCopyTargetDevice(lpFormatEtc->ptd);
		if (lpFormatEtc->ptd == NULL)
			AfxThrowMemoryException();
	}
	// otherwise, copying worked...
	return TRUE;
}

void CEnumFormatEtc::AddFormat(const FORMATETC* lpFormatEtc)
{
	ASSERT(m_nSize <= m_nMaxSize);

	if (m_nSize == m_nMaxSize)
	{
		// not enough space for new item -- allocate more
		FORMATETC* pListNew = new FORMATETC[m_nSize+10];
		m_nMaxSize += 10;
		memcpy(pListNew, m_pvEnum, m_nSize*sizeof(FORMATETC));
		delete m_pvEnum;
		m_pvEnum = (BYTE*)pListNew;
	}

	// add this item to the list
	ASSERT(m_nSize < m_nMaxSize);
	FORMATETC* pFormat = &((FORMATETC*)m_pvEnum)[m_nSize];
	pFormat->cfFormat = lpFormatEtc->cfFormat;
	pFormat->ptd = lpFormatEtc->ptd;
		// Note: ownership of lpFormatEtc->ptd is transfered with this call.
	pFormat->dwAspect = lpFormatEtc->dwAspect;
	pFormat->lindex = lpFormatEtc->lindex;
	pFormat->tymed = lpFormatEtc->tymed;
	++m_nSize;
}

/////////////////////////////////////////////////////////////////////////////
// COleDataSource::XDataObject

BEGIN_INTERFACE_MAP(COleDataSource, CCmdTarget)
	INTERFACE_PART(COleDataSource, IID_IDataObject, DataObject)
END_INTERFACE_MAP()

STDMETHODIMP_(ULONG) COleDataSource::XDataObject::AddRef()
{
	METHOD_PROLOGUE_EX_(COleDataSource, DataObject)
	return pThis->ExternalAddRef();
}

STDMETHODIMP_(ULONG) COleDataSource::XDataObject::Release()
{
	METHOD_PROLOGUE_EX_(COleDataSource, DataObject)
	return pThis->ExternalRelease();
}

STDMETHODIMP COleDataSource::XDataObject::QueryInterface(
	REFIID iid, LPVOID* ppvObj)
{
	METHOD_PROLOGUE_EX_(COleDataSource, DataObject)
	return pThis->ExternalQueryInterface(&iid, ppvObj);
}

STDMETHODIMP COleDataSource::XDataObject::GetData(
	LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium)
{
	METHOD_PROLOGUE_EX(COleDataSource, DataObject)
	ASSERT_VALID(pThis);

	// attempt to find match in the cache
	AFX_DATACACHE_ENTRY* pCache = pThis->Lookup(lpFormatEtc, DATADIR_GET);
	if (pCache == NULL)
		return DATA_E_FORMATETC;

	// use cache if entry is not delay render
	memset(lpStgMedium, 0, sizeof(STGMEDIUM));
	if (pCache->m_stgMedium.tymed != TYMED_NULL)
	{
		// Copy the cached medium into the lpStgMedium provided by caller.
		if (!_AfxCopyStgMedium(lpFormatEtc->cfFormat, lpStgMedium,
		  &pCache->m_stgMedium))
			return DATA_E_FORMATETC;

		// format was supported for copying
		return S_OK;
	}

	SCODE sc = DATA_E_FORMATETC;
	TRY
	{
		// attempt LPSTGMEDIUM based delay render
		if (pThis->OnRenderData(lpFormatEtc, lpStgMedium))
			sc = S_OK;
	}
	CATCH_ALL(e)
	{
		sc = COleException::Process(e);
		DELETE_EXCEPTION(e);
	}
	END_CATCH_ALL

	return sc;
}

STDMETHODIMP COleDataSource::XDataObject::GetDataHere(
	LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium)
{
	METHOD_PROLOGUE_EX(COleDataSource, DataObject)
	ASSERT_VALID(pThis);

	// these two must be the same
	ASSERT(lpFormatEtc->tymed == lpStgMedium->tymed);
	lpFormatEtc->tymed = lpStgMedium->tymed;    // but just in case...

	// attempt to find match in the cache
	AFX_DATACACHE_ENTRY* pCache = pThis->Lookup(lpFormatEtc, DATADIR_GET);
	if (pCache == NULL)
		return DATA_E_FORMATETC;

	// handle cached medium and copy
	if (pCache->m_stgMedium.tymed != TYMED_NULL)
	{
		// found a cached format -- copy it to dest medium
		ASSERT(pCache->m_stgMedium.tymed == lpStgMedium->tymed);
		if (!_AfxCopyStgMedium(lpFormatEtc->cfFormat, lpStgMedium,
		  &pCache->m_stgMedium))
			return DATA_E_FORMATETC;

		// format was supported for copying
		return S_OK;
	}

	SCODE sc = DATA_E_FORMATETC;
	TRY
	{
		// attempt LPSTGMEDIUM based delay render
		if (pThis->OnRenderData(lpFormatEtc, lpStgMedium))
			sc = S_OK;
	}
	CATCH_ALL(e)
	{
		sc = COleException::Process(e);
		DELETE_EXCEPTION(e);
	}
	END_CATCH_ALL

	return sc;
}

STDMETHODIMP COleDataSource::XDataObject::QueryGetData(LPFORMATETC lpFormatEtc)
{
	METHOD_PROLOGUE_EX_(COleDataSource, DataObject)

	// attempt to find match in the cache
	AFX_DATACACHE_ENTRY* pCache = pThis->Lookup(lpFormatEtc, DATADIR_GET);
	if (pCache == NULL)
		return DATA_E_FORMATETC;

	// it was found in the cache or can be rendered -- success
	return S_OK;
}

STDMETHODIMP COleDataSource::XDataObject::GetCanonicalFormatEtc(
	LPFORMATETC /*lpFormatEtcIn*/, LPFORMATETC /*lpFormatEtcOut*/)
{
	// because we support the target-device (ptd) for server metafile format,
	//  all members of the FORMATETC are significant.

	return DATA_S_SAMEFORMATETC;
}

STDMETHODIMP COleDataSource::XDataObject::SetData(
	LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium, BOOL bRelease)
{
	METHOD_PROLOGUE_EX(COleDataSource, DataObject)
	ASSERT_VALID(pThis);

	ASSERT(lpFormatEtc->tymed == lpStgMedium->tymed);

	// attempt to find match in the cache
	AFX_DATACACHE_ENTRY* pCache = pThis->Lookup(lpFormatEtc, DATADIR_SET);
	if (pCache == NULL)
		return DATA_E_FORMATETC;

	ASSERT(pCache->m_stgMedium.tymed == TYMED_NULL);

	SCODE sc = E_UNEXPECTED;
	TRY
	{
		// attempt LPSTGMEDIUM based SetData
		if (pThis->OnSetData(lpFormatEtc, lpStgMedium, bRelease))
			sc = S_OK;
	}
	CATCH_ALL(e)
	{
		sc = COleException::Process(e);
		DELETE_EXCEPTION(e);
	}
	END_CATCH_ALL

	return sc;
}

STDMETHODIMP COleDataSource::XDataObject::EnumFormatEtc(
	DWORD dwDirection, LPENUMFORMATETC* ppenumFormatEtc)
{
	METHOD_PROLOGUE_EX_(COleDataSource, DataObject)

	*ppenumFormatEtc = NULL;

	CEnumFormatEtc* pFormatList = NULL;
	SCODE sc = E_OUTOFMEMORY;
	TRY
	{
		// generate a format list from the cache
		pFormatList = new CEnumFormatEtc;
		for (UINT nIndex = 0; nIndex < pThis->m_nSize; nIndex++)
		{
			AFX_DATACACHE_ENTRY* pCache = &pThis->m_pDataCache[nIndex];
			if ((DWORD)pCache->m_nDataDir & dwDirection)
			{
				// entry should be enumerated -- add it to the list
				FORMATETC formatEtc;
				_AfxOleCopyFormatEtc(&formatEtc, &pCache->m_formatEtc);
				pFormatList->AddFormat(&formatEtc);
			}
		}
		// give it away to OLE (ref count is already 1)
		*ppenumFormatEtc = (LPENUMFORMATETC)&pFormatList->m_xEnumVOID;
		sc = S_OK;
	}
	END_TRY

	return sc;
}

STDMETHODIMP COleDataSource::XDataObject::DAdvise(
	FORMATETC* /*pFormatetc*/, DWORD /*advf*/,
	LPADVISESINK /*pAdvSink*/, DWORD* pdwConnection)
{
	*pdwConnection = 0;
	return OLE_E_ADVISENOTSUPPORTED;
}

STDMETHODIMP COleDataSource::XDataObject::DUnadvise(DWORD /*dwConnection*/)
{
	return OLE_E_ADVISENOTSUPPORTED;
}

STDMETHODIMP COleDataSource::XDataObject::EnumDAdvise(
	LPENUMSTATDATA* ppenumAdvise)
{
	*ppenumAdvise = NULL;
	return OLE_E_ADVISENOTSUPPORTED;
}

/////////////////////////////////////////////////////////////////////////////
// COleDataSource diagnostics

#ifdef _DEBUG
void COleDataSource::AssertValid() const
{
	CCmdTarget::AssertValid();
	ASSERT(m_nSize <= m_nMaxSize);
	ASSERT(m_nMaxSize != 0 || m_pDataCache == NULL);
}

void COleDataSource::Dump(CDumpContext& dc) const
{
	CCmdTarget::Dump(dc);

	dc << "m_nMaxSize = " << m_nMaxSize;
	dc << "\nm_nSize = " << m_nSize;
	dc << "\nm_pDataCache = " << m_pDataCache;

	for (UINT n = 0; n < m_nSize; n++)
	{
		dc << "\n\tentry [" << n << "] = {";
		AFX_DATACACHE_ENTRY& rEntry = m_pDataCache[n];
		dc << "\n\t m_formatEtc.cfFormat = " << rEntry.m_formatEtc.cfFormat;
		dc << "\n\t m_formatEtc.pdt = " << rEntry.m_formatEtc.ptd;
		dc << "\n\t m_formatEtc.dwAspect = " << rEntry.m_formatEtc.dwAspect;
		dc << "\n\t m_formatEtc.lindex = " << rEntry.m_formatEtc.lindex;
		dc << "\n\t m_formatEtc.tymed = " << rEntry.m_formatEtc.tymed;
		dc << "\n\t m_stgMedium.tymed = " << rEntry.m_stgMedium.tymed;
		dc << "\n\t m_nDataDir = " << (UINT)rEntry.m_nDataDir;
		dc << "\n\t}";
	}

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

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

⌨️ 快捷键说明

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