diff options
Diffstat (limited to 'private/oleutest/simpdnd/dxferobj.cpp')
-rw-r--r-- | private/oleutest/simpdnd/dxferobj.cpp | 739 |
1 files changed, 739 insertions, 0 deletions
diff --git a/private/oleutest/simpdnd/dxferobj.cpp b/private/oleutest/simpdnd/dxferobj.cpp new file mode 100644 index 000000000..c95dbe8bf --- /dev/null +++ b/private/oleutest/simpdnd/dxferobj.cpp @@ -0,0 +1,739 @@ +//********************************************************************** +// File name: DXFEROBJ.CPP +// +// Implementation file for CDataXferObj, data transfer object +// implementation of IDataObject interface. +// +// Functions: +// +// See DXFEROBJ.H for class definition +// +// Copyright (c) 1992 - 1993 Microsoft Corporation. All rights reserved. +//********************************************************************** + +#include "pre.h" +#include <enumfetc.h> +#include <assert.h> +#include "dxferobj.h" +#include "site.h" + +//BUGBUG: These should be fetched from real header files +#define CF_HDROP 15 +typedef struct _dropfilestruct { + DWORD pFiles; + POINT pt; + BOOL fNC; + BOOL fWide; +} DROPFILESTRUCT; + + +CLIPFORMAT g_cfEmbeddedObject=RegisterClipboardFormat(CF_EMBEDDEDOBJECT); +CLIPFORMAT g_cfObjectDescriptor=RegisterClipboardFormat(CF_OBJECTDESCRIPTOR); + +// List of formats offered by our data transfer object via EnumFormatEtc +static FORMATETC s_arrGetFmtEtcs[] = +{ + { g_cfEmbeddedObject, NULL, DVASPECT_CONTENT, -1, TYMED_ISTORAGE}, + { g_cfObjectDescriptor, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}, + { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT} +}; + + +//********************************************************************** +// +// CDataXferObj::Create +// +// Purpose: +// +// Creation routine for CDataXferObj +// +// Parameters: +// +// CSimpleSite FAR *lpSite - Pointer to source CSimpleSite +// this is the container site of the +// source OLE object to be transfered +// +// Return Value: +// +// None +// +// Function Calls: +// Function Location +// +// StgCreateDocfile OLE API +// assert C Runtime +// +// Comments: +// reference count of CDataXferObj will be 0 on return. +// +//******************************************************************** + +CDataXferObj FAR * CDataXferObj::Create( + CSimpleSite FAR *lpSite, + POINTL FAR* pPointl +) +{ + CDataXferObj FAR * lpTemp = new CDataXferObj(); + + if (!lpTemp) + return NULL; + + // create a sub-storage for the object + HRESULT hErr = StgCreateDocfile( + NULL, + STGM_READWRITE | STGM_DIRECT | STGM_SHARE_EXCLUSIVE | + STGM_DELETEONRELEASE, + 0, + &lpTemp->m_lpObjStorage); + + assert(hErr == NOERROR); + + if (hErr != NOERROR) + { + delete lpTemp; + return NULL; + } + + // Clone the source object + if (lpSite->m_lpOleObject) + { + // Object is loaded; ask the object to save into the new storage + LPPERSISTSTORAGE pPersistStorage; + + if (lpSite->m_lpOleObject->QueryInterface(IID_IPersistStorage, + (LPVOID FAR*)&pPersistStorage) != ResultFromScode(S_OK)) + { + /* cannot find interface + */ + return(NULL); + } + assert(pPersistStorage); + if (OleSave(pPersistStorage, lpTemp->m_lpObjStorage, FALSE) + != ResultFromScode(S_OK)) + { + TestDebugOut("Fail in OleSave\n"); + } + + // pass NULL so that object application won't forget the real stg + if (pPersistStorage->SaveCompleted(NULL) != ResultFromScode(S_OK)) + { + TestDebugOut("Fail in IPersistStorage::SaveCompleted\n"); + } + pPersistStorage->Release(); + } + else + { + // Object not loaded so use cheaper IStorage CopyTo operation + lpSite->m_lpObjStorage->CopyTo(0, NULL, NULL, lpTemp->m_lpObjStorage); + } + + if (OleLoad(lpTemp->m_lpObjStorage, IID_IOleObject, NULL, + (LPVOID FAR*)&lpTemp->m_lpOleObject) + != ResultFromScode(S_OK)) + { + /* we cannot load the embedded/linked object into the memory + */ + return(NULL); + } + assert(lpTemp->m_lpOleObject); + + lpTemp->m_sizel = lpSite->m_sizel; + if (pPointl) + lpTemp->m_pointl = *pPointl; + else + lpTemp->m_pointl.x = lpTemp->m_pointl.y = 0; + return lpTemp; +} + +//********************************************************************** +// +// CDataXferObj::CDataXferObj +// +// Purpose: +// +// Constructor for CDataXferObj +// +// Parameters: +// +// CSimpleDoc FAR *lpDoc - Pointer to CSimpleDoc +// +// Return Value: +// +// None +// +// Function Calls: +// Function Location +// +// +//******************************************************************** + +CDataXferObj::CDataXferObj (void) +{ + // clear the reference count + m_nCount = 0; + + m_lpObjStorage = NULL; + m_lpOleObject = NULL; + m_sizel.cx = m_sizel.cy = 0; + m_pointl.x = m_pointl.y = 0; +} + +//********************************************************************** +// +// CDataXferObj::~CDataXferObj +// +// Purpose: +// +// Destructor for CDataXferObj +// +// Parameters: +// +// None +// +// Return Value: +// +// None +// +// Function Calls: +// Function Location +// +// TestDebugOut Windows API +// IOleObject::Release Object +// IStorage::Release OLE API +// +// +//******************************************************************** + +CDataXferObj::~CDataXferObj () +{ + TestDebugOut ("In CDataXferObj's Destructor \r\n"); + + if (m_lpOleObject) + { + m_lpOleObject->Release(); + m_lpOleObject = NULL; + + // Release the storage for this object + m_lpObjStorage->Release(); + m_lpObjStorage = NULL; + } +} + + + +//********************************************************************** +// +// CDataXferObj::QueryInterface +// +// Purpose: +// +// Used for interface negotiation of the CDataXferObj instance +// +// Parameters: +// +// REFIID riid - A reference to the interface that is +// being queried. +// +// LPVOID FAR* ppvObj - An out parameter to return a pointer to +// the interface. +// +// Return Value: +// +// S_OK - The interface is supported. +// E_NOINTERFACE - The interface is not supported +// +// Function Calls: +// Function Location +// +// TestDebugOut Windows API +// IsEqualIID OLE API +// ResultFromScode OLE API +// CDataXferObj::AddRef DXFEROBJ.CPP +// +// +//******************************************************************** + +STDMETHODIMP CDataXferObj::QueryInterface(REFIID riid, LPVOID FAR* ppvObj) +{ + TestDebugOut("In CDataXferObj::QueryInterface\r\n"); + + if (IsEqualIID( riid, IID_IUnknown) || IsEqualIID(riid, IID_IDataObject)) + { + AddRef(); + *ppvObj = this; + return NOERROR; + } + + // unknown interface requested + *ppvObj = NULL; // must set out pointer parameters to NULL + return ResultFromScode(E_NOINTERFACE); +} + +//********************************************************************** +// +// CDataXferObj::AddRef +// +// Purpose: +// +// Increments the reference count of the CDataXferObj instance +// +// Parameters: +// +// None +// +// Return Value: +// +// ULONG - The new reference count of the object +// +// Function Calls: +// Function Location +// +// TestDebugOut Windows API +// +// +//******************************************************************** + +STDMETHODIMP_(ULONG) CDataXferObj::AddRef() +{ + TestDebugOut("In CDataXferObj::AddRef\r\n"); + + return ++m_nCount; +} + +//********************************************************************** +// +// CDataXferObj::Release +// +// Purpose: +// +// Decrements the reference count of the CDataXferObj object +// +// Parameters: +// +// None +// +// Return Value: +// +// ULONG - The new reference count of the object. +// +// Function Calls: +// Function Location +// +// TestDebugOut Windows API +// +// +//******************************************************************** + +STDMETHODIMP_(ULONG) CDataXferObj::Release() +{ + TestDebugOut("In CDataXferObj::Release\r\n"); + + if (--m_nCount == 0) + { + delete this; + return 0; + } + return m_nCount; +} + + +/******************************************************************** +** This IDataObject implementation is used for data transfer. +** +** The following methods are NOT supported for data transfer: +** IDataObject::SetData -- return E_NOTIMPL +** IDataObject::DAdvise -- return OLE_E_ADVISENOTSUPPORTED +** ::DUnadvise +** ::EnumDAdvise +** IDataObject::GetCanonicalFormatEtc -- return E_NOTIMPL +** (NOTE: must set pformatetcOut->ptd = NULL) +*********************************************************************/ + + +//********************************************************************** +// +// CDataXferObj::QueryGetData +// +// Purpose: +// +// Called to determine if our object supports a particular +// FORMATETC. +// +// Parameters: +// +// LPFORMATETC pformatetc - Pointer to the FORMATETC being queried for. +// +// Return Value: +// +// DV_E_FORMATETC - The FORMATETC is not supported +// S_OK - The FORMATETC is supported. +// +// +// Function Calls: +// Function Location +// +// TestDebugOut Windows API +// ResultFromScode OLE API +// +// Comments: +// we support the following formats: +// "Embedded Object" +// "Object Descriptor" +// CF_METAFILEPICT +// +//******************************************************************** +STDMETHODIMP CDataXferObj::QueryGetData (LPFORMATETC pformatetc) +{ + SCODE sc = DV_E_FORMATETC; + + TestDebugOut("In CDataXferObj::QueryGetData\r\n"); + + // check the validity of the formatetc. + + if ( (pformatetc->cfFormat == g_cfEmbeddedObject) && + (pformatetc->dwAspect == DVASPECT_CONTENT) && + (pformatetc->tymed == TYMED_ISTORAGE) ) + { + sc = S_OK; + } + + else if ( (pformatetc->cfFormat == g_cfObjectDescriptor) && + (pformatetc->dwAspect == DVASPECT_CONTENT) && + (pformatetc->tymed == TYMED_HGLOBAL) ) + { + sc = S_OK; + } + + else if ( (pformatetc->cfFormat == CF_METAFILEPICT) && + (pformatetc->dwAspect == DVASPECT_CONTENT) && + (pformatetc->tymed == TYMED_MFPICT) ) + { + sc = S_OK; + } + else if ( (pformatetc->cfFormat == CF_HDROP) && + (pformatetc->dwAspect == DVASPECT_CONTENT) && + (pformatetc->tymed == TYMED_HGLOBAL) ) + { + sc = S_OK; + } + + return ResultFromScode(sc); +} + +extern BOOL gfUseEmptyEnumerator; + +//********************************************************************** +// +// CDataXferObj::EnumFormatEtc +// +// Purpose: +// +// Enumerates the formats that can be used to store data +// +// Parameters: +// +// DWORD dwDirection - format to be enumerated +// +// LPENUMFORMATETC ppenumFormatEtc - where to return the +// instantiated enumerator +// +// Return Value: +// +// S_OK - if the operation is successful +// E_OUTOFMEMORY - if ran out of memory +// E_NOTIMPL - if dwDirection is not supported +// +// +// Function Calls: +// Function Location +// +// TestDebugOut Windows API +// ResultFromScode OLE API +// OleStdEnumFmtEtc_Create OLE2UI +// +//********************************************************************** + +STDMETHODIMP CDataXferObj::EnumFormatEtc( + DWORD dwDirection, + LPENUMFORMATETC FAR* ppenumFormatEtc +) +{ + SCODE sc = E_NOTIMPL; + + TestDebugOut("In CDataXferObj::EnumFormatEtc\r\n"); + *ppenumFormatEtc = NULL; + + if( gfUseEmptyEnumerator == TRUE ) + { + return E_FAIL; + } + + if (dwDirection == DATADIR_GET) + { + *ppenumFormatEtc = OleStdEnumFmtEtc_Create( + sizeof(s_arrGetFmtEtcs)/sizeof(s_arrGetFmtEtcs[0]), + s_arrGetFmtEtcs); + if (*ppenumFormatEtc == NULL) + sc = E_OUTOFMEMORY; + else + sc = S_OK; + } + return ResultFromScode(sc); +} + + +//********************************************************************** +// +// CDataXferObj::GetData +// +// Purpose: +// +// Returns the data in the format specified in pformatetcIn. +// +// Parameters: +// +// LPFORMATETC pformatetcIn - The format requested by the caller +// +// LPSTGMEDIUM pmedium - The medium requested by the caller +// +// Return Value: +// +// DV_E_FORMATETC - Format not supported +// S_OK - Success +// +// Function Calls: +// Function Location +// +// TestDebugOut Windows API +// OleStdGetOleObjectData OLE2UI API +// OleStdGetMetafilePictFromOleObject OLE2UI API +// OleStdGetObjectDescriptorDataFromOleObject OLE2UI API +// ResultFromScode OLE API +// IOleObject::QueryInterface Object +// +// Comments: +// we support GetData for the following formats: +// "Embedded Object" +// "Object Descriptor" +// CF_METAFILEPICT +// +//******************************************************************** + +STDMETHODIMP CDataXferObj::GetData ( + LPFORMATETC pformatetcIn, + LPSTGMEDIUM pmedium +) +{ + SCODE sc = DV_E_FORMATETC; + + TestDebugOut("In CDataXferObj::GetData\r\n"); + + // we must set all out pointer parameters to NULL. */ + pmedium->tymed = TYMED_NULL; + pmedium->pUnkForRelease = NULL; // we transfer ownership to caller + pmedium->hGlobal = NULL; + + // Check the FORMATETC and fill pmedium if valid. + if ( (pformatetcIn->cfFormat == g_cfEmbeddedObject) && + (pformatetcIn->dwAspect == DVASPECT_CONTENT) && + (pformatetcIn->tymed == TYMED_ISTORAGE) ) + { + LPPERSISTSTORAGE pPersistStorage; + + /* render CF_EMBEDDEDOBJECT by asking the object to save + ** into a temporary, DELETEONRELEASE IStorage allocated by us. + */ + HRESULT hRes; + if ((hRes=m_lpOleObject->QueryInterface( + IID_IPersistStorage, (LPVOID FAR*)&pPersistStorage)) + != ResultFromScode(S_OK)) + { + return(hRes); + } + + assert(pPersistStorage); + HRESULT hrErr = OleStdGetOleObjectData( + pPersistStorage, + pformatetcIn, + pmedium, + FALSE /* fUseMemory -- (use file-base stg) */ + ); + pPersistStorage->Release(); + sc = GetScode( hrErr ); + + } + else if ( (pformatetcIn->cfFormat == g_cfObjectDescriptor) && + (pformatetcIn->dwAspect == DVASPECT_CONTENT) && + (pformatetcIn->tymed == TYMED_HGLOBAL) ) + { + + // render CF_OBJECTDESCRIPTOR data + pmedium->hGlobal = OleStdGetObjectDescriptorDataFromOleObject( + m_lpOleObject, + TEXT("Simple OLE 2.0 Container"), //string to identify source + DVASPECT_CONTENT, + m_pointl, + (LPSIZEL)&m_sizel + ); + if (! pmedium->hGlobal) + sc = E_OUTOFMEMORY; + else + { + pmedium->tymed = TYMED_HGLOBAL; + sc = S_OK; + } + + } + else if ( (pformatetcIn->cfFormat == CF_METAFILEPICT) && + (pformatetcIn->dwAspect == DVASPECT_CONTENT) && + (pformatetcIn->tymed == TYMED_MFPICT) ) + { + + // render CF_METAFILEPICT by drawing the object into a metafile DC + pmedium->hGlobal = OleStdGetMetafilePictFromOleObject( + m_lpOleObject, DVASPECT_CONTENT, NULL, pformatetcIn->ptd); + if (! pmedium->hGlobal) + sc = E_OUTOFMEMORY; + else + { + pmedium->tymed = TYMED_MFPICT; + sc = S_OK; + } + } + else if ( (pformatetcIn->cfFormat == CF_HDROP) && + (pformatetcIn->dwAspect == DVASPECT_CONTENT) && + (pformatetcIn->tymed == TYMED_HGLOBAL) ) + { + // testing for Win3.1 style drag drop. If we offer + // CF_HDROP ( basically, a list of filenames) in a data object + // given to OLE DoDragDrop, then DoDragDrop will translate + // OLE drag drop into Win3.1 drag drop for Win3.1 drop targets + + ULONG cbFile; + char szFile[256]; + DROPFILESTRUCT *pdfs; + char *pfile; + + + cbFile = GetEnvironmentVariable("SystemRoot", szFile, sizeof(szFile)); + + if( cbFile == 0 ) + { + sc = E_FAIL; + goto errRtn; + } + + + cbFile += sizeof("\\setup.txt"); + + strcat(szFile, "\\setup.txt"); + + pmedium->tymed = TYMED_HGLOBAL; + + pmedium->hGlobal = GlobalAlloc( GMEM_DDESHARE, + sizeof(DROPFILESTRUCT) + + cbFile + 3); + + if( pmedium->hGlobal ) + { + pdfs = (DROPFILESTRUCT *)GlobalLock(pmedium->hGlobal); + + if( pdfs ) + { + pdfs->pFiles = sizeof(DROPFILESTRUCT); + pfile = (char *)((BYTE *)pdfs) + sizeof(DROPFILESTRUCT); + pdfs->fNC = FALSE; + pdfs->fWide = FALSE; + pdfs->pt.x = 0; + pdfs->pt.y = 0; + strcpy(pfile, szFile); + // double-NULL terminate it + pfile[strlen(pfile)+2] = '\0'; + + GlobalUnlock(pmedium->hGlobal); + + sc = S_OK; + } + else + { + sc = E_OUTOFMEMORY; + } + } + else + { + sc = E_OUTOFMEMORY; + } + } + +errRtn: + + return ResultFromScode( sc ); +} + +//********************************************************************** +// +// CDataXferObj::GetDataHere +// +// Purpose: +// +// Called to get a data format in a caller supplied location +// +// Parameters: +// +// LPFORMATETC pformatetc - FORMATETC requested +// +// LPSTGMEDIUM pmedium - Medium to return the data +// +// Return Value: +// +// NOERROR - if OleStdGetOleObjectData success +// DATA_E_FORMATETC - We don't support the requested format +// +// Function Calls: +// Function Location +// +// TestDebugOut Windows API +// OleStdGetOleObjectData OLE2UI API +// IOleObject::QueryInterface Object +// +// +//******************************************************************** + +STDMETHODIMP CDataXferObj::GetDataHere ( + LPFORMATETC pformatetc, + LPSTGMEDIUM pmedium +) +{ + SCODE sc = DV_E_FORMATETC; + + TestDebugOut("In CDataXferObj::GetDataHere\r\n"); + + // NOTE: pmedium is an IN parameter. we should NOT set + // pmedium->pUnkForRelease to NULL + + // Check the FORMATETC and fill pmedium if valid. + if ( (pformatetc->cfFormat == g_cfEmbeddedObject) && + (pformatetc->dwAspect == DVASPECT_CONTENT) && + (pformatetc->tymed == TYMED_ISTORAGE) ) + { + LPPERSISTSTORAGE pPersistStorage; + + /* render CF_EMBEDDEDOBJECT by asking the object to save + ** into the IStorage allocated by the caller. + */ + HRESULT hRes; + + if ((hRes=m_lpOleObject->QueryInterface( + IID_IPersistStorage, (LPVOID FAR*)&pPersistStorage)) + != ResultFromScode(S_OK)) + { + return(hRes); + } + assert(pPersistStorage); + HRESULT hrErr = OleStdGetOleObjectData( + pPersistStorage, pformatetc, pmedium,0 /*fUseMemory--N/A*/ ); + pPersistStorage->Release(); + sc = GetScode( hrErr ); + } + return ResultFromScode( sc ); +} |