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

📄 rtfread2.cpp

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

	// Create another object site for the new object
	_ped->GetClientSite(&reobj.polesite) ;
	if (!reobj.polesite )
	{
		goto Cleanup;
	}

	if (FAILED(pOleLoad(reobj.pstg, IID_IOleObject, reobj.polesite,
				(LPVOID *) &reobj.poleobj)))
	{
		goto Cleanup;
	}

	if(!fGotClsid) {
		// we weren't able to obtain a clsid from the progid
		// in the \objclass RTF tag	

		reobj.poleobj->GetUserClassID(&reobj.clsid);
	}
	
	reobj.cbStruct = sizeof(REOBJECT);
	reobj.cp = _prg->GetCp();
	reobj.sizel.cx = HimetricFromTwips(_prtfObject->xExt)
						* _prtfObject->xScale / 100;
	reobj.sizel.cy = HimetricFromTwips(_prtfObject->yExt)
						* _prtfObject->yScale / 100;

	// Read any container flags which may have been previously saved
	if (!ObjectReadSiteFlags(&reobj))
	{
		// If no flags, make best guess
		reobj.dwFlags = REO_RESIZABLE;
	}
	reobj.dvaspect = DVASPECT_CONTENT;		// OLE 1 forces DVASPECT_CONTENT

	// Ask the cache if it knows what to display
	if (SUCCEEDED(reobj.poleobj->QueryInterface(IID_IOleCache, (void**)&polecache)) &&
		SUCCEEDED(polecache->EnumCache(&penumstatdata)))
	{
		// Go look for the best cached presentation CF_METAFILEPICT
		while (penumstatdata->Next(1, &statdata, NULL) == S_OK)
		{
			if (statdata.formatetc.cfFormat == CF_METAFILEPICT)
			{
				LPDATAOBJECT pdataobj = NULL;
				STGMEDIUM med;
				BOOL fUpdate;

				ZeroMemory(&med, sizeof(STGMEDIUM));
                if (SUCCEEDED(polecache->QueryInterface(IID_IDataObject, (void**)&pdataobj)) &&
					SUCCEEDED(pdataobj->GetData(&statdata.formatetc, &med)))
                {
					HANDLE	hGlobal;

					hGlobal = med.hGlobal;

					if( FIsIconMetafilePict(hGlobal) )
				    {
						// BUGBUG: was !OleStdSwitchDisplayAspect(...)
					    OleStdSwitchDisplayAspect(reobj.poleobj, &reobj.dvaspect, 
							  					    DVASPECT_ICON, med.hGlobal,
												    TRUE, FALSE, NULL, &fUpdate);
				    }
				}

				pReleaseStgMedium(&med);
				if (pdataobj)
				{
					pdataobj->Release();
				}
				break;
			}
		}

		polecache->Release();
		penumstatdata->Release();
	}

	// This code is borrowed from RichEdit1.0; Word generates
	// bogus objects, so we need to compensate.

	if( reobj.dvaspect == DVASPECT_CONTENT )
	{
		IStream *pstm = NULL;
		BYTE bT;
		BOOL fUpdate;

		if (SUCCEEDED(reobj.pstg->OpenStream(OLESTR("\3ObjInfo"), 0, STGM_READ |
									   STGM_SHARE_EXCLUSIVE, 0, &pstm)) &&
		   SUCCEEDED(pstm->Read(&bT, sizeof(BYTE), NULL)) &&
		   (bT & 0x40))
		{
		   _fNeedIcon = TRUE;
		   _fNeedPres = TRUE;
		   _pobj = (COleObject *)reobj.polesite;
		   OleStdSwitchDisplayAspect(reobj.poleobj, &reobj.dvaspect, DVASPECT_ICON,
									   NULL, TRUE, FALSE, NULL, &fUpdate);
		}
		if( pstm )
		{
			pstm->Release();
		}
   }

	// Since we are loading an object, it shouldn't be blank
	reobj.dwFlags &= ~REO_BLANK;

	_prg->Set_iCF(-1);	
	_prg->ReplaceRange(1, &ch, NULL, SELRR_IGNORE);  
	hr = ObjectMgr->InsertObject(reobj.cp, &reobj, NULL);

	if (FAILED(hr))
	{
		goto Cleanup;
	}

	// Word doesn't give us objects with presenation
	// caches; as a result, we can't draw them!  In order to get around this,
	// we check to see if there is a presentation cache (via the same way
	// RE1.0 did) using a GetExtent call.  If that fails, we'll just use
	// the presentation stored in the RTF.  
	//
	// COMPATIBILITY ISSUE: RE1.0, instead of using the presenation stored
	// in RTF, would instead call IOleObject::Update.  There are two _big_
	// drawbacks to this approach: 1. it's incredibly expensive (potentially,
	// MANY SECONDS per object), and 2. it doesn't work if the object server
	// is not installed on the machine.

	SIZE sizeltemp;

	if( reobj.poleobj->GetExtent(reobj.dvaspect, &sizeltemp) != NOERROR )
	{
		_fNeedPres = TRUE;
		_pobj = (COleObject *)reobj.polesite;
	}

	fRet = TRUE;

Cleanup:
	if (reobj.pstg)	reobj.pstg->Release();
	if (reobj.polesite) reobj.polesite->Release();
	if (reobj.poleobj) reobj.poleobj->Release();

	return fRet;
}

/*
 *	ObHBuildMetafilePict(prtfobject, hBits)
 *
 *	Purpose:
 *		Build a METAFILEPICT from RTFOBJECT and the raw data.
 *
 *	Arguments:
 *		RTFOBJECT *	The details we picked up from RTF
 *		HGLOBAL		A handle to the raw data
 *
 *	Returns:
 *		HGLOBAL		Handle to a METAFILEPICT
 */
HGLOBAL ObHBuildMetafilePict(RTFOBJECT *prtfobject, HGLOBAL hBits)
{
#ifndef NOMETAFILES
	HGLOBAL hmfp = NULL;
	LPMETAFILEPICT pmfp = NULL;
	SCODE sc = E_OUTOFMEMORY;
	LPBYTE pbBits;
	ULONG cbBits;

	// Allocate the METAFILEPICT structure
    hmfp = GlobalAlloc(GHND, sizeof(METAFILEPICT));
	if (!hmfp)
		goto Cleanup;

	// Lock it down
	pmfp = (LPMETAFILEPICT) GlobalLock(hmfp);
	if (!pmfp)
		goto Cleanup;

	// Put in the header information
	pmfp->mm = prtfobject->sPictureType;
	pmfp->xExt = prtfobject->xExt;
	pmfp->yExt = prtfobject->yExt;

	// Set the metafile bits
	pbBits = (LPBYTE) GlobalLock(hBits);
	cbBits = GlobalSize(hBits);
	pmfp->hMF = SetMetaFileBitsEx(cbBits, pbBits);
	
	// We can throw away the data now since we don't need it anymore
	GlobalUnlock(hBits);
	GlobalFree(hBits);

	if (!pmfp->hMF)
		goto Cleanup;
	GlobalUnlock(hmfp);
	sc = S_OK;

Cleanup:
	if (sc && hmfp)
	{
		if (pmfp)
			GlobalUnlock(hmfp);
		GlobalFree(hmfp);
		hmfp = NULL;
	}
	TRACEERRSZSC("ObHBuildMetafilePict", sc);
	return hmfp;
#else
	return NULL;
#endif
}

/*
 *	ObHBuildBitmap
 *
 *	Purpose:
 *		Build a BITMAP from RTFOBJECT and the raw data
 *
 *	Arguments:
 *		RTFOBJECT *	The details we picked up from RTF
 *		HGLOBAL		A handle to the raw data
 *
 *	Returns:
 *		HGLOBAL		Handle to a BITMAP
 */
HGLOBAL ObHBuildBitmap(RTFOBJECT *prtfobject, HGLOBAL hBits)
{
	HBITMAP hbm = NULL;
	LPVOID	pvBits = GlobalLock(hBits);

	if (!pvBits)
		goto Cleanup;
	hbm = CreateBitmap(prtfobject->xExt, prtfobject->yExt,
						prtfobject->cColorPlanes, prtfobject->cBitsPerPixel,
						pvBits);

Cleanup:
	GlobalUnlock(hBits);
	GlobalFree(hBits);
	return hbm;
}

/*
 *	ObHBuildDib
 *
 *	Purpose:
 *		Build a DIB from RTFOBJECT and the raw data
 *
 *	Arguments:
 *		RTFOBJECT *	The details we picked up from RTF
 *		HGLOBAL		A handle to the raw data
 *
 *	Returns:
 *		HGLOBAL		Handle to a DIB
 */
HGLOBAL ObHBuildDib(RTFOBJECT *prtfobject, HGLOBAL hBits)
{
	// Apparently DIB's are just a binary dump
	return hBits;
}

/*
 *	CRTFRead::StaticObjectReadFromEditstream
 *
 *	Purpose:
 *		Reads an picture from the RTF output stream.
 *
 *	Returns:
 *		BOOL		TRUE on success, FALSE on failure.
 */
#define cbBufferMax	16384
#define cbBufferStep 1024
#define cbBufferMin 1024
BOOL CRTFRead::StaticObjectReadFromEditStream(int cb)
{
	HRESULT hr;
	BOOL fRet = FALSE;
	LPPERSISTSTORAGE pperstg = NULL;
	LPOLECACHE polecache = NULL;
	REOBJECT reobj = { 0 };
	LPSTREAM pstm = NULL;
	LPBYTE pbBuffer = NULL;
	LONG cbRead;
	LONG cbBuffer;
	FORMATETC formatetc;
	STGMEDIUM stgmedium;
	DWORD dwConn;
	HGLOBAL hBits = NULL;
	HGLOBAL (*pfnBuildPict)(RTFOBJECT *, HGLOBAL) = NULL;
	LPRICHEDITOLECALLBACK  precall ;
	DWORD dwAdvf;
	WCHAR 	ch = WCH_EMBEDDING;

	CObjectMgr *ObjectMgr = _ped->GetObjectMgr();

	if (! ObjectMgr)
	   goto Cleanup;
	
	// precall may end up being null (e.g. Windows CE).
	precall = ObjectMgr->GetRECallback();

	// Initialize various data structures
	formatetc.ptd = NULL;
	formatetc.dwAspect = DVASPECT_CONTENT;
	formatetc.lindex = -1;
	switch (_prtfObject->sType)
	{
	case ROT_Metafile:
		reobj.clsid = CLSID_StaticMetafile;
		formatetc.cfFormat = CF_METAFILEPICT;
		formatetc.tymed = TYMED_MFPICT;
		pfnBuildPict = ObHBuildMetafilePict;
		break;

	case ROT_Bitmap:
		reobj.clsid = CLSID_StaticDib;
		formatetc.cfFormat = CF_BITMAP;
		formatetc.tymed = TYMED_GDI;
		pfnBuildPict = ObHBuildBitmap;
		break;

	case ROT_DIB:
		reobj.clsid = CLSID_StaticDib;
		formatetc.cfFormat = CF_DIB;
		formatetc.tymed = TYMED_HGLOBAL;
		pfnBuildPict = ObHBuildDib;
		break;

    default:
        AssertSz(0, "Bad ObjectType in CRTFRead::StaticObjectReadFromEditStream");
        goto Cleanup;
	}

	reobj.sizel.cx = (LONG) HimetricFromTwips(_prtfObject->xExtGoal)
						* _prtfObject->xScale / 100;
	reobj.sizel.cy = (LONG) HimetricFromTwips(_prtfObject->yExtGoal)
						* _prtfObject->yScale / 100;
	stgmedium.tymed = formatetc.tymed;
	stgmedium.pUnkForRelease = NULL;

	if (precall)
	{
		if( !_fNeedPres )
		{
			// Get storage for the object from the application
			if (FAILED(precall->GetNewStorage(&reobj.pstg)))
			{
				goto Cleanup;
			}
		}
		// Let's create a stream on HGLOBAL
		if (FAILED(hr = pCreateStreamOnHGlobal(NULL, FALSE, &pstm)))
		{
			goto Cleanup;
		}
		// Allocate a buffer, preferably a big one
		for (cbBuffer = cbBufferMax;
			 cbBuffer >= cbBufferMin;
			cbBuffer -= cbBufferStep)
		{
			pbBuffer = (unsigned char *)PvAlloc(cbBuffer, 0);
			if (pbBuffer)
				break;
		}
	}
	else
	{
		cbBuffer = cb;
		if (!cb)
		{
			// this means we didn't understand the picture type; so just
			// skip it without failing.
			fRet = TRUE;
			goto Cleanup;
		};

        hBits = GlobalAlloc(GMEM_FIXED, cb);
		pbBuffer = (BYTE *) GlobalLock(hBits);
	}
		
	if (!pbBuffer)
	{
		goto Cleanup;
	}
	
	// Copy the data from RTF into our HGLOBAL

	while ((cbRead = RTFReadOLEStream.lpstbl->Get(&RTFReadOLEStream,pbBuffer,cbBuffer)) > 0)
	{
		if (pstm && (hr = pstm->Write( pbBuffer, cbRead, NULL)))
		{
			TRACEERRSZSC("ObFReadStaticFromEditstream: Write", GetScode(hr));
			goto Cleanup;
		}
	}

	if (hBits)
	{
		Assert(!precall);
		GlobalUnlock(hBits);
		pbBuffer = NULL;		// To avoid free below
	}

	if (pstm && (hr = pGetHGlobalFromStream(pstm, &hBits)))
	{
		TRACEERRSZSC("ObFReadStaticFromEditstream: no hglobal from stm", GetScode(hr));
		goto Cleanup;
	}

	// Build the picture
	if( pfnBuildPict )
	{
		stgmedium.hGlobal = pfnBuildPict(_prtfObject, hBits);
	}
	else
	{
		// this means we didn't understand the picture type; so just
		// skip it without failing.
		fRet = TRUE;
		goto Cleanup;
	}

	if( precall && !stgmedium.hGlobal )
		goto Cleanup;

	if( precall )
	{
		if( !_fNeedPres )
		{
			// Create the default handler
			hr = pOleCreateDefaultHandler(reobj.clsid, NULL, IID_IOleObject,(void **) &reobj.poleobj);
			if (FAILED(hr))
			{
				TRACEERRSZSC("ObFReadStaticFromEditstream: no def handler", GetScode(hr));
				goto Cleanup;
			}

			// Get the IPersistStorage and initialize it
			if ((FAILED(hr = reobj.poleobj->QueryInterface(IID_IPersistStorage,(void **)&pperstg))) ||
				(FAILED(hr = pperstg->InitNew(reobj.pstg))))
			{
				TRACEERRSZSC("ObFReadStaticFromEditstream: InitNew", GetScode(hr));
				goto Cleanup;
			}
			dwAdvf = ADVF_PRIMEFIRST;
		}
		else
		{
			Assert(_pobj);
			_pobj->GetIUnknown()->QueryInterface(IID_IOleObject, (void **)&(reobj.poleobj));
			dwAdvf = ADVF_NODATA;
			formatetc.dwAspect = _fNeedIcon ? DVASPECT_ICON : DVASPECT_CONTENT;
		}

		// Get the IOleCache and put the picture data there
		if (FAILED(hr = reobj.poleobj->QueryInterface(IID_IOleCache,(void **)&polecache)))
		{
			TRACEERRSZSC("ObFReadStaticFromEditstream: QI: IOleCache", GetScode(hr));
			goto Cleanup;
		}

		if (FAILED(hr = polecache->Cache(&formatetc, dwAdvf, &dwConn)))
		{
			TRACEERRSZSC("ObFReadStaticFromEditstream: Cache", GetScode(hr));
			goto Cleanup;
		}

		if (FAILED(hr = polecache->SetData(&formatetc, &stgmedium, TRUE)))
		{
			TRACEERRSZSC("ObFReadStaticFromEditstream: SetData", GetScode(hr));
			goto Cleanup;
		}
	}

	if( !_fNeedPres )
	{
		// Create another object site for the new object
		_ped->GetClientSite(&reobj.polesite) ;
		if (!reobj.polesite )
		{
			goto Cleanup;
		}

		// Set the client site
		if (reobj.poleobj && (hr = reobj.poleobj->SetClientSite(reobj.polesite)))
		{
			TRACEERRSZSC("ObFReadStaticFromEditstream: SetClientSite", GetScode(hr));
			goto Cleanup;
		}
		else if (!reobj.poleobj)
		{
			// Windows CE static object Save the data and mark it.
			COleObject *pobj = (COleObject *)reobj.polesite;
			COleObject::ImageInfo *pimageinfo = new COleObject::ImageInfo;
			pobj->SetHdata(hBits);
			pimageinfo->xScale = _prtfObject->xScale;
			pimageinfo->yScale = _prtfObject->yScale;
			pimageinfo->xExtGoal = _prtfObject->xExtGoal;
			pimageinfo->yExtGoal = _prtfObject->yExtGoal;
			pimageinfo->cBytesPerLine = _prtfObject->cBytesPerLine;
			pobj->SetImageInfo(pimageinfo);
		}

		// Put object into the edit control
		reobj.cbStruct = sizeof(REOBJECT);
		reobj.cp = _prg->GetCp();
		reobj.dvaspect = DVASPECT_CONTENT;
		reobj.dwFlags = REO_RESIZABLE;
		// Since we are loading an object, it shouldn't be blank
		reobj.dwFlags &= ~REO_BLANK;


		_prg->Set_iCF(-1);	
		_prg->ReplaceRange(1, &ch, NULL, SELRR_IGNORE);  
		hr = ObjectMgr->InsertObject(reobj.cp, &reobj, NULL);
		if (FAILED(hr))
		{
			goto Cleanup;
		}
	}
	else
	{
		// the new presentation may have a different idea about how big the
		// object is supposed to be.  Make sure the object stays the correct
		// size.
		_pobj->ResetSizel(reobj.sizel);
	}

	fRet = TRUE;

Cleanup:

    // V-GUYB: 
    // If we failed to stream in the object, then set the oom error here.
    // Note, the above code can fail for other reasons, but oom is most 
    // likely. By setting the error here, the user will see the oom message 
    // and the stream in will be aborted.
    if(!fRet)
    {
        _ped->GetCallMgr()->SetOutOfMemory();
		_ecParseError = ecNoMemory;
    }

	if (polecache) polecache->Release()	;
	if (reobj.pstg)	reobj.pstg->Release();
	if (reobj.polesite) reobj.polesite->Release();
	if (reobj.poleobj) reobj.poleobj->Release();
	if (pperstg) pperstg->Release();
	if (pstm) pstm->Release();
	FreePv(pbBuffer);

	_fNeedIcon = FALSE;
	_fNeedPres = FALSE;
	_pobj = NULL;

	return fRet;
}



⌨️ 快捷键说明

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