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

📄 range.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
 */
LONG CTxtRange::CheckChange(
	LONG cpSave)		//@parm Original _cp for this range
{
	LONG cchAdj = GetAdjustedTextLength();
	LONG cchSave = _cch;

	if(_fExtend)								// Wants to be nondegenerate
	{											//  and maybe it is
		LONG cp = GetCp();

		_cch = cp - (cpSave - cchSave);
		CheckIfSelHasEOP(cpSave, cchSave);
	}
	else
	{
		_cch = 0;								// Insertion point
		_fSelHasEOP = FALSE;					// Selection doesn't contain
		_fSelHasCell = FALSE;					//  any char, let alone a CR
	}											//  or table cell

	if(!_cch && GetCp() > cchAdj)				// If still IP and active end
		CRchTxtPtr::SetCp(cchAdj);				//  follows nondeletable EOP,
												//  backspace over that EOP
	if(cpSave != GetCp() || cchSave != _cch)
	{
		Update_iFormat(-1);
		if(_fSel)
			GetPed()->GetCallMgr()->SetSelectionChanged();

		_TEST_INVARIANT_
	}

	LONG cch = GetCp() - cpSave;
	_fMoveBack = cch < 0;
	return cch;
}

/*
 *	CTxtRange::CheckIfSelHasEOP(cpSave, cchSave)
 *	
 *	@mfunc
 *		Maintains _fSelHasEOP = TRUE iff selection contains one or more EOPs.
 *		When cpSave = -1, calculates _fSelHasEOP unconditionally and cchSave
 *		is ignored (it's only used for conditional execution). Else _fSelHasEOP
 *		is only calculated for cases that may change it, i.e., it's assumed
 *		be up to date before the change.
 *
 *	@rdesc
 *		TRUE iff _fSel and _cch
 *
 *	@devnote
 *		Call after updating range _cch
 */
BOOL CTxtRange::CheckIfSelHasEOP(
	LONG cpSave,	//@parm Previous active end cp or -1
	LONG cchSave)	//@parm Previous signed length if cpSave != -1
{
	// _fSelHasEOP only maintained for the selection
	if(!_fSel)
		return FALSE;

	if(!_cch)
	{
		_fSelHasEOP  = FALSE;			// Selection doesn't contain
		_fSelHasCell = FALSE;			//  any char, let alone CR
		return FALSE;					
	}

	LONG cpMin, cpMost;					
	GetRange(cpMin, cpMost);

	if(cpSave != -1)					// Selection may have changed
	{									// Set up to bypass text scan if
		LONG cpMinPrev, cpMostPrev;		//  selection grew and _fSelHasEOP
										//  is already TRUE or got smaller
		cpMinPrev = cpMostPrev = cpSave;//  and _fSelHasEOP is FALSE.

		if(cchSave > 0)					// Calculate previous cpMin
			cpMinPrev  -= cchSave;		//  and cpMost
		else
			cpMostPrev -= cchSave;

		// Note: _fSelHasCell shouldn't change while in a table, since
		// Update() should always expand to a cell once _fSelHasCell has
		// been deteted.
		if (!_fSelHasEOP && cpMin >= cpMinPrev && cpMost <= cpMostPrev ||
			 _fSelHasEOP && cpMin <= cpMinPrev && cpMost >= cpMostPrev)
		{		
			return TRUE;				// _fSelHasEOP can't change
		}
	}
	
	LONG	FEOP_Results;
	CTxtPtr tp(_rpTX);					// Scan range for an EOP

	tp.SetCp(cpMin);
	tp.FindEOP(cpMost - cpMin, &FEOP_Results);
	_fSelHasCell = (FEOP_Results & FEOP_CELL) != 0;
	_fSelHasEOP  = (FEOP_Results & FEOP_EOP)  != 0;
	return TRUE;
}

/*
 *	CTxtRange::GetRange(&cpMin, &cpMost)
 *	
 *	@mfunc
 *		set cpMin  = this range cpMin
 *		set cpMost = this range cpMost
 *		return cpMost - cpMin, i.e. abs(_cch)
 *	
 *	@rdesc
 *		abs(_cch)
 */
LONG CTxtRange::GetRange (
	LONG& cpMin,				// @parm Pass-by-ref cpMin
	LONG& cpMost) const			// @parm Pass-by-ref cpMost
{
	TRACEBEGIN(TRCSUBSYSRANG, TRCSCOPEINTERN, "CTxtRange::GetRange");

	LONG cch = _cch;

	if(cch >= 0)
	{
		cpMost	= GetCp();
		cpMin	= cpMost - cch;
	}
	else
	{
		cch		= -cch;
		cpMin	= GetCp();
		cpMost	= cpMin + cch;
	}
	return cch;
}

/*
 *	CTxtRange::GetCpMin()
 *	
 *	@mfunc
 *		return this range's cpMin
 *	
 *	@rdesc
 *		cpMin
 *
 *	@devnote
 *		If you need cpMost and/or cpMost - cpMin, GetRange() is faster
 */
LONG CTxtRange::GetCpMin() const
{
	TRACEBEGIN(TRCSUBSYSRANG, TRCSCOPEINTERN, "CTxtRange::GetCpMin");

	LONG cp = GetCp();
	return min(cp, cp - _cch);
}

/*
 *	CTxtRange::GetCpMost()
 *	
 *	@mfunc
 *		return this range's cpMost
 *	
 *	@rdesc
 *		cpMost
 *
 *	@devnote
 *		If you need cpMin and/or cpMost - cpMin, GetRange() is faster
 */
LONG CTxtRange::GetCpMost() const
{
	TRACEBEGIN(TRCSUBSYSRANG, TRCSCOPEINTERN, "CTxtRange::GetCpMost");

	LONG cp = GetCp();
	return max(cp, cp - _cch);
}

/*
 *	CTxtRange::Update(fScrollIntoView)
 *
 *	@mfunc
 *		Virtual stub routine overruled by CTxtSelection::Update() when this
 *		text range is a text selection.  The purpose is to update the screen
 *		display of the caret or	selection to correspond to changed cp's.
 *
 *	@rdesc
 *		TRUE
 */
BOOL CTxtRange::Update (
	BOOL fScrollIntoView)		//@parm TRUE if should scroll caret into view
{
	TRACEBEGIN(TRCSUBSYSRANG, TRCSCOPEINTERN, "CTxtRange::Update");

	return TRUE;				// Simple range has no selection colors or
}								//  caret, so just return TRUE

/*
 * CTxtRange::SetCp(cp)
 *
 *	@mfunc
 *		Set active end of this range to cp. Leave other end where it is or
 *		collapse range depending on _fExtend (see CheckChange()).
 *
 *	@rdesc
 *		cp at new active end (may differ from cp, since cp may be invalid).
 */
DWORD CTxtRange::SetCp(
	DWORD cp)			// @parm new cp for active end of this range
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtRange::SetCp");

	LONG cpSave = GetCp();

	CRchTxtPtr::SetCp(cp);
	CheckChange(cpSave);					// NB: this changes _cp if after 
	return GetCp();							//  final CR and _cch = 0
}

/*
 *	CTxtRange::Set (cp, cch)
 *	
 *	@mfunc
 *		Set this range's active-end cp and signed cch
 */
BOOL CTxtRange::Set (
	LONG cp,					// @parm Desired active end cp
	LONG cch)					// @parm Desired signed count of chars
{
	TRACEBEGIN(TRCSUBSYSRANG, TRCSCOPEINTERN, "CTxtRange::Set");

	BOOL bRet	 = FALSE;
	LONG cchSave = _cch;			// Save entry _cp, _cch for change check
	LONG cchText = GetAdjustedTextLength();
	LONG cpSave  = GetCp();
	LONG cpOther = cp - cch;		// Desired "other" end

	ValidateCp(cp);							// Be absolutely sure to validate
	ValidateCp(cpOther);					//  both ends

	if(cp == cpOther && cp > cchText)		// IP cannot follow undeletable
		cp = cpOther = cchText;				//  EOP at end of story

	CRchTxtPtr::Advance(cp - GetCp());
	AssertSz(cp == GetCp(),
		"CTxtRange::Set: inconsistent cp");

	_cch = cp - cpOther;					// Validated _cch value
	CheckIfSelHasEOP(cpSave, cchSave);		// Maintain _fSelHasEOP in
											//  outline mode
	if(cpSave != GetCp() || cchSave != _cch)
	{
		if(_fSel)
			GetPed()->GetCallMgr()->SetSelectionChanged();

		Update_iFormat(-1);
		bRet = TRUE;
	}
	 
	_fMoveBack = GetCp() < cpSave;
	_TEST_INVARIANT_
	return bRet;
}

/*
 *	CTxtRange::Advance(cch)
 *
 *	@mfunc
 *		Advance active end of range by cch.
 *		Other end stays put iff _fExtend
 *
 *	@rdesc
 *		cch actually moved
 */
LONG CTxtRange::Advance (
	LONG cch)				// @parm Signed char count to move active end
{
	TRACEBEGIN(TRCSUBSYSRANG, TRCSCOPEINTERN, "CTxtRange::Advance");

	LONG cpSave = GetCp();			// Save entry _cp for CheckChange()
		
	CRchTxtPtr::Advance(cch);
	return CheckChange(cpSave);
}	

/*
 *	CTxtRange::AdvanceCRLF()
 *
 *	@mfunc
 *		Advance active end of range one char, treating CRLF as a single char.
 *		Other end stays put iff _fExtend is nonzero.
 *
 *	@rdesc
 *		cch actually moved
 */
LONG CTxtRange::AdvanceCRLF()
{
	TRACEBEGIN(TRCSUBSYSRANG, TRCSCOPEINTERN, "CTxtRange::AdvanceCRLF");

	LONG cpSave = GetCp();			// Save entry _cp for CheckChange()

	CRchTxtPtr::AdvanceCRLF();
	return CheckChange(cpSave);
}

/*
 *	CTxtRange::BackupCRLF()
 *
 *	@mfunc
 *		Backup active end of range one char, treating CRLF as a single char.
 *		Other end stays put iff _fExtend
 *
 *	@rdesc
 *		cch actually moved
 */
LONG CTxtRange::BackupCRLF()
{
	TRACEBEGIN(TRCSUBSYSRANG, TRCSCOPEINTERN, "CTxtRange::BackupCRLF");

	LONG cpSave = GetCp();			// Save entry _cp for CheckChange()

	CRchTxtPtr::BackupCRLF();
	return CheckChange(cpSave);
}

/*
 *	CTxtRange::FindWordBreak(action)
 *
 *	@mfunc
 *		Move active end as determined by plain-text FindWordBreak().
 *		Other end stays put iff _fExtend
 *
 *	@rdesc
 *		cch actually moved
 */
LONG CTxtRange::FindWordBreak (
	INT action)			// @parm action defined by CTxtPtr::FindWordBreak()
{
	TRACEBEGIN(TRCSUBSYSRANG, TRCSCOPEINTERN, "CTxtPtr::FindWordBreak");

	LONG cpSave = GetCp();			// Save entry _cp for CheckChange()

	CRchTxtPtr::FindWordBreak(action);
	return CheckChange(cpSave);
}

/*
 *	CTxtRange::FlipRange()
 *
 *	@mfunc
 *		Flip active and non active ends
 */
void CTxtRange::FlipRange()
{
	TRACEBEGIN(TRCSUBSYSRANG, TRCSCOPEINTERN, "CTxtRange::FlipRange");

	_TEST_INVARIANT_

	CRchTxtPtr::Advance(-_cch);
	_cch = -_cch;
}
	
/*
 *	CTxtRange::CleanseAndReplaceRange(cch, *pch, fTestLimit, publdr)
 *	
 *	@mfunc
 *		Cleanse the string pch (replace CRLFs by CRs, etc.) and substitute
 *		the resulting string for the text in this range using the CCharFormat
 *		_iFormat and updating other text runs as needed. For single-line
 *		controls, truncate on the first EOP and substitute the truncated
 *		string.  Also truncate if string would overflow the max text length.
 *	
 *	@rdesc
 *		Count of new characters added
 *
 *	@devnote
 *		If we know somehow that pch comes from RichEdit, we shouldn't have to
 *		cleanse it.  This could be tied into delayed IDataObject rendering.
 *		This code is similar to that in CLightDTEngine::ReadPlainText(), but
 *		deals with a single string instead of a series of stream buffers.
 */
LONG CTxtRange::CleanseAndReplaceRange (
	LONG			cch,		// @parm Length of replacement text
	const TCHAR *	pch,		// @parm Replacement text
	BOOL			fTestLimit,	// @parm whether we need to do a limit test
	IUndoBuilder *	publdr)		// @parm UndoBuilder to receive antievents
{
	TRACEBEGIN(TRCSUBSYSRANG, TRCSCOPEINTERN, "CTxtRange::CleanseAndReplaceRange");

	CTxtEdit *	ped = GetPed();
	LONG		cchLen = CalcTextLenNotInRange();
	DWORD		cchMax = ped->TxGetMaxLength();
	LONG		cchT;
	CTempWcharBuf twcb;
	TCHAR *		pchT;

	if(!pch)									// No text so no cleansing
		cch = 0;

	else if(!ped->TxGetMultiLine())				// Single-line control
	{
		if(cch < 0)								// Calculate string length
			cch = tomForward;					//  while looking for EOP
												// Truncate at 1st EOP to be
		for(cchT = 0; cchT < cch &&				//  compatible with RE 1.0
			*pch && !IsASCIIEOP(*pch);			//  and user's SLE and to
			cchT++, pch++)						//  give consistent display
			;									//  behavior
		cch = cchT;
		pch -= cchT;							// Restore pch
	}
	else										// Multiline control
	{
		if(cch < 0)								// Calculate length
			cch = wcslen(pch);

		if(!GetPed()->Get10Mode() && cch)		// Cleanse if not RE 1.0
		{										//  and some new chars
			pchT = twcb.GetBuf(cch);

			if (NULL == pchT)
			{
				// Could not allocate buffer so give up with no update.
				return 0;
			}

			cch = Cleanse(pchT, pch, cch);
			pch = pchT;
		}
	}
	if(fTestLimit && cch && (DWORD)(cch + cchLen) > cchMax)	// New plus old	count exceeds
	{											//  max allowed, so truncate
		cch = cchMax - cchLen;					//  down to what fits
		cch = max(cch, 0);						// Keep it positive
		ped->GetCallMgr()->SetMaxText();		// Tell anyone who cares
	}

	LONG cchUpdate = ReplaceRange(cch, pch, publdr, SELRR_REMEMBERRANGE);

	return cchUpdate;
}

/*
 *	CTxtRange::ReplaceRange(cchNew, *pch, publdr. selaemode)
 *	
 *	@mfunc
 *		Replace the text in this range by pch using CCharFormat _iFormat
 *		and updating other text runs as needed.
 *	
 *	@rdesc
 *		Count of new characters added
 *	
 *	@devnote
 *		moves this text pointer to end of replaced text and
 *		may move text block and formatting arrays
 */
LONG CTxtRange::ReplaceRange (
	LONG			cchNew,		// @parm Length of replacement text
	TCHAR const *	pch,		// @parm Replacement text
	IUndoBuilder *	publdr,		// @parm UndoBuilder to receive antievents
	SELRR			selaemode)	// @parm Controls how selection antievents
								// are to be generated.
{
	TRACEBEGIN(TRCSUBSYSRANG, TRCSCOPEINTERN, "CTxtRange::ReplaceRange");

	LONG lRet;
	LONG iFormat = _iFormat;
	BOOL fReleaseFormat = FALSE;
	ICharFormatCache * pcf;

	_TEST_INVARIANT_

⌨️ 快捷键说明

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