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

📄 dxfrobj.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:

	if(IsZombie())							// Check for range zombie
		return CO_E_RELEASED;

	CLIPFORMAT	cf = pformatetcIn->cfFormat;
	HRESULT		hr = DV_E_FORMATETC;

	if( (cf == cf_EMBEDDEDOBJECT ||
		 cf == cf_EMBEDSOURCE) &&
		(pformatetcIn->tymed & TYMED_ISTORAGE))
	{
        _pObjStg = GetDataForEmbeddedObject( _pOleObj, pmedium->pstg );
		pmedium->tymed = TYMED_ISTORAGE;
		hr = _pObjStg != NULL ? NOERROR : hr;
		return hr;
	}

	if( cf == cf_OBJECTDESCRIPTOR &&
			 (pformatetcIn->tymed & TYMED_HGLOBAL) &&
			 _hObjDesc)
	{
		pmedium->hGlobal = DuplicateHGlobal(_hObjDesc);
		pmedium->tymed = TYMED_HGLOBAL;
		return NOERROR;
	}

	if( cf == CF_METAFILEPICT )
	{
		pmedium->hMetaFilePict = pOleDuplicateData(_hMFPict, CF_METAFILEPICT, 0);
		pmedium->tymed = TYMED_MFPICT;
		return NOERROR;
	}

	if( cf == CF_DIB )
	{
		if( _ped->HasObjects() && _cch == 1 )
		{
			COleObject *pobj = _ped->_pobjmgr->GetObjectFromCp(_cpMin);
			if (pobj)
			{
				HGLOBAL hdib = pobj->GetHdata();
				if (hdib)
				{
					pmedium->hGlobal = DuplicateHGlobal(hdib);
					pmedium->tymed = TYMED_HGLOBAL;
				}
			}
		}
		return NOERROR;
	}

	// now handle 'native' richedit formats.

	if( cf && pformatetcIn->tymed & TYMED_HGLOBAL )
	{
		if( cf == CF_UNICODETEXT )
			pmedium->hGlobal = DuplicateHGlobal(TextToHglobal(_hPlainText, tPlain));

		else if(cf == CF_TEXT)
			pmedium->hGlobal = TextHGlobalWtoA(TextToHglobal(_hPlainText, tPlain));

		else if(cf == cf_RTF || cf == cf_RTFASTEXT || cf == cf_RTFNOOBJS)
			pmedium->hGlobal = DuplicateHGlobal(TextToHglobal(_hRtfText, tRtf));

		else if(cf == cf_RTFUTF8)
			pmedium->hGlobal = DuplicateHGlobal(TextToHglobal(_hRtfUtf8, tRtfUtf8));

		else
			return DV_E_FORMATETC;

		hr = E_OUTOFMEMORY;							// Default not enuf RAM
		if( pmedium->hGlobal )						// Succeeded
		{
			pmedium->tymed	 = TYMED_HGLOBAL;
			hr = NOERROR;
		}
	}

	return hr;
}

/*
 *	CDataTransferObj::GetDataForEmbeddedObject (pformatetc, lpstgdest)
 *
 *	@mfunc
 *		retrieves data for embedded object
 *
 *	@rdesc
 *		LPSTORAGE
 *
 */
LPSTORAGE CDataTransferObj::GetDataForEmbeddedObject(
	LPOLEOBJECT	 pOleObj,
	LPSTORAGE	 lpstgdest)
{
	TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CDataTransferObj::GetDataForEmbeddedObject");
	
	HRESULT			 hr, hr1;
	LPPERSISTSTORAGE pperstg;

	if (_pObjStg != NULL && lpstgdest != NULL)
	{
		// We saved the data previously. Copy it to destination.
		hr = _pObjStg->CopyTo(0, NULL, NULL, lpstgdest);
		if (hr == NOERROR)
		{
			lpstgdest->Commit(STGC_DEFAULT);
			return _pObjStg;
		}
		return NULL;
	}

	if (_pObjStg != NULL && lpstgdest == NULL)
	{
		// We saved the data previously.  Return a reference
		_pObjStg->AddRef();
		return _pObjStg;
	}

	// We don't have a saved copy.  Create One.
	hr = pOleObj->QueryInterface( IID_IPersistStorage, (void **) &pperstg );
	if (hr != NOERROR)
	{
		return NULL;
	}

	if (lpstgdest == NULL)
	{
		// It is null.  We have to create our own.
		LPLOCKBYTES lpLockBytes = NULL;
		hr = pCreateILockBytesOnHGlobal(NULL, TRUE, // delete on release
									   (LPLOCKBYTES *)&lpLockBytes);
		if (hr != NOERROR)
		{
			pperstg->Release();
			return NULL;
		}
		hr = pStgCreateDocfileOnILockBytes(
			lpLockBytes,
			STGM_READWRITE | STGM_TRANSACTED | STGM_SHARE_EXCLUSIVE | STGM_CREATE,
			0,	// reserved
			&lpstgdest
		);
		lpLockBytes->Release();
		if (hr != NOERROR)
		{
			pperstg->Release();
			return NULL;
		}
		_pObjStg = lpstgdest;
	}
	else
	{
		// Force the data to be saved
		_pObjStg = GetDataForEmbeddedObject( _pOleObj, NULL );
		pperstg->Release();
		return GetDataForEmbeddedObject( _pOleObj, lpstgdest );
	}

    // OLE2NOTE: even if OleSave returns an error you should still call 
    // SaveCompleted.
    hr = pOleSave( pperstg, lpstgdest, FALSE /* fSameAsLoad */ );
 	hr1 = pperstg->SaveCompleted(NULL);
	if (hr != NOERROR || hr1 != NOERROR)			// Should we use SUCCEED macros ????
	{
		lpstgdest = NULL;
    }
	pperstg->Release();
	return _pObjStg;
}

/*
 *	CDataTransferObj::GetDataorObjectDescriptor (pformatetc, pmedium)
 *
 *	@mfunc
 *		retrieves data for embedded object descriptor
 *
 *	@rdesc
 *		HRESULT
 *
 */
HGLOBAL CDataTransferObj::GetDataForObjectDescriptor(
	LPOLEOBJECT	 pOleObj,
	DWORD		 dwAspect
)
{
	TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CDataTransferObj::GetDataForObjectDescriptor");

	POINTL ptl = {0};
	SIZEL sizel = {0};

	if (_hObjDesc == NULL)
	{
		_hObjDesc = OleGetObjectDescriptorDataFromOleObject(
			pOleObj,
			dwAspect,
			ptl,
			&sizel
		);
	}

	return _hObjDesc;
}

/*
 *	CDataTransferObj::GetDataHere (pformatetc, pmedium)
 *
 *	@mfunc
 *		retrieves data of the specified format into the given medium
 *
 *	@rdesc
 *		HRESULT = E_NOTIMPL
 *
 *	@devnote (alexgo): technically, we're supposed to support transfers
 *		into hglobals, but I'd rather not at the moment.
 */
STDMETHODIMP CDataTransferObj::GetDataHere(
	FORMATETC *pformatetc, 
	STGMEDIUM *pmedium)
{
	TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CDataTransferObj::GetDataHere");

	CLIPFORMAT	cf = pformatetc->cfFormat;
	HRESULT		hr = DV_E_FORMATETC;

	if(IsZombie())							// Check for range zombie
		return CO_E_RELEASED;

	if( (cf == cf_EMBEDDEDOBJECT ||
		 cf == cf_EMBEDSOURCE) &&
		(pformatetc->tymed & TYMED_ISTORAGE))
	{
		// For some reason the NT4.0 and Win95 Shell
		//          ask for the EMBEDSOURCE format.
        _pObjStg = GetDataForEmbeddedObject( _pOleObj, pmedium->pstg );
		pmedium->tymed = TYMED_ISTORAGE;
		hr = pmedium->pstg != NULL ? NOERROR : hr;
		return hr;
	}

	if( cf == cf_OBJECTDESCRIPTOR &&
			 (pformatetc->tymed & TYMED_HGLOBAL) &&
			 _hObjDesc)
	{
		pmedium->hGlobal = DuplicateHGlobal(_hObjDesc);
		pmedium->tymed = TYMED_HGLOBAL;
		return NOERROR;
	}

	return E_NOTIMPL;
}

/*
 *	CDataTransferObj::QueryGetData (pformatetc)
 *
 *	@mfunc
 *		Queries whether the given format is available in this data object
 *
 *	@rdesc
 *		HRESULT
 */
STDMETHODIMP CDataTransferObj::QueryGetData(
	FORMATETC *pformatetc )		// @parm FETC to look for
{
	TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CDataTransferObj::QueryGetData");

	if(IsZombie())							// Check for range zombie
		return CO_E_RELEASED;

	DWORD	cFETC = _cTotal;

	while (cFETC--)				// Maybe faster to search from start
	{
		if( pformatetc->cfFormat == _prgFormats[cFETC].cfFormat && 
			(pformatetc->tymed & _prgFormats[cFETC].tymed) )
		{
			return NOERROR;
		}
	}

	return DV_E_FORMATETC;
}

/*
 *	CDataTransferObj::SetData (pformatetc, pmedium, fRelease)
 *
 *	@mfunc
 *		allows data to be set into this data object
 *
 *	@rdesc
 *		HRESULT = E_FAIL
 *
 *	@devnote
 *		as we are a data transfer object with a "snapshot" of data,
 *		we do not allow it to be replaced
 */
STDMETHODIMP CDataTransferObj::SetData(
	FORMATETC *pformatetc,
	STGMEDIUM *pmedium,
	BOOL fRelease)
{
	TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CDataTransferObj::SetData");

	return E_FAIL;
}


/*
 *	CDataTransferObj::OnPreReplaceRange
 *
 *	@mfunc	implementation of ITxNotify::OnPreReplaceRange
 *			called before changes are made to the backing store
 *
 *	@rdesc		void
 */
void CDataTransferObj::OnPreReplaceRange(
	DWORD cp, 			//@parm cp of the changes
	DWORD cchDel,		//@parm #of chars deleted
	DWORD cchNew,		//@parm # of chars added
	DWORD cpFormatMin, 	//@parm min cp of formatting changes
	DWORD cpFormatMax)	//@parm max cp of formatting changes
{
	TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CDataTransferObj::OnPreReplaceRange");

	if (CONVERT_TO_PLAIN != cp && INFINITE != cp)
	{
		if ((LONG) cp > _cpMin + _cch)
		{
			// Change beyond our extent
			return;
		}

		if ((LONG) (cp + cchDel) < _cpMin)
		{
			// Change before our extent
			_cpMin += (cchNew - cchDel);
			return;
		}
	}

	// FUTURE (murrays): save only one master format (UTF8 RTF or better
	// CTxtStory) and generate individual ones in GetData and GetDataHere.
	_hPlainText = TextToHglobal(_hPlainText, tPlain);
	_hRtfText	= TextToHglobal(_hRtfText,	 tRtf);
	_hRtfUtf8	= TextToHglobal(_hRtfUtf8,	 tRtfUtf8);
}

/*
 *	CDataTransferObj::OnPostReplaceRange
 *
 *	@mfunc	implementation of ITxNotify::OnPostReplaceRange
 *			called after changes are made to the backing store
 *
 *	@rdesc	void
 *	
 *	@comm	we use this method to keep our cp's up-to-date
 */
void CDataTransferObj::OnPostReplaceRange(
	DWORD cp, 			//@parm cp of the changes
	DWORD cchDel,		//@parm #of chars deleted
	DWORD cchNew,		//@parm # of chars added
	DWORD cpFormatMin, 	//@parm min cp of formatting changes
	DWORD cpFormatMax)	//@parm max cp of formatting changes
{
	TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CDataTransferObj::OnPostReplaceRange");

	// Nothing to do
	return;
}

/*
 *	CDataTransferObj::Zombie ()
 *
 *	@mfunc
 *		Turn this object into a zombie
 */
void CDataTransferObj::Zombie ()
{
	TRACEBEGIN(TRCSUBSYSOLE, TRCSCOPEEXTERN, "CDataTransferObj::Zombie");

	_ped = NULL;
}

/*
 *	CDataTransferObj::Create(ped)
 *
 *	@mfunc
 *		static function to create CDataTransferObj. Used to force users
 *		not to create this object on the stack, which would break OLE's
 *		liveness rules.
 *
 *	@rdesc
 *		new CDataTransferObj *
 */
CDataTransferObj *CDataTransferObj::Create(
	CTxtEdit *ped,			// @parm ped to which this DataObject belongs
	CTxtRange *prg,			// @parm range for the data object
	LONG lStreamFormat)		// @parm stream format to use in Rtf conversion
{
	TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CDataTransferObj::Create");

	Assert(CFETC == ARRAY_SIZE(g_rgFETC) && CFETC == ARRAY_SIZE(g_rgDOI));

	LONG ch;
	CNotifyMgr *pnm;

	CDataTransferObj *pdo = new CDataTransferObj(ped);

	if( !pdo )
	{
		ped->GetCallMgr()->SetOutOfMemory();
		return NULL;
	}

	pdo->_hPlainText = NULL;
	pdo->_hRtfText = NULL;
	pdo->_hRtfUtf8 = NULL;
	pdo->_pOleObj = NULL;
	pdo->_hObjDesc = NULL;
	pdo->_pObjStg = NULL;
	pdo->_hMFPict = NULL;
	
	pdo->_cch = abs(prg->GetCch());
	pdo->_cpMin = prg->GetCpMin();

	pdo->_lStreamFormat = lStreamFormat;

	pnm = ped->GetNotifyMgr();
	if( pnm )
	{
		pnm->Add( (ITxNotify *) pdo );
	}

	//Set the object count.
	pdo->_cObjs = 0;
	if( ped->HasObjects() )
	{
		pdo->_cObjs = ped->_pobjmgr->CountObjectsInRange(prg->GetCpMin(),
			prg->GetCpMost());
	}

	pdo->_cTotal = ped->IsRich() ? 6 : 2;
	pdo->_prgFormats = new FORMATETC[pdo->_cTotal];
	if( !pdo->_prgFormats )
	{
		pdo->_cTotal = 0;
		pdo->Release();
		ped->GetCallMgr()->SetOutOfMemory();

⌨️ 快捷键说明

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