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

📄 rtext.cpp

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

		fIsAtBOP = !GetCp() || _rpTX.IsAfterEOP();
		if (!fIsAtBOP && cch == cchOld &&		// Deleting EOP alone before
			!rp.GetIch())						//  new PARAFORMAT run start
		{										//  in para with more than EOP
			cchMove = cchNextEOP;				// Need to move chars up to
			cpFormat += cchMove;				//  end of next para for
		}
		
		cchNextEOP += cchOld;					// Count from GetCp() to EOP
			
		tp.SetCp(GetCp());						// Back to this ptr's _cp
		if(!fIsAtBOP)
			cchPrevEOP = tp.FindEOP(tomBackward);// Get cch to start of para

		// If deleting from within one format run up to or into another, set
		// up to move last para in starting format run into the run following
		// the deleted text
		if(rp.GetFormat() != _rpPF.GetFormat()	// Change of format during  
			&& !fIsAtBOP && !cchMove)			//  deleted text not starting
		{										//  at BOP
			cchMove = cchPrevEOP;				// Get cch to start of para
			cpFormatMin += cchMove;				//  in this ptr's run for
		}										//  moving into rp's run
	}
	
	Assert(cchNew >= 0 && cchOld >= 0);
	if(!(cchNew + cchOld))						// Nothing to do (note: all
		return 0;								//  these cch's are >= 0)

	// Handle pre-replace range notifications.  This method is very
	// useful for delayed rendering of data copied to the clipboard.

	pnm = GetPed()->GetNotifyMgr();
	if( pnm )
	{
		pnm->NotifyPreReplaceRange((ITxNotify *)this, cpSave, cchOld,
			cchNew, cpFormatMin, cpFormat + cchOld);
	}

	if(iFormat >= 0)
		Check_rpCF();

	// Get rid of objects first.  This let's us guarantee that when we
	// insert the objects as part of an undo, the objects themselves are
	// restored _after_ their corresponding WCH_EMBEDDINGs have been
	// added to the backing store.

	if(GetObjectCount())
	{
		pobjmgr = GetPed()->GetObjectMgr();

		if (NULL == pobjmgr)
		{
		    TRACEWARNSZ("GetObjectMgr failed");
		    Assert(pobjmgr);         //if we Got an ObjectCount, how did we not get an ObjectMgr?
		    return 0;  //nothing we can do
	    }
	    

		pobjmgr->ReplaceRange(cpSave, cchOld, publdr);
	}

	if(IsRich() || IsIMERich())				// Rich text enabled
	{
		// The anti-events used below are a bit tricky (paeCF && paePF).
		// Essentially, this call, CRchTxtPtr::ReplaceRange generates one
		// 'combo' anti-event composed of up to two formatting AE's plus
		// the text anti-event.  These anti-events are combined together
		// to prevent ordering problems during undo/redo.
		cpFR = ReplaceRangeFormatting(cchOld + cchEndEOP, cchNew + cchEndEOP, 
			iFormat, publdr, &paeCF, &paePF, cchMove, cchPrevEOP, cchNextEOP);

		if (cchEndEOP)
		{
			// If we added in the EOP we need to back up by the EOP so
			// that the invariants don't get annoyed and the richtext object
			// doesn't get out of sync.
			_rpCF.AdvanceCp(-cchEndEOP);
			_rpPF.AdvanceCp(-cchEndEOP);
		}
				
		if(cpFR < 0)
		{
			Tracef(TRCSEVERR, "ReplaceRangeFormatting(%ld, %ld, %ld) failed", GetCp(), cchOld, cchNew);
			cch = 0;
			goto Exit;
		}
	}

	// As noted above in the call to ReplaceRangeFormatting, the anti-events
	// paeCF and paePF, if non-NULL, were generated by ReplaceRangeFormatting.
	// In order to solve ordering problems, the anti-event generated by this
	// method is actually a combo anti-event of text && formatting AE's.
	cch = _rpTX.ReplaceRange(cchOld, cchNew, pch, publdr, paeCF, paePF);
	if (cch != cchNew)
	{
		Tracef(TRCSEVERR, "_rpTX.ReplaceRange(%ld, %ld, ...) failed", cchOld, cchNew);

#ifndef NODUMPFORMATRUNS
		// Boy, out of memory or something bad.  Dump our formatting and hope
		// for the best.  
		//
		// FUTURE: (alexgo) degrade more gracefully than loosing formatting
		// info.

		// Notify every interested party that they should dump their formatting
		if( pnm )
		{
			pnm->NotifyPreReplaceRange(NULL, CONVERT_TO_PLAIN, 0, 0, 0, 0);
		}

		// Tell document to dump its format runs
		GetPed()->GetTxtStory()->DeleteFormatRuns();
#endif
		goto Exit;
	}

	AssertSz(!_rpPF.IsValid() || _rpPF.GetIch() || !GetCp() || _rpTX.IsAfterEOP(),
		"CRchTxtPtr::ReplaceRange: EOP not at end of PF run");
			
	// BUGBUG!! (alexgo) doesn't handle correctly the case where things fail
	// (due to out of memory or whatever).  See also notes in CTxtPtr::HandleReplaceRange
	// Undo.  The assert below is therefore somewhat bogus, but if it fires, 
	// then our floating ranges are going to be in trouble until we fix
	// up the logic here.

	Assert(cch == cchNew);

Exit:

#ifdef DEBUG
	// test the invariant again before calling out to replace range notification;
	// in this way, we can catch bugs earlier. The invariant has its own
	// scope for convenience.
	if( 1 )
	{
		_TEST_INVARIANT_
	}
#endif

	if( pnm )
	{
		pnm->NotifyPostReplaceRange((ITxNotify *)this, cpSave, cchOld, cch,
			cpFormatMin, cpFormat + cchOld);
	}

	GetPed()->GetCallMgr()->SetChangeEvent(CN_TEXTCHANGED);

	return cch;
}

/*
 *	CRchTxtPtr::InitRunPtrs(cp)
 *
 *	@mfunc
 *		Initialize Run Ptrs of this rich-text ptr to correspond to
 *		document given by ped and to cp given by cp.
 */
void CRchTxtPtr::InitRunPtrs(
	LONG cp)			// @parm character position to move RunPtrs to
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CRchTxtPtr::InitRunPtrs");

	CTxtStory *pStory;

	AssertSz(GetPed(), "RTP::InitRunPtrs: illegal GetPed()");

	if( IsRich() || IsIMERich() )						
	{
		pStory = GetPed()->GetTxtStory();
		if(pStory->_pCFRuns)						//  and there's RichData,
		{											//  initialize format-run ptrs
			_rpCF.SetRunArray((CRunArray *)pStory->_pCFRuns);
			_rpCF.BindToCp(cp);
		}
		if (pStory->_pPFRuns)
		{
			_rpPF.SetRunArray((CRunArray *)pStory->_pPFRuns);
			_rpPF.BindToCp(cp);
		}
	}
 
}

/*
 *	CRchTxtPtr::SetRunPtrs(cp, cpFrom)
 *
 *	@mfunc set Run Ptrs of this rich-text ptr to correspond to cp
 *
 *	@rdesc
 *			TRUE unless cp is outside of doc (in which case RunPtrs are
 *			set to nearest document end).
 */
BOOL CRchTxtPtr::SetRunPtrs(
	LONG cp,				// @parm character position to move RunPtrs to
	LONG cpFrom)			// @parm cp to start with
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CRchTxtPtr::SetRunPtrs");

	BOOL fRet = TRUE;

	if(cpFrom && 2*cp >= cpFrom)
	{
		if (_rpCF.IsValid())
			fRet = _rpCF.AdvanceCp(cp - cpFrom);

		if(_rpPF.IsValid())
			fRet = _rpPF.AdvanceCp(cp - cpFrom);
		return fRet;
	}
		
#ifdef LATER
	if(_rpOB.IsValid())
		fRet = _rpOB.RpSetCp(cp);

	if(_rpRTF.IsValid())
		fRet = _rpRTF.RpSetCp(cp);
#endif

	if(_rpCF.IsValid())
		fRet = _rpCF.BindToCp(cp);

	if(_rpPF.IsValid())
		fRet = _rpPF.BindToCp(cp);

	return fRet;
}

/*
 *	CRchTxtPtr::ReplaceRangeFormatting(cchOld, cchNew, iFormat, publdr,
 *									   ppaeCF, ppaePF, cchMove)
 *	@mfunc
 *		replace character and paragraph formatting at this text pointer
 *		using CCharFormat with index iFormat
 *	
 *	@rdesc
 *		count of new characters added
 *	
 *	@devnote
 *		moves _rpCF and _rpPF to end of replaced text
 *		moves format run arrays
 *		CCharFormat for iFormat is fully configured, i.e., no NINCHes
 */
INLINE LONG CRchTxtPtr::ReplaceRangeFormatting(
	LONG		cchOld,		//@parm length of range to replace
	LONG		cchNew,		//@parm length of replacement text
	LONG		iFormat,	//@parm Char format to use
	IUndoBuilder *publdr,	//@parm UndoBuilder to receive antievents
	IAntiEvent **ppaeCF,	//@parm where to return 'extra' CF anti-events
	IAntiEvent **ppaePF,	//@parm where to return extra PF anti-events
	LONG		cchMove,	//@parm cch to move between PF runs
	LONG		cchPrevEOP,	//@parm cch from _cp back to prev EOP
	LONG		cchNextEOP)	//@parm cch from _cp up to next EOP
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CRchTxtPtr::ReplaceRangeFormatting");

	LONG				cp = GetCp();				
	ICharFormatCache *	pcfc;
	IParaFormatCache *	ppfc;
	DWORD iRunMerge	= 0;

	AssertSz(cchOld >= 0,
		"CRchTxtPtr::ReplaceRangeFormatting: Illegal cchOld");

	if(_rpCF.IsValid())
	{
		iRunMerge = _rpCF._iRun;
		if( iRunMerge > 0 )
		{
			iRunMerge--;
		}

		if(FAILED(GetCharFormatCache(&pcfc)))
			return -1;							// Access to CF caches failed

		if(cchOld > 0)
		{										// add the soon-to-be deleted
			if( publdr )						// formats to the undo list
			{
				*ppaeCF = gAEDispenser.CreateReplaceFormattingAE(
							GetPed(), _rpCF, cchOld, pcfc, CharFormat);
			}
												// Delete/modify CF runs <-->
			_rpCF.Delete(cchOld, pcfc, 0);		//  to cchOld chars
		}
		// If we deleted all of text in story, don't bother adding a new
		// run.	Else insert/modify CF runs corresponding to cchNew chars
		//
		// For IME composition in a plain text control, there is no
		// trailing carriage return and thus need the extra test.
		if(cchNew > 1 || cchNew && ( cchOld < (LONG)GetTextLength()
						|| ( IsIMERich() && cchOld == (LONG)GetTextLength())))
		{
			_rpCF.InsertFormat(cchNew, iFormat, pcfc);
		}
#ifdef DEBUG
 		else if( cchNew > 0 )
		{
			// Make sure that we don't have any format runs; we should
			// be in the new document state.
			Assert(!_rpCF.IsValid());
		}
#endif // DEBUG

		if((cchOld || cchNew) && _rpCF.IsValid())// Deleting all text
		{										//  invalidates _rpCF
			_rpCF.MergeRuns(iRunMerge, pcfc);
			_rpCF.BindToCp(cp + cchNew);
		}
	}

	if(_rpPF.IsValid())
	{
		_rpPF.AdjustForward();					// Be absolutely sure that
												//  PF runs end with EOPs
		iRunMerge = _rpPF._iRun;
		if( iRunMerge > 0 )
		{
			iRunMerge--;
		}

		if(FAILED(GetParaFormatCache(&ppfc)))
			return -1;							// Access to PF caches failed

		if(cchOld)								// Delete cchOld from PF runs
		{										// add the soon-to-be deleted
			if( publdr )						// formats to the undo list
			{
				CFormatRunPtr rp(_rpPF);

				rp.AdvanceCp(cchPrevEOP);
				*ppaePF = gAEDispenser.CreateReplaceFormattingAE(GetPed(),
								rp, cchNextEOP - cchPrevEOP, ppfc, ParaFormat);
			}
		    _rpPF.Delete(cchOld, ppfc, cchMove);
		}

		if(_rpPF.IsValid())						// Deleting all text
		{										//  invalidates _rpPF
			_rpPF.AdjustForward();
			_rpPF.GetRun(0)->_cch += cchNew;	// Insert cchNew into current
			_rpPF._ich	+= cchNew;				//  PF run
			if(cchOld || cchNew)
			{
				_rpPF.MergeRuns(iRunMerge, ppfc);
				_rpPF.BindToCp(cp + cchNew);
			}
		}
	}
	return cchNew;
}

/*
 *	CRchTxtPtr::ExtendFormattingCRLF()
 *	
 *	@mfunc
 *		Use the same CCharFormat and CParaFormat indices for the EOP at
 *		this text ptr as those immediately preceeding it.
 *
 *	@devnote
 *		Leaves this text ptr's format ptrs at run you get from AdjustBackward
 *		since this run ends up including the new text.
 */	
void CRchTxtPtr::ExtendFormattingCRLF()
{
	LONG		  cch = GetTextLength() - GetPed()->GetAdjustedTextLength();
	IFormatCache *pf;
	CNotifyMgr *pnm = GetPed()->GetNotifyMgr();

	GetCharFormatCache((ICharFormatCache **)&pf);
	_rpCF.AdjustFormatting(cch, pf);

	GetParaFormatCache((IParaFormatCache **)&pf);
	_rpPF.AdjustFormatting(cch, pf);

	if( pnm )
	{
		// we assume that Cch is positive (or zero) here
		Assert(cch >= 0);
		pnm->NotifyPostReplaceRange((ITxNotify *)this, INFINITE, 0, 0,
				GetCp(), GetCp() + cch);
	}
}

/*
 *	CRchTxtPtr::IsRich()
 *	
 *	@mfunc
 *		Determine whether rich-text operation is operable
 *	
 *	@rdesc
 *		TRUE if associated CTxtEdit::_fRich = 1, i.e., control is allowed
 *		to be rich.
 */
BOOL CRchTxtPtr::IsRich()
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CRchTxtPtr::IsRich");

	return GetPed()->IsRich();
}

/*
 *	CRchTxtPtr::IsIMERich() const
 *	
 *	@mfunc
 *		This allow CF runs during plain text IME composition.
 *	
 *	@rdesc
 *		TRUE if not IsRich() and IME composition is occuring.
 */
BOOL CRchTxtPtr::IsIMERich() const
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CRchTxtPtr::IsIMERich");
	CTxtEdit *ped;

	ped = GetPed();

	Assert(ped);

	return !ped->_fRich && ped->IsIMEComposition();
}

/*
 *	CRchTxtPtr::Check_rpCF()
 *	
 *	@mfunc
 *		enable _rpCF if it's not already enabled
 *	
 *	@rdesc
 *		TRUE if _rpCF is enabled
 *
 *	FUTURE (murrays)
 *		Combine more of Check_rpCF and Check_rpPF. Maybe define common routine:
 *
 *			BOOL CRchTxtPtr::Check_rp(CFormatPtr& rp, DWORD cbOffset)
 *
 *		called by
 *
 *			Check_rp (_rpCF, offsetof(CTxtStory, _pCFRuns))
 *
 *		Note that cbOffset arg turns into a fast 2-byte constant push on x86
 */

⌨️ 快捷键说明

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