STDMETHODIMP CDataObject::GetData(FORMATETC *pFormatEtc, STGMEDIUM *pStgMedium) { LONG idx = LookupFormatEtc(pFormatEtc); if (idx == -1) { return DV_E_FORMATETC; } memset(pStgMedium, 0, sizeof(STGMEDIUM)); if(m_vtFtmEtc[idx].tymed != TYMED_NULL) { if (!CopyStgMedium(pFormatEtc->cfFormat, pStgMedium, &m_vtStgMedium[idx])) { ATLTRACE(L"\nGetData: %d, hr=%x", pFormatEtc->cfFormat, DATA_E_FORMATETC); return DATA_E_FORMATETC; } ATLTRACE(L"\nGetData: %d, hr=%x", pFormatEtc->cfFormat, 0); return S_OK; } ATLTRACE(L"\nGetData: %d, hr=%x", pFormatEtc->cfFormat, DATA_E_FORMATETC); return DATA_E_FORMATETC; }
/*********************************************************************** * CopyBindInfo (URLMON.@) */ HRESULT WINAPI CopyBindInfo(const BINDINFO *pcbiSrc, BINDINFO *pcbiDest) { DWORD size; HRESULT hres; TRACE("(%p %p)\n", pcbiSrc, pcbiDest); if(!pcbiSrc || !pcbiDest) return E_POINTER; if(!pcbiSrc->cbSize || !pcbiDest->cbSize) return E_INVALIDARG; size = pcbiDest->cbSize; if(size > pcbiSrc->cbSize) { memcpy(pcbiDest, pcbiSrc, pcbiSrc->cbSize); memset((char*)pcbiDest+pcbiSrc->cbSize, 0, size-pcbiSrc->cbSize); } else { memcpy(pcbiDest, pcbiSrc, size); } pcbiDest->cbSize = size; size = FIELD_OFFSET(BINDINFO, szExtraInfo)+sizeof(void*); if(pcbiSrc->cbSize>=size && pcbiDest->cbSize>=size && pcbiSrc->szExtraInfo) { size = (strlenW(pcbiSrc->szExtraInfo)+1)*sizeof(WCHAR); pcbiDest->szExtraInfo = CoTaskMemAlloc(size); if(!pcbiDest->szExtraInfo) return E_OUTOFMEMORY; memcpy(pcbiDest->szExtraInfo, pcbiSrc->szExtraInfo, size); } size = FIELD_OFFSET(BINDINFO, stgmedData)+sizeof(STGMEDIUM); if(pcbiSrc->cbSize>=size && pcbiDest->cbSize>=size) { hres = CopyStgMedium(&pcbiSrc->stgmedData, &pcbiDest->stgmedData); if(FAILED(hres)) { CoTaskMemFree(pcbiDest->szExtraInfo); return hres; } } size = FIELD_OFFSET(BINDINFO, szCustomVerb)+sizeof(void*); if(pcbiSrc->cbSize>=size && pcbiDest->cbSize>=size && pcbiSrc->szCustomVerb) { size = (strlenW(pcbiSrc->szCustomVerb)+1)*sizeof(WCHAR); pcbiDest->szCustomVerb = CoTaskMemAlloc(size); if(!pcbiDest->szCustomVerb) { CoTaskMemFree(pcbiDest->szExtraInfo); ReleaseStgMedium(&pcbiDest->stgmedData); return E_OUTOFMEMORY; } memcpy(pcbiDest->szCustomVerb, pcbiSrc->szCustomVerb, size); } size = FIELD_OFFSET(BINDINFO, securityAttributes)+sizeof(SECURITY_ATTRIBUTES); if(pcbiDest->cbSize >= size) memset(&pcbiDest->securityAttributes, 0, sizeof(SECURITY_ATTRIBUTES)); if(pcbiSrc->pUnk) IUnknown_AddRef(pcbiDest->pUnk); return S_OK; }
// // IDataObject::SetData // HRESULT __stdcall CDataObject::SetData (FORMATETC *pFormatEtc, STGMEDIUM *pMedium, BOOL fRelease) { int res=LookupFormatEtc(pFormatEtc, pMedium, TRUE); if(-1 == res) { return S_FALSE; } if (m_pStgMedium[res].tymed) { ReleaseStgMedium ( &m_pStgMedium[res] ); ZeroMemory (&m_pStgMedium[res], sizeof(STGMEDIUM) ); } if(fRelease) { m_pStgMedium[res]=*pMedium; } else { CopyStgMedium(pMedium, &m_pStgMedium[res]); } m_pFormatEtc[res].tymed=m_pStgMedium[res].tymed; if(m_pStgMedium[res].tymed==TYMED_HGLOBAL) { m_pStgMedium[res].hGlobal=DupMem(pMedium->hGlobal);//必须分配足够的内存空间和拷贝数据。 } if(GetCanonicalIUnknown(m_pStgMedium[res].pUnkForRelease)== GetCanonicalIUnknown(static_cast<IDataObject*>(this))) { m_pStgMedium[res].pUnkForRelease->Release(); m_pStgMedium[res].pUnkForRelease = NULL; } return S_OK; }