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

📄 range.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	if(!(cchNew | _cch))					// Nothing to add or delete,
		return 0;							//  so we're done

	if( publdr && selaemode != SELRR_IGNORE )
	{
		Assert(selaemode == SELRR_REMEMBERRANGE);
		HandleSelectionAEInfo(GetPed(), publdr, GetCp(), _cch, 
				GetCpMin() + cchNew, 0, SELAE_MERGE);
	}
	
	if(_cch > 0)
		FlipRange();

	// If we are replacing a non-degenerate selection, then the Word95
	// UI specifies that we should use the rightmost formatting at cpMin.

	if( _cch < 0 && _rpCF.IsValid() && !_fDualFontMode && !_fUseiFormat )
	{
		_rpCF.AdjustForward();
		iFormat = _rpCF.GetFormat();

		// This is a bit icky, but the idea is to stabilize the
		// reference count on iFormat.  When we get it above, it's
		// not addref'ed, so if we happen to delete the text in the
		// range and the range is the only one with that format,
		// then the format will go away.

		if(FAILED(GetCharFormatCache(&pcf)))
		{
			AssertSz(0, "couldn't get format cache yet we have formatting");
			return 0;
		}
		pcf->AddRefFormat(iFormat);

		fReleaseFormat = TRUE;
	}
	_fUseiFormat = FALSE;
	
	LONG cchForReplace = -_cch;	
	_cch = 0;
	lRet = CRchTxtPtr::ReplaceRange(cchForReplace, cchNew, pch, publdr, 
				iFormat);
	Update_iFormat(fReleaseFormat ? iFormat : -1);

	if(fReleaseFormat)
	{
		Assert(pcf);
		pcf->ReleaseFormat(iFormat);
	}

	return lRet;
}

/*
 *	CTxtRange::GetCharFormat(pCF, flags)
 *	
 *	@mfunc
 *		Set *pCF = CCharFormat for this range. If cbSize = sizeof(CHARFORMAT)
 *		only transfer CHARFORMAT data.
 *	
 *	@devnote
 *		NINCH means No Input No CHange (a Microsoft Word term). Here used for
 *		properties that change during the range of cch characters.	NINCHed
 *		properties in a Word-Font dialog have grayed boxes. They are indicated
 *		by zero values in their respective dwMask bit positions. Note that
 *		a blank at the end of the range does not participate in the NINCH
 *		test, i.e., it can have a different CCharFormat without zeroing the
 *		corresponding dwMask bits.  This is done to be compatible with Word
 *		(see also CTxtSelection::SetCharFormat when _fWordSelMode is TRUE).
 */
void CTxtRange::GetCharFormat (
	CCharFormat *pCF, 		// @parm CCharFormat to fill with results
	DWORD flags) const		// @parm flags
{
	TRACEBEGIN(TRCSUBSYSRANG, TRCSCOPEINTERN, "CTxtRange::GetCharFormat");
	_TEST_INVARIANT_
	
	CTxtEdit * const ped = GetPed();

	if(!_cch || !_rpCF.IsValid())					// IP or invalid CF
	{												//	run ptr: use CF at
		ped->GetCharFormat(_iFormat)->Get(pCF);		//  this text ptr
		return;
	}

	LONG		  cpMin, cpMost;					// Nondegenerate range:
	LONG		  cch = GetRange(cpMin, cpMost);	//  need to scan
	LONG		  cchChunk;							// cch in CF run
	LONG		  iDirection;						// Direction of scan
	CFormatRunPtr rp(_rpCF);						// Nondegenerate range

	/*
	 * The code below reads character formatting the way Word does it,
	 * that is, by not including the formatting of the last character in the
	 * selection if that character is a blank. 
	 *
	 * See also the corresponding code in CTxtSelection::SetCharFormat().
	 */

	if(cch > 1 && _fSel && (flags & SCF_USEUIRULES))// If more than one char,
	{												//  don't include trailing
		CTxtPtr tp(ped, cpMost - 1);				//  blank in NINCH test
		if(tp.GetChar() == ' ')
		{											// Have trailing blank:
			cch--;									//  one less char to check
			if(_cch > 0)							// Will scan backward, so
				rp.AdvanceCp(-1);					//  backup before blank
		}
	}

	if(_cch < 0)									// Setup direction and
	{												//  initial cchChunk
		iDirection = 1;								// Scan forward
		rp.AdjustForward();
		cchChunk = rp.GetCchLeft();					// Chunk size for _rpCF
	}
	else
	{
		iDirection = -1;							// Scan backward
		rp.AdjustBackward();						// If at BOR, go to
		cchChunk = rp.GetIch();						//  previous EOR
	}

	ped->GetCharFormat(rp.GetFormat())->Get(pCF);	// Initialize *pCF to
													//  starting format
	AssertSz(pCF->dwMask == (pCF->cbSize == sizeof(CHARFORMAT)
			? CFM_ALL : CFM_ALL2),
		"CTxtRange::GetCharFormat: dwMask not initialized");
	while(cchChunk < cch)							// NINCH properties that
	{												//  change over the range
		cch -= cchChunk;							//	given by cch
		if(!rp.ChgRun(iDirection))					// No more runs
			return;									//	(cch too big)
		cchChunk = rp.GetRun(0)->_cch;

		const CCharFormat *pCFTemp = ped->GetCharFormat(rp.GetFormat());

		if (pCFTemp)
		{
    		pCFTemp->Delta(pCF);						// NINCH properties that
		}    
        else
        {
            AssertSz(pCFTemp, "ped->GetCharFormat failed");
        }
													//  changed, i.e., reset
	}												//  corresponding bits
}

/*
 *	CTxtRange::SetCharFormat(pCF, flags, publdr)
 *	
 *	@mfunc
 *		apply CCharFormat *pCF to this range.  If range is an insertion point,
 *		and fApplyToWord is TRUE, then apply CCharFormat to word surrounding
 *		this insertion point
 *	
 *	@rdesc
 *		HRESULT = (successfully set whole range) ? NOERROR : S_FALSE
 *
 *	@devnote
 *		SetParaFormat() is similar, but simpler, since it doesn't have to
 *		special case insertion-point ranges or worry about bullet character
 *		formatting, which is given by EOP formatting.
 */
HRESULT CTxtRange::SetCharFormat (
	const CCharFormat *pCF,	// @parm CCharFormat to fill with results
	DWORD flags,			// @parm APPLYTOWORD or IGNORESELAE
	IUndoBuilder *publdr)	// @parm the undo builder to use.
{
	TRACEBEGIN(TRCSUBSYSRANG, TRCSCOPEINTERN, "CTxtRange::SetCharFormat");

	LONG				cch = -_cch;			// Defaults for _cch <= 0
	LONG				cchBack = 0;			// cch to back up for formatting
	LONG				cchFormat;				// cch for formatting
	CCharFormat			CF;						// Temporary CF
	LONG				cp = 0;					// Used for DEBUG only
	LONG				cpMin, cpMost;
	LONG                cpStart = 0;
	LONG				cpWordMin, cpWordMost;
	LONG				delta;
	BOOL				fApplyToWord = (flags & APPLYTOWORD);
	BOOL				fApplyToEOP = FALSE;
	BOOL				fProtected = FALSE;
	HRESULT				hr = NOERROR;
	LONG				icf;
	CTxtEdit * const	ped = GetPed();			//  defined and not style
	ICharFormatCache *	pf;

 	_TEST_INVARIANT_

	AssertSz(IsValidCharFormat((CHARFORMAT *)pCF),
		"RTR::SetCharFormat(): invalid CCharFormat");

	if (!Check_rpCF() ||
		FAILED(GetCharFormatCache(&pf)))
	{
		return NOERROR;
	}

	if(_cch > 0)								// Active end at range end
	{
		cchBack = -_cch;						// Setup to back up _rpCF to
		cch = _cch;								//  start of format area
	}
	else if (_cch < 0)
    {
        _rpCF.AdjustForward();
    }
	else if(!cch && fApplyToWord )
	{
		FindWord(&cpWordMin, &cpWordMost, FW_EXACT);

		// If nearest word is within this range, calculate cchback and cch
		// so that we can apply the given format to the word
		if( cpWordMin < GetCp() && GetCp() < cpWordMost )
		{
			// RichEdit 1.0 made 1 final check: ensure word's format
			// is constant w.r.t. the format passed in
			CTxtRange rg(*this);

			rg.Set(cpWordMin, cpWordMin - cpWordMost);
			fProtected = rg.WriteAccessDenied();
			if(!fProtected)
			{
				rg.GetCharFormat(&CF);
				if( (CF.dwMask & pCF->dwMask) == pCF->dwMask )
				{
					cchBack = cpWordMin - GetCp();
					cch = cpWordMost - cpWordMin;
				}
			}
		}
		else if(_rpTX.IsAtEOP() && !GetPF()->wNumbering)
		{
			CTxtPtr tp(_rpTX);
			cch = tp.AdvanceCpCRLF();
			_rpCF.AdjustForward();				// Go onto format EOP
			fApplyToEOP = TRUE;
		}
	}
	cchFormat = cch;

	BOOL fFullyDefined = FALSE;					// Default input CF not fully
	BOOL fInOurHost = ped->fInOurHost();		//  defined	

	if (ped->HandleStyle(&CF, pCF) == NOERROR &&
		pf->Cache(&CF, &icf) == NOERROR)
	{
		fFullyDefined = TRUE;
	}

	if(!cch)									// Set degenerate-range	(IP)
	{											//  CF
		if(!fFullyDefined)						// If pCF doesn't specify
		{										//  full CF, fill in undefined
			ped->GetCharFormat(_iFormat)		// Copy current CF at IP to CF
				->Get(&CF);
			hr = CF.Apply(pCF, fInOurHost);		// Apply *pCF
			if(hr != NOERROR)					// Cache result if new
				return hr;
			hr = pf->Cache(&CF, &icf);			// In any case, get icf
			if(hr != NOERROR)
				return hr;
		}
		pf->ReleaseFormat(_iFormat);			//  AddRefFormat() it)
		_iFormat = icf;
		if(fProtected)							// Signal to beep if UI
			hr = S_FALSE;
	}
	else										// Set nondegenerate-range CF
	{											// Get start of affected area
		CNotifyMgr *pnm = ped->GetNotifyMgr();	// Get the notification mgr
		if(pnm)
		{
			cpStart = GetCp() + cchBack;		// Bulletting may move
												//  affected area back if
			if(GetPF()->wNumbering)				//  formatting hits EOP that
			{									//  affects bullet at BOP
				FindParagraph(&cpMin, &cpMost);

				if(cpMost <= GetCpMost())
					cpStart = cpMin;
			}
			pnm->NotifyPreReplaceRange(this,	// Notify interested parties of
				INFINITE, 0, 0, cpStart,		// the impending update
					cpStart + cchFormat);
		}

		_rpCF.AdvanceCp(cchBack);				// Back up to formatting start
		CFormatRunPtr rp(_rpCF);				// Clone _rpCF to walk range

		if( publdr )
		{
			IAntiEvent *pae = gAEDispenser.CreateReplaceFormattingAE(
								ped, rp, cch, pf, CharFormat);
			if( pae )
				publdr->AddAntiEvent(pae);
		}
	
		while(cch > 0 && rp.IsValid())
		{
			if(!fFullyDefined)					// If input CF not fully def'd
			{									//  fill in remaining members
				ped->GetCharFormat(rp.GetFormat())	// Copy rp CF to temp CF
					->Get(&CF);
				hr = CF.Apply(pCF, fInOurHost);	// Apply *pCF
				if(hr != NOERROR)
					return hr;
				hr = pf->Cache(&CF, &icf);		// Cache result if new, In any
				if(hr != NOERROR)				//  cause, use format index icf
					break;							
			}
			delta = rp.SetFormat(icf, cch, pf);	// Set format for this run
			if( delta == -1 )
			{
				ped->GetCallMgr()->SetOutOfMemory();
				break;
			}
			cch -= delta;
		}
		_rpCF.AdjustBackward();					// Expand scope for merging
		rp.AdjustForward();						//  runs

		rp.MergeRuns(_rpCF._iRun, pf);			// Merge adjacent runs that
												//  have the same format
		if(cchBack)								// Move _rpCF back to where it
			_rpCF.AdvanceCp(-cchBack);			//  was
		else									// Active end at range start:
			_rpCF.AdjustForward();				//  don't leave at EOR

		if (pnm)
		{
			pnm->NotifyPostReplaceRange(this, 	// Notify interested parties
				INFINITE, 0, 0, cpStart,		// of the change.
					cpStart + cchFormat - cch);
		}

		if( publdr && !(flags & IGNORESELAE))
		{
			HandleSelectionAEInfo(ped, publdr, GetCp(), _cch, GetCp(), _cch, 
					SELAE_FORCEREPLACE);
		}

		if(!_cch)								// In case IP with ApplyToWord
		{
			if(fApplyToEOP)						// Formatting EOP only
			{
				_rpCF.AdjustForward();			// Get EOP format			
				Set_iCF(_rpCF.GetFormat());		// Use it for IP
			}
			else
				Update_iFormat(-1);				
		}
		ped->GetCallMgr()->SetChangeEvent(CN_GENERIC);
	}
	if(_fSel)
		ped->GetCallMgr()->SetSelectionChanged();
 
	AssertSz(GetCp() == (cp = _rpCF.GetCp()),
		"RTR::SetCharFormat(): incorrect format-run ptr");

	return (hr == NOERROR && cch) ? S_FALSE : hr;
}

/*
 *	CTxtRange::GetParaFormat(pPF)
 *	
 *	@mfunc
 *		return CParaFormat for this text range. If no PF runs are allocated,
 *		then return default CParaFormat
 *	
 *	@devnote
 *		This is very similar to GetCharFormat, but it's not obvious how to
 *		reduce the code size further w/o introducing virtual methods on
 *		CCharFormat and CParaFormat, which inherit from structs.  We don't
 *		want a vtable, since it would increase the storage of format classes
 */
void CTxtRange::GetParaFormat (
	CParaFormat *pPF) const		// @parm ptr to user-supplied CParaFormat to
{								//  be filled with possibly NINCH'd values
	TRACEBEGIN(TRCSUBSYSRANG, TRCSCOPEINTERN, "CTxtRange::GetParaFormat");

	CTxtEdit * const ped = GetPed();

   	_TEST_INVARIANT_

	pPF->dwMask = pPF->cbSize == sizeof(PARAFORMAT2)// Default presence of
			? PFM_ALL2 : PFM_ALL;					//  all properties	

	CFormatRunPtr rp(_rpPF);
	LONG		  cch = -_cch;

	if(cch < 0)										// At end of range:
	{												//  go to start of range
		rp.AdvanceCp(cch);
		cch = -cch;									// Count with cch > 0
	}

	ped->GetParaFormat(rp.GetFormat())->Get(pPF);	// Initialize *pPF to
													//  starting paraformat
	if(!cch || !rp.IsValid())						// No cch or invalid PF
		return;										//	run ptr: use PF at
													//  this text ptr
	LONG cchChunk = rp.GetCchLeft();				// Chunk size for rp
	while(cchChunk < cch)							// NINCH properties that
	{												//  change over the range
		cch -= cchChunk;							//	given by cch
		if(!rp.NextRun())		 					// Go to next run													// No more runs
			break;									//	(cch too big)
		cchChunk = rp.GetCchLeft();
		ped->GetParaFormat(rp.GetFormat())			// NINCH properties that
			->Delta(pPF);							//  changed, i.e., reset
	}												//  corresponding bits
}

/*
 *	CTxtRange::SetParaFormat(pPF, publdr)
 *
 *	@mfunc
 *		apply CParaFormat *pPF to this range.
 *
 *	@rdesc
 *		if successfully set whole range, return NOERROR, otherwise
 *		return error code or S_FALSE.
 */
HRESULT CTxtRange::SetParaFormat (
	const CParaFormat* pPF,		// @parm CParaFormat to apply to this range
	IUndoBuilder *publdr)		// @parm the undo context for this operation
{
	TRACEBEGIN(TRCSUBSYSRANG, TRCSCOPEINTERN, "CTxtRange::SetParaFormat");

	LONG				cch;				// length of text to format
	LONG				cchBack;			// cch to back up for formatting
	LONG				cp = 0;				// Used for DEBUG only
	LONG				cpMin, cpMost;		// limits of text to format
	LONG				delta;
	HRESULT				hr = NOERROR;
	LONG				ipf;				// index to a CParaFormat
	CTxtEdit * const	ped = GetPed();
	CParaFormat			PF;					// Temporary CParaFormat
	IParaFormatCache *	pf;					// ptr to format caches for Cache,
											//  AddRefFormat, ReleaseFormat
											
	AssertSz(IsValidParaFormat((PARAFORMAT *)pPF),
		"RTR::SetParaFormat(): invalid CParaFormat");

 	_TEST_INVARIANT_

	if(!Check_rpPF())
		return E_FAIL;

	if(FAILED(hr = GetParaFormatCache(&pf)))
		return hr;

	FindParagraph(&cpMin, &cpMost);				// Get limits of text to
	cch = cpMost - cpMin;						//  format, namely closest

	CNotifyMgr *pnm = ped->GetNotifyMgr();
	if (pnm)
	{
		pnm->NotifyPreReplaceRange(this,		// Notify interested parties of
			INFINITE, 0, 0, cpMin,	cpMost);	// the impending update
	}

	cchBack = cpMin - GetCp();

	_rpPF.AdvanceCp(cchBack);					// Back up to formatting start
	CFormatRunPtr rp(_rpPF);					// Clone _rpPF to walk range

⌨️ 快捷键说明

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