ldte.cpp

来自「Windows CE 6.0 Word Application 源码」· C++ 代码 · 共 2,381 行 · 第 1/5 页

CPP
2,381
字号
		_pdo = NULL;
	}
}

/*
 *	CLightDTEngine::CanPaste(pdo, cf, flags)
 *
 *	@mfunc
 *		Determines if clipboard format cf is one we can paste.
 *
 *	@rdesc
 *		BOOL - true if we can paste cf into range prg OR DF_CLIENTCONTROL
 *		if the client is going to handle this one.
 *
 *	@devnote
 *		we check the clipboard ourselves if cf is 0. Primarily, this
 *		is for backwards compatibility with Richedit1.0's EM_CANPASTE
 *		message.
 *
 */
DWORD CLightDTEngine::CanPaste(
	IDataObject *pdo,	// @parm Data object to check; if NULL use clipboard
	CLIPFORMAT cf, 		// @parm clipboard format to query about; if 0, use
						//		 best available.
	DWORD flags)		// @parm flags 
{
	TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CLightDTEngine::CanPaste");

	IRichEditOleCallback *precall = _ped->GetRECallback();
	CLIPFORMAT	cf0 = cf;
	DWORD		cFETC = CFETC;
	HRESULT		hr = NOERROR;
	DWORD		ret = FALSE;

#ifndef MACPORT								 
	if( pdo == NULL && precall )
#else
	if( pdo == NULL)
#endif
	{
		// don't worry about errors
		pOleGetClipboard(&pdo);
	}
	else if( pdo )
	{
		// so we can make just one 'Release' call below
		pdo->AddRef();
	}
	
	if( precall && pdo )
	{
		hr = precall->QueryAcceptData(pdo, &cf, flags, 0, NULL);

		if( SUCCEEDED(hr) && (hr != S_OK && hr != DATA_S_SAMEFORMATETC ) )
		{
			ret = DF_CLIENTCONTROL;
			goto Exit;
		}
		else if( FAILED(hr) && hr != E_NOTIMPL )
		{
			goto Exit;
		}
		else if(SUCCEEDED(hr))
		{
			// we should go on and check ourselves unless the client
			// modified the format when it shouldn't have
			if( cf0 && cf0 != cf )
			{
				goto Exit;
			}
		}

		// otherwise, continue with our normal checks
	}

    if (_ped->TxGetReadOnly())		    // Can't paste if read only
		goto Exit;

	while(cFETC--)						// Does cf = format we can paste or
	{									//  is selection left up to us?
		cf0 = g_rgFETC[cFETC].cfFormat;
	    if( cf == cf0 || !cf )
		{
			// either we hit the format requested, or no format
			// was requested.  Now see if the format matches what
			// we could handle in principle.  There are three
			// basic categories:
			//		1. we are rich text and have an OLE callback;
			//		then we can handle pretty much everything.
			//		2. we are rich text but have no OLE callback.
			//		then we can handle anything but OLE specific
			//		formats.
			//		3. we are plain text only.  Then we can only
			//		handle plain text formats.

			if( (_ped->_fRich || (g_rgDOI[cFETC] & DOI_CANPASTEPLAIN)) &&
				(precall || !(g_rgDOI[cFETC] & DOI_CANPASTEOLE)))
			{
				// once we get this far, make sure the data format
				// is actually available.
				if( (pdo && pdo->QueryGetData(&g_rgFETC[cFETC]) == NOERROR ) ||
					(!pdo && IsClipboardFormatAvailable(cf0)) )
				{
					ret = TRUE;			// Return arbitrary non zero value.
					break;
				}
			}
		}
    }	

Exit:
	if( pdo )
	{
		pdo->Release();
	}
	return ret;
}

/*
 *	CLightDTEngine::RangeToDataObject (prg, lStreamFormat, ppdo)
 *
 *	@mfunc
 *		Create data object (with no OLE-formats) for the range prg
 *
 *	@rdesc
 *		HRESULT	= !ppdo ? E_INVALIDARG :
 *				  pdo ? NOERROR : E_OUTOFMEMORY
 */
HRESULT CLightDTEngine::RangeToDataObject(
	CTxtRange *		prg,			// @parm Range to get DataObject for
	LONG			lStreamFormat,	// @parm stream format to use for loading
	IDataObject **	ppdo)			// @parm Out parm for DataObject
{
	TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CLightDTEngine::RangeToDataObject");

	if(!ppdo)
		return E_INVALIDARG;

	CDataTransferObj *pdo = CDataTransferObj::Create(_ped, prg, lStreamFormat);

	*ppdo = pdo;
	return pdo ? NOERROR : E_OUTOFMEMORY;
}

/*
 *	CLightDTEngine::RenderClipboardFormat(wFmt)
 *
 *	@mfunc
 *		Renders current clipboard data object in specified format. (Ole less transfer)
 *
 *	@rdesc
 *		HRESULT
 */
HRESULT CLightDTEngine::RenderClipboardFormat(
	WPARAM wFmt)
{
	HRESULT hr = E_FAIL;

    // GuyBark Jupiter: Added utf8 handling here. The first format that the 
    // RichEdit pasting code tries is UTF8. Given that RichEdit can copy that 
    // ok to the clipboard, handle it here. We used to ignore the request for
    // utf8 here and then accept the next request which was RTF.
	if (_fOleless && (wFmt == cf_RTFUTF8 || wFmt == cf_RTF || wFmt == CF_UNICODETEXT || wFmt == CF_DIB))
	{
		Assert(_pdo);
		STGMEDIUM med;
		DWORD iFETC = iUnicodeFETC;
		if (wFmt == cf_RTF)
			iFETC = iRtfFETC;
		else if (wFmt == cf_RTFUTF8)
			iFETC = iRtfUtf8;
		else if (wFmt == CF_DIB)
			iFETC = iDIB;
		med.tymed = TYMED_HGLOBAL;
		med.pUnkForRelease = NULL;
		med.hGlobal = NULL;
		hr = _pdo->GetData(&g_rgFETC[iFETC], &med);
        if (SUCCEEDED(hr) && ::SetClipboardData(wFmt, med.hGlobal) != NULL)
        {
            hr = S_OK;
        }    
	}
	return hr;		
}

/*
 *	CLightDTEngine::RenderAllClipboardFormats(wFmt)
 *
 *	@mfunc
 *		Renders current clipboard data object (text and RTF). (Ole less transfer)
 *
 *	@rdesc
 *		HRESULT
 */
HRESULT CLightDTEngine::RenderAllClipboardFormats()
{
	HRESULT hr;
	if (_fOleless)
	{
		HWND howner = ::GetClipboardOwner();
		HWND hwnd;
		if (howner &&
			_ped->TxGetWindow(&hwnd) == NOERROR &&
			howner == hwnd &&
			::OpenClipboard(hwnd)
		)
		{
			::EmptyClipboard();
			hr = RenderClipboardFormat(cf_RTF);
			if (SUCCEEDED(hr))
			    hr = RenderClipboardFormat(CF_UNICODETEXT);
			//hr = hr || RenderClipboardFormat(CF_UNICODETEXT);
			if (SUCCEEDED(hr))
                hr = RenderClipboardFormat(CF_DIB);
			//hr = hr || RenderClipboardFormat(CF_DIB);
			::CloseClipboard();
			return hr;
		}
	}
	return S_OK;		// Pretend we did the right thing.
}

/*
 *	CLightDTEngine::DestroyClipboard()
 *
 *	@mfunc
 *		Destroys the clipboard data object
 *
 *	@rdesc
 *		HRESULT
 *
 */
HRESULT CLightDTEngine::DestroyClipboard()
{
	// Nothing to do.  This should work together with our Flush clipboard logic
	return S_OK;
}

/*
 *	CLightDTEngine::HGlobalToRange(dwFormatIndex, hGlobal, ptext, prg, publdr, bDBCString)
 *
 *	@mfunc
 *		Copies the contents of the given string (ptext) to the given range.
 *		The global memory handle may or may not point to the string depending
 *		on the format
 *
 *	@rdesc
 *		HRESULT
 */
HRESULT CLightDTEngine::HGlobalToRange(
	DWORD		dwFormatIndex,
	HGLOBAL		hGlobal,
	LPTSTR		ptext,
	CTxtRange *	prg,
	IUndoBuilder *publdr,
	BOOL		bDBCString)
{
	READHGLOBAL	rhg;
        EDITSTREAM      es;
        BOOL            fSetCur=FALSE;
        HCURSOR         hcur;

	// If RTF, wrap EDITSTREAM around hGlobal & delegate to LoadFromEs()
	if (dwFormatIndex == iRtfNoObjs || dwFormatIndex == iRtfFETC ||
		dwFormatIndex == iRtfUtf8)
	{
		Assert(hGlobal != NULL);
		rhg.ptext		= (LPSTR)ptext;			// Start at beginning
		rhg.cbLeft		= GlobalSize(hGlobal);	//  with full length
		es.dwCookie		= (DWORD)&rhg;			// The read "this" ptr
		es.dwError		= NOERROR;				// No errors yet
        es.pfnCallback  = ReadHGlobal;                  // The read method

		// DBoone: Want wait cursor to display sooner
        if (rhg.cbLeft > 1024) {
			hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
            fSetCur = TRUE;
		}

         LoadFromEs(prg, SFF_SELECTION | SF_RTF, &es, TRUE, publdr);

         if (fSetCur)
			SetCursor(hcur);

		return es.dwError;
	}

	Assert( dwFormatIndex == iRtfAsTextFETC ||
			dwFormatIndex == iAnsiFETC ||
			dwFormatIndex == iUnicodeFETC );


	prg->CleanseAndReplaceRange(-1, ptext, TRUE, publdr);
 	if(prg->_rpTX.IsAfterEOP()) 			// If new text ends
	{										//  with EOP, select
		prg->SetExtend(TRUE);				//  and	delete that
		prg->BackupCRLF();					//  EOP 
		prg->ReplaceRange(0, NULL, publdr, SELRR_REMEMBERRANGE);
	}
	return NOERROR;
}

/* 
 *	CLightDTEngine::DIBToRange(hGlobal, prg, publdr)
 *
 *	@mfunc
 *		Inserts dib data from the clipboard into range in the control
*
 *	@rdesc
 *		HRESULT
 *
 */
HRESULT CLightDTEngine::DIBToRange(HGLOBAL hGlobal,	CTxtRange *prg,	IUndoBuilder *	publdr)
{
	HRESULT         hresult = DV_E_FORMATETC;
	REOBJECT        reobj = { 0 };
	LPBITMAPINFO	pbmi = (LPBITMAPINFO) GlobalLock(hGlobal);
	WCHAR           ch = WCH_EMBEDDING;

	reobj.clsid = CLSID_StaticDib;
	reobj.sizel.cx =
		(LONG) _ped->_pdp->DXtoHimetricX( pbmi->bmiHeader.biWidth );
	reobj.sizel.cy =
		(LONG) _ped->_pdp->DYtoHimetricY( pbmi->bmiHeader.biHeight );
	_ped->GetClientSite(&reobj.polesite);

	COleObject *pobj = (COleObject *)reobj.polesite;
	COleObject::ImageInfo *pimageinfo = new COleObject::ImageInfo;
	if(!pimageinfo)
		{
		hresult = E_OUTOFMEMORY;
		goto leave;
		}

	pobj->SetHdata(hGlobal);
	pimageinfo->xScale = 100;
	pimageinfo->yScale = 100;
	pimageinfo->xExtGoal = reobj.sizel.cx;
	pimageinfo->yExtGoal = reobj.sizel.cy;
	pimageinfo->cBytesPerLine = 0;
	pobj->SetImageInfo(pimageinfo);
	
	if (!reobj.polesite )
	{
		goto leave;
	}

	// Put object into the edit control
	reobj.cbStruct = sizeof(REOBJECT);

    //V-GUYB: 
    // If there is currently a selection, this will get replaced with the
    // WCH_EMBEDDING character. Therefore by the time the object in inserted,
    // it will get inserted at what is currently the start of any selection,
    // NOT the end of it. So reobj.cp MUST be set to cpMin here. Calling 
    // prg->GetCp here can return what is currently end of the selection.
#ifdef NEVER
	reobj.cp = prg->GetCp();
#else
	reobj.cp = prg->GetCpMin();
#endif // NEVER

	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, publdr, SELRR_IGNORE);

	hresult = _ped->GetObjectMgr()->InsertObject(reobj.cp, &reobj, NULL);
leave:
	return hresult;
}

/* 
 *	CLightDTEngine::PasteDataObjectToRange (pdo, prg, cf, rps, pubdlr, dwFlags)
 *
 *	@mfunc
 *		Inserts data from the data object pdo into the range prg. If the
 *		clipboard format cf is not NULL, that format is used; else the highest
 *		priority clipboard format is used.  In either case, any text that
 *		already existed in the range is replaced.  If pdo is NULL, the
 *		clipboard is used.
 *
 *	@rdesc
 *		HRESULT
 *
 */
HRESULT CLightDTEngine::PasteDataObjectToRange(
	IDataObject *	pdo,		// @parm Data object to paste
	CTxtRange *		prg,		// @parm Range into which to paste
	CLIPFORMAT		cf,			// @parm ClipBoard format to paste
	REPASTESPECIAL *rps,		// @parm Special paste info
	IUndoBuilder *	publdr,		// @parm Undo builder to receive antievents
	DWORD			dwFlags)	// @parm DWORD packed flags
{
	TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CLightDTEngine::PasteDataObjectToRange");

	HGLOBAL		hGlobal = NULL;
	HRESULT		hresult = DV_E_FORMATETC;
	HGLOBAL		hUnicode = NULL;
	DWORD		i;
	STGMEDIUM	medium = {0, NULL};
	IDataObject *pdoSave = pdo;
	FORMATETC *	pfetc = g_rgFETC;
	LPTSTR		ptext = NULL;
	LPRICHEDITOLECALLBACK const precall = _ped->GetRECallback();
	BOOL		fThawDisplay = FALSE;
	BOOL		bDBCString = FALSE;	// use in pasting plain text
	DWORD		dwTemp;

	if(!pdo)								// No data object: use clipboard
	{
		hresult = pOleGetClipboard(&pdo);
		if(FAILED(hresult))
		{
			// Ooops.  No Ole clipboard support
			// Need to use direct clipboard access
			HWND howner = ::GetClipboardOwner();
			HWND hwnd;
			if (howner &&
				_ped->TxGetWindow(&hwnd) == NOERROR &&
				howner == hwnd
			)
			{
				// We are cut/pasting within the same richedit instance
				// Use our cached clipboard data object
				pdo = _pdo;
				if (!pdo) {		// Som failure
					_ped->Sound();
					return hresult;
				}
				pdo->AddRef();
			}
			else
			{
				// Oh Oh We need to transfer from clipboard without data object
				// Data must be coming from another window instance
				if (_ped->TxGetWindow(&hwnd) == NOERROR &&
					::OpenClipboard(hwnd)
				)
				{
					DWORD dwFmt = iRtfUtf8;				// Try for UTF8 RTF
					_ped->_pdp->Freeze();

					// GuyBark Jupiter: 
					// Don't check for rtf here if the control is in plain text mode.
					// hGlobal is initialized to NULL above.
#ifdef PWD_JUPITER
					if(_ped->IsRich())
					{
#endif // PWD_JUPITER
					hGlobal = ::GetClipboardData(cf_RTFUTF8);
					if (hGlobal == NULL)				// Wasn't there, so
					{									//  try for RTF
						hGlobal = ::GetClipboardData(cf_RTF);
						dwFmt = iRtfFETC;
					}
#ifdef PWD_JUPITER
					}
#endif // PWD_JUPITER
					if (hGlobal == NULL)				// Wasn't there either
					{									//  so try for plain
						hGlobal = ::GetClipboardData(CF_UNICODETEXT);
						dwFmt = iUnicodeFETC;
					}
					if (hGlobal)
					{
						ptext = (LPTSTR)GlobalLock(hGlobal);
						hresult = HGlobalToRange(dwFmt, hGlobal, ptext, prg, publdr, bDBCString);
					}
					else								// hGlobal == NULL Try for bitmaps
					{
						hGlobal = ::GetClipboardData(CF_DIB);
						if (hGlobal) {

⌨️ 快捷键说明

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