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

📄 range.cpp

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

	BOOL	bRet = FALSE;					// Default no object
	LONG	cpMin, cpMost;
	CTxtPtr tp(_rpTX);

	GetRange(cpMin, cpMost);
	if(pcpMin)
	{
		tp.SetCp(cpMin);
		if(tp.GetChar() != WCH_EMBEDDING)
		{
			cpMin = tp.FindExact(tomBackward, szEmbedding);
			if(cpMin >= 0)
			{
				bRet = TRUE;
				*pcpMin = cpMin;
			}
		}
	}
	if(pcpMost)
	{
		tp.SetCp(cpMost);
		if (tp.PrevChar() != WCH_EMBEDDING &&
			tp.FindExact(tomForward, szEmbedding) >= 0)
		{
			bRet = TRUE;
			*pcpMost = tp.GetCp();
		}
	}
	return bRet;
}

/*
 *	CTxtRange::FindCell(pcpMin, pcpMost)
 *	
 *	@mfunc
 *		Set *pcpMin  = closest cell cpMin  <lt>= range cpMin (see comment)
 *		Set *pcpMost = closest cell cpMost <gt>= range cpMost
 *	
 *	@comment
 *		This function does nothing if the range isn't completely in a table.
 */
void CTxtRange::FindCell (
	LONG *pcpMin,			// @parm Out parm for bounding-cell cpMin
	LONG *pcpMost) const	// @parm Out parm for bounding-cell cpMost
{
	TRACEBEGIN(TRCSUBSYSRANG, TRCSCOPEINTERN, "CTxtRange::FindCell");

	WCHAR		ch;
	LONG		cpMin, cpMost;
	CRchTxtPtr	rtp(*this);

	_TEST_INVARIANT_

	GetRange(cpMin, cpMost);

	if(pcpMin)
	{
		if(_cch > 0)
			rtp.Advance(-_cch);

		rtp._rpPF.AdjustBackward();
		if(rtp.GetPF()->wEffects & PFE_TABLE)
		{
			while(rtp.GetCp())
			{
				rtp.BackupCRLF();
				ch = rtp.GetChar();
				if(ch == CR || ch == CELL)
				{
					rtp.AdvanceCRLF();
					break;
				}
				Assert(rtp.GetPF()->wEffects & PFE_TABLE);
			}
		}
		*pcpMin = rtp.GetCp();
	}

	if(pcpMost)
	{
		rtp.SetCp(cpMost);
		if(rtp.GetPF()->wEffects & PFE_TABLE)
		{
			rtp.BackupCRLF();
			do
			{
				ch = rtp.GetChar();
				rtp.AdvanceCRLF();
				Assert(rtp.GetPF()->wEffects & PFE_TABLE);
			} while(ch && ch != CR && ch != CELL);
		}
		*pcpMost = rtp.GetCp();
	}
}

/*
 *	CTxtRange::FindParagraph(pcpMin, pcpMost)
 *	
 *	@mfunc
 *		Set *pcpMin  = closest paragraph cpMin  <lt>= range cpMin (see comment)
 *		Set *pcpMost = closest paragraph cpMost <gt>= range cpMost
 *	
 *	@devnote
 *		If this range's cpMost follows an EOP, use it for bounding-paragraph
 *		cpMost unless 1) the range is an insertion point, and 2) pcpMin and
 *		pcpMost are both nonzero, in which case use the next EOP.  Both out
 *		parameters are nonzero if FindParagraph() is used to expand to full
 *		paragraphs (else StartOf or EndOf is all that's requested).  This
 *		behavior is consistent with the selection/IP UI.  Note that FindEOP
 *		treats the beginning/end of document (BOD/EOD) as a BOP/EOP,
 *		respectively, but IsAfterEOP() does not.
 */
void CTxtRange::FindParagraph (
	LONG *pcpMin,			// @parm Out parm for bounding-paragraph cpMin
	LONG *pcpMost) const	// @parm Out parm for bounding-paragraph cpMost
{
	TRACEBEGIN(TRCSUBSYSRANG, TRCSCOPEINTERN, "CTxtRange::FindParagraph");

	LONG	cpMin, cpMost;
	CTxtPtr	tp(_rpTX);

	_TEST_INVARIANT_

	GetRange(cpMin, cpMost);
	if(pcpMin)
	{
		tp.SetCp(cpMin);					// tp points at this range's cpMin
		if(!tp.IsAfterEOP())				// Unless tp directly follows an
			tp.FindEOP(tomBackward);		//  EOP, search backward for EOP
		*pcpMin = cpMin = tp.GetCp();
	}

	if(pcpMost)
	{
		tp.SetCp(cpMost);					// If range cpMost doesn't follow
		if (!tp.IsAfterEOP() ||				//  an EOP or else if expanding
			(!cpMost || pcpMin) &&
			 cpMin == cpMost)				//  IP at paragraph beginning,
		{
			tp.FindEOP(tomForward);			//  search for next EOP
		}
		*pcpMost = tp.GetCp();
	}
}

/*
 *	CTxtRange::FindSentence(pcpMin, pcpMost)
 *	
 *	@mfunc
 *		Set *pcpMin  = closest sentence cpMin  <lt>= range cpMin
 *		Set *pcpMost = closest sentence cpMost <gt>= range cpMost
 *	
 *	@devnote
 *		If this range's cpMost follows a sentence end, use it for bounding-
 *		sentence cpMost unless the range is an insertion point, in which case
 *		use the	next sentence end.  The routine takes care of aligning on
 *		sentence beginnings in the case of range ends that fall on whitespace
 *		in between sentences.
 */
void CTxtRange::FindSentence (
	LONG *pcpMin,			// @parm Out parm for bounding-sentence cpMin
	LONG *pcpMost) const	// @parm Out parm for bounding-sentence cpMost
{
	TRACEBEGIN(TRCSUBSYSRANG, TRCSCOPEINTERN, "CTxtRange::FindSentence");

	LONG	cpMin, cpMost;
	CTxtPtr	tp(_rpTX);

	_TEST_INVARIANT_

	GetRange(cpMin, cpMost);
	if(pcpMin)								// Find sentence beginning
	{
		tp.SetCp(cpMin);					// tp points at this range's cpMin
		if(!tp.IsAtBOSentence())			// If not at beginning of sentence
			tp.FindBOSentence(tomBackward);	//  search backward for one
		*pcpMin = cpMin = tp.GetCp();
	}

	if(pcpMost)								// Find sentence end
	{										// Point tp at this range's cpLim
		tp.SetCp(cpMost);					// If cpMost isn't at sentence
		if (!tp.IsAtBOSentence() ||			//  beginning or if at story
			(!cpMost || pcpMin) &&			//  beginning or expanding
			 cpMin == cpMost)				//  IP at sentence beginning,
		{									//  find next sentence beginning
			if(!tp.FindBOSentence(tomForward))
				tp.SetCp(GetTextLength());	// End of story counts as 
		}									//  sentence end too
		*pcpMost = tp.GetCp();
	}
}

/*
 *	CTxtRange::FindVisibleRange(pcpMin, pcpMost)
 *	
 *	@mfunc
 *		Set *pcpMin  = _pdp->_cpFirstVisible
 *		Set *pcpMost = _pdp->_cpLastVisible
 *	
 *	@rdesc
 *		TRUE iff calculated cp's differ from this range's cp's
 *	
 *	@devnote
 *		CDisplay::GetFirstVisible() and GetCliVisible() return the first cp
 *		on the first visible line and the last cp on the last visible line.
 *		These won't be visible if they are scrolled off the screen.
 *		FUTURE: A more general algorithm would CpFromPoint (0,0) and
 *		(right, bottom).
 */
BOOL CTxtRange::FindVisibleRange (
	LONG *pcpMin,			// @parm Out parm for cpFirstVisible
	LONG *pcpMost) const	// @parm Out parm for cpLastVisible
{
	TRACEBEGIN(TRCSUBSYSRANG, TRCSCOPEINTERN, "CTxtRange::FindVisibleRange");

	_TEST_INVARIANT_

	CDisplay *	pdp = GetPed()->_pdp;

	if(!pdp)
		return FALSE;

	if(pcpMin)
		*pcpMin = pdp->GetFirstVisibleCp();

	pdp->GetCliVisible(pcpMost);

	return TRUE;
}

/*
 *	CTxtRange::FindWord(pcpMin, pcpMost, type)
 *	
 *	@mfunc
 *		Set *pcpMin  = closest word cpMin  <lt>= range cpMin
 *		Set *pcpMost = closest word cpMost <gt>= range cpMost
 *
 *	@comm
 *		There are two interesting cases for finding a word.  The first,
 *		(FW_EXACT) finds the exact word, with no extraneous characters.
 *		This is useful for situations like applying formatting to a
 *		word.  The second case, FW_INCLUDE_TRAILING_WHITESPACE does the
 *		obvious thing, namely includes the whitespace up to the next word.
 *		This is useful for the selection double-click semantics and TOM.
 */
void CTxtRange::FindWord(
	LONG *pcpMin,			//@parm Out parm to receive word's cpMin; NULL OK
	LONG *pcpMost,			//@parm Out parm to receive word's cpMost; NULL OK
	FINDWORD_TYPE type) const //@parm Type of word to find
{
	TRACEBEGIN(TRCSUBSYSRANG, TRCSCOPEINTERN, "CTxtRange::FindWord");

	LONG	cch, cch1;
	LONG	cpMin, cpMost;
	CTxtPtr	tp(_rpTX);

	_TEST_INVARIANT_

	Assert(type == FW_EXACT || type == FW_INCLUDE_TRAILING_WHITESPACE );

	GetRange(cpMin, cpMost);
	if(pcpMin)
	{
		tp.SetCp(cpMin);
		if(!tp.IsAtBOWord())							// cpMin not at BOW:
			cpMin += tp.FindWordBreak(WB_MOVEWORDLEFT);	//  go there

		*pcpMin = cpMin;

		Assert(cpMin >= 0 && cpMin <= GetTextLength());
	}

	if(pcpMost)
	{
		tp.SetCp(cpMost);
		if (!tp.IsAtBOWord() ||							// If not at word strt
			(!cpMost || pcpMin) && cpMin == cpMost)		//  or there but need
		{												//  to expand IP,
			cch = tp.FindWordBreak(WB_MOVEWORDRIGHT);	//  move to next word

			if(cch && type == FW_EXACT)					// If moved and want
			{											//  word proper, move
				cch1 = tp.FindWordBreak(WB_LEFTBREAK);	//  back to end of
				if(cch + cch1 > 0)						//  preceding word
					cch += cch1;						// Only do so if were
			}											//  not already at end
			cpMost += cch;
		}
		*pcpMost = cpMost;

		Assert(cpMost >= 0 && cpMost <= GetTextLength());
		Assert(cpMin <= cpMost);
	}
}

/*
 *	CTxtRange::CalcTextLenNotInRange()
 *	
 *	@mfunc
 *		Helper function that calculates the total length of text
 *		excluding the current range. 
 *
 *	@comm
 *		Used for limit testing. The problem being solved is that 
 *		the range can contain the final EOP which is not included
 *		in the adjusted text length.
 */
LONG CTxtRange::CalcTextLenNotInRange()
{
	LONG	cchAdjLen = GetPed()->GetAdjustedTextLength();
	LONG	cchLen = cchAdjLen - abs(_cch);
	LONG	cpMost = GetCpMost();

	if (cpMost > cchAdjLen)
	{
		// Selection extends beyond adjusted length. Put amount back in the
		// selection as it has become too small by the difference.
		cchLen += cpMost - cchAdjLen;
	}

	return cchLen;
}

/*
 *	CTxtRange::ExpandToLink()
 *
 *	@mfunc	
 *		helper function that expands this range to the bounding set of runs
 *		with CFE_LINK set
 *
 *	@devnote	FUTURE (alexgo): this should be recoded in the future to make
 *				it smaller && less demented.  Potentially, we could use a 
 *				generic "search for partial charformat" routine.
 */
void CTxtRange::ExpandToLink(void)
{
	CTxtEdit *ped = GetPed();
	LONG	cpMin, cpMost;
	const CCharFormat *pcf;

	// do the easy check first

	Expander(tomCharFormat, TRUE, NULL, &cpMin, &cpMost);

	// make cpMin be the active end
	if( _cch > 0 )
	{
		FlipRange();
	}

	SetExtend(TRUE);		

	CFormatRunPtr rp(_rpCF);

	// go backwards until we don't see any more CFE_LINK bits
	while( 1 )
	{
		rp.AdjustBackward();

		pcf = ped->GetCharFormat(rp.GetFormat());

		if( !pcf || !(pcf->dwEffects & CFE_LINK) )
		{
			break;
		}

		if( !Advance(-(LONG)rp.GetIch()) )
		{
			break;
		}
		rp.AdvanceCp(-(LONG)rp.GetIch());
	}

	// now flip the range around and go forwards until we

	FlipRange();
	rp = _rpCF;

	while( 1 )
	{
		rp.AdjustForward();

		pcf = ped->GetCharFormat(rp.GetFormat());

		if( !pcf || !(pcf->dwEffects & CFE_LINK) )
		{
			break;
		}

		if( !Advance( rp.GetRun(0)->_cch ) )
		{
			break;
		}

		rp.AdvanceCp(rp.GetRun(0)->_cch);
	}

	SetExtend(FALSE);
}

////////////////////////// Outline Support //////////////////////////////////

/*
 *	CTxtRange::Promote(lparam, publdr)
 *
 *	@mfunc
 *		Promote selected text according to:
 *
 *		LOWORD(lparam) == 0 ==> promote to body-text
 *		LOWORD(lparam) != 0 ==> promote/demote current selection by
 *								LOWORD(lparam) levels
 *	@rdesc
 *		TRUE iff promotion occurred
 *
 *	@devnote
 *		Changes this range
 */
HRESULT CTxtRange::Promote (
	LPARAM		  lparam,	//@parm 0 to body, < 0 demote, > 0 promote
	IUndoBuilder *publdr)	//@parm undo builder to receive antievents
{
	TRACEBEGIN(TRCSUBSYSSEL, TRCSCOPEINTERN, "CTxtRange::Promote");

	if(abs(lparam) >= NHSTYLES)
		return E_INVALIDARG;

	if(publdr)
		publdr->StopGroupTyping();

	if(_cch > 0)							// Point at cpMin
		FlipRange();

	LONG		cchText = GetTextLength();
	LONG		cpEnd = GetCpMost();
	LONG		cpMin, cpMost;
	BOOL		fHeading = TRUE;			// Default heading in range
	HRESULT		hr;
	LONG		Level = 0;
	LONG		nHeading = NHSTYLES;		// Setup to find any heading
	CParaFormat PF;
	const CParaFormat *pPF;
	CPFRunPtr	rp(*this);
	LONG		cch = rp.FindHeading(abs(_cch), nHeading);
	WORD		wEffects;

	if(!lparam)								// Demote to subtext
	{
		if(cch)								// Already in subtext so don't
			return S_FALSE;					//  need to demote

		CTxtPtr tp(_rpTX);

		if(!tp.IsAfterEOP())
			cch = tp.FindEOP(tomBackward);
		nHeading = 1;
		if(tp.GetCp())						// Get previous level and convert
		{									//  to heading to set up
			rp.AdvanceCp(cch);				//  following Level code
			rp.AdjustBackward();
			nHeading = rp.GetOutlineLevel()/2 + 1;
		}
	}
	else if(cch == tomBackward)				// No heading in range					
	{										// Set up to promote to
		

⌨️ 快捷键说明

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