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

📄 rtext.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
BOOL CRchTxtPtr::Check_rpCF()
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CRchTxtPtr::Check_rpCF");

	if(_rpCF.IsValid())
		return TRUE;

	if( !IsRich() && !IsIMERich() )
		return FALSE;
	
	if( !_rpCF.InitRuns (GetCp(), GetTextLength(),
				&(GetPed()->GetTxtStory()->_pCFRuns)) )
	{
		return FALSE;
	}

	CNotifyMgr *pnm = GetPed()->GetNotifyMgr();	// For notifying of changes
	if( pnm )
		pnm->NotifyPostReplaceRange(	 		// Notify interested parties
				(ITxNotify *)this, INFINITE,	//  that
				0, 0, INFINITE, INFINITE);

	return TRUE;
}

/*
 *	CRchTxtPtr::Check_rpPF()
 *	
 *	@mfunc
 *		enable _rpPF if it's not already enabled
 *	
 *	@rdesc
 *		TRUE if _rpPF is enabled
 */
BOOL CRchTxtPtr::Check_rpPF()
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CRchTxtPtr::Check_rpPF");

	if(_rpPF.IsValid())
		return TRUE;

	if( !IsRich() )
		return FALSE;

	if( !_rpPF.InitRuns (GetCp(), GetTextLength(),
				&(GetPed()->GetTxtStory()->_pPFRuns)) )
	{
		return FALSE;
	}

	CNotifyMgr *pnm = GetPed()->GetNotifyMgr();	// For notifying of changes
	if( pnm )
		pnm->NotifyPostReplaceRange(	 		// Notify interested parties
				(ITxNotify *)this, INFINITE,	// of the change.
				0, 0, INFINITE, INFINITE);

	return TRUE;
}

/*
 * CRchTxtPtr::FindWordBreak(action, cpMost)
 *
 *	@mfunc
 *		Same as CTxtPtr::FindWordBreak(), but moves the whole rich text ptr
 *
 *	@rdesc
 *		cch this rich text ptr is moved
 */
LONG CRchTxtPtr::FindWordBreak(
	INT		action,		//@parm Kind of word break to find
	LONG	cpMost)		//@parm Limiting character position

{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CRchTxtPtr::FindWordBreak");

	LONG cch = _rpTX.FindWordBreak(action, cpMost);
	_rpCF.AdvanceCp(cch);
	_rpPF.AdvanceCp(cch);

	return cch;
}

/*
 *	CRchTxtPtr::BindToCp(dwNewCp)
 *
 *	@mfunc
 *		Set cp to new value and recalculate that new position.
 */
void CRchTxtPtr::BindToCp(
	DWORD cp)			// @parm new cp for rich text
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CRchTxtPtr::BindToCp");

	cp = _rpTX.BindToCp(cp);		// Recalculate cp for plain text

	// use the InitRunPtrs routine so that the run pointers will get 
	// re-initialized and rebound with the correct run array.  The
	// run array formerly used (if any at all) is not necessary valid
	// when this function is called.

	InitRunPtrs(cp);

	// Do invariant testing at end because this fixes up the rich text
	// pointer in the face of backing store changes.
	_TEST_INVARIANT_
}

/*
 *	CRchTxtPtr::CheckFormatRuns ()
 *
 *	@mfunc
 *		Check the format runs against what's in CTxtStory.  If
 *		different, forces a rebind to <p cp>
 */
void CRchTxtPtr::CheckFormatRuns( )
{
	CTxtStory *pStory = GetPed()->GetTxtStory();

	if( (pStory->GetCFRuns() != (CFormatRuns *)_rpCF._prgRun) ||
		(pStory->GetPFRuns() != (CFormatRuns *)_rpPF._prgRun) )
	{
		InitRunPtrs(GetCp());
	}

	_TEST_INVARIANT_
}

/*
 *	CRchTxtPtr::ChangeCase(cch, Type, publdr)
 *	
 *	@mfunc
 *		Change case of cch chars starting at this text ptr according to Type,
 *		which has the possible values:
 *
 *		tomSentenceCase	= 0: capitalize first letter of each sentence
 *		tomLowerCase	= 1: change all letters to lower case
 *		tomUpperCase	= 2: change all letters to upper case
 *		tomTitleCase	= 3: capitalize the first letter of each word
 *		tomToggleCase	= 4: toggle the case of each letter
 *	
 *	@rdesc
 *		TRUE iff a change occurred
 *
 *	@devnote
 *		Since this routine only changes the case of characters, it has no
 *		effect on rich-text formatting.  However it is part of the CRchTxtPtr
 *		class in order to notify the display of changes.  CTxtRanges are also
 *		notified just in case the text blocks are modified.
 */
BOOL CRchTxtPtr::ChangeCase (
	LONG		  cch,			//@parm # chars to change case for
	LONG		  Type,			//@parm Type of change case command
	IUndoBuilder *publdr)		//@parm UndoBuilder to receive anti-event
								//  	for any replacements
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CRchTxtPtr::ChangeCase");
	_TEST_INVARIANT_

#define	BUFFERLEN	256

	LONG	cchChunk, cchFirst, cchFormat, cchGet, cchLast;
	BOOL	fAlpha, fToUpper, fUpper;			// Flags controling case change
	BOOL	fChange = FALSE;					// No change yet
	BOOL	fStart = TRUE;						// Start of Word/Sentence
	TCHAR *	pch;								// Ptr to walk rgCh with
	WORD *	pType;								// Ptr to walk rgType with
	WCHAR	rgCh[BUFFERLEN];					// Char buffer to work in
	WORD	rgType[BUFFERLEN];					// C1_TYPE array for rgCh

	if( GetCp() )
	{
		if( Type == tomSentenceCase )
		{
			fStart = _rpTX.IsAtBOSentence();
		}
		else if( Type == tomTitleCase )
		{
			// check to see if we are at the beginning of
			// a word.  This is the case if the character preceeding
			// our current position is white space.
			fStart = IsWhiteSpace(_rpTX.GetPrevChar());
		}
	}
	while(cch > 0)								// Do 'em all (or as many as
	{											//  in story)
		cchChunk = min(BUFFERLEN, cch);			// Get next bufferful
		if(_rpCF.IsValid())						// Make sure it stays within
		{										//  current char/paraformat
			cchFormat = _rpCF.GetCchLeft();		//  runs to simplify changing
			cchChunk = min(cchChunk, cchFormat);//  text with undo
		}										
		if(_rpPF.IsValid())						
		{
			cchFormat = _rpPF.GetCchLeft(); 
			cchChunk = min(cchChunk, cchFormat); 
		}
		cch -= cchChunk;						// Decrement the count
		cchGet = _rpTX.GetText(cchChunk, rgCh);	// Manipulate chars in buffer
		if(cchGet < cchChunk)					//  (for undo, need to use
		{										//  ReplaceRange())
			cch = 0;							// No more chars in story,
			if(!cchGet)							//  so we'll be done
				break;							// We're done already
			cchChunk = cchGet;					// Something in this chunk
		}

		if (0 == W32->GetStringTypeEx(0, CT_CTYPE1, rgCh,		// Find out whether chars are
						 cchChunk, rgType))				//  UC, LC, or neither
        {
            TRACEWARNSZ("GetStringTypeEx failed");
            return FALSE;
        }    
		cchLast = 0;									// Default nothing to replace
		cchFirst = -1;
		for(pch = rgCh, pType = rgType;			// Process buffered chars
			cchChunk;
			cchChunk--, pch++, pType++)
		{
			fAlpha = *pType & (C1_UPPER | C1_LOWER); // Nonzero if UC or LC
			fUpper = (*pType & C1_UPPER) != 0;	// TRUE if UC
			fToUpper = fStart ? TRUE : fUpper;	// capitalize first letter of a
												// sentence
			switch(Type)
			{									// Decide whether to change
			case tomLowerCase:					//  case and determine start
				fToUpper = FALSE;				//  of word/sentence for title
				break;							//  and sentence cases

			case tomUpperCase:
				fToUpper = TRUE;
				break;

			case tomToggleCase:
				fToUpper = !fUpper;
				break;

			case tomSentenceCase:
				if(*pch == TEXT('.'))			// If sentence terminator,
					fStart = TRUE;				//  capitalize next alpha
				if(fAlpha)						// If this char is alpha, next
					fStart = FALSE;				//  char can't start a
				break;							//  sentence

			case tomTitleCase:					// If this char is alpha, next
				fStart = (fAlpha == 0);			//  char can't start a word
				break;
			default:
				return FALSE;
			}

			if(fAlpha && (fToUpper ^ fUpper))	// Only change case if it
			{									//  makes a difference (saves
				if(fToUpper)					//  on system calls and undos)
					CharUpperBuff(pch, 1);
				else
					CharLowerBuff(pch, 1);

				fChange = TRUE;					// Return value: change made
				if( cchFirst == -1 )			// Save cch of unchanged
					cchFirst = cchGet-cchChunk;	//  leading string
				cchLast = cchChunk - 1;			// Save cch of unchanged
			}									//  trailing string
		}
		if( cchFirst == -1 )
		{
			Assert(cchLast == 0);
			cchFirst = cchGet;
		}

		Advance(cchFirst);						// Skip unchanged leading
		cchGet -= cchFirst + cchLast;			//  string. cchGet = cch of
		_rpCF.AdjustForward();					//  changed span. Adjust in
												//  case cchFirst = 0
		ReplaceRange(cchGet, cchGet, rgCh		
			+ cchFirst, publdr, _rpCF.GetFormat());
		Advance(cchLast);						// Skip unchanged trailing 
	}											//  string
	return fChange;
}

// The following defines a mask for Units implemented by UnitCounter()
#define IMPL ((1 << tomCharacter)  + (1 << tomWord) + (1 << tomSentence) + \
			  (1 << tomParagraph)  + (1 << tomLine) + (1 << tomStory) +	\
			  (1 << tomCharFormat) + (1 << tomParaFormat) + (1 << tomObject))
 
/*
 *	CRchTxtPtr::UnitCounter (Unit, &cUnit, cchMax)
 *
 *	@mfunc
 *		Helper function to count chars in <p cUnit> Units defined by <p Unit>
 *		<p cUnit> is a signed count.  If it extends beyond either end of the
 *		story, count up to that end and update <p cUnit> accordingly.  If
 *		<p cchMax> is nonzero, stop counting when the count exceeds <p cchMax>
 *		in magnitude.
 *
 *	@rdesc
 *		If unit is implemented, return cch corresponding to the units counted
 *		(up to a maximum magnitude of <p cchMax>) and update cUnit;
 *		else return tomForward to signal unit not implemented and cUnit = 0.
 *		If unit is implemented but unavailable, e.g., tomObject with no
 *		embedded objects, return tomBackward.
 *
 *	@devnote
 *		This is the basic engine used by the TOM CTxtRange::Move() and Index()
 *		methods.
 */
LONG CRchTxtPtr::UnitCounter (
	LONG	Unit,				//@parm Type of unit to count
	LONG &	cUnit,				//@parm Count of units to count chars for
	LONG	cchMax)				//@parm Maximum character count
{
	TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEINTERN, "CRchTxtPtr::UnitCounter");

	LONG	action;				// Gives direction and tomWord commands
	LONG	cch;				// Collects cch counted
	LONG	cchText = GetTextLength();
	LONG	cp = GetCp();
	LONG	iDir = cUnit > 0 ? 1 : -1;
	LONG	j;					// For-loop index
	CDisplay *pdp;				// Used for tomLine case

	if(!cUnit)									// Nothing to count
	{
		return ((DWORD)Unit > tomObject || !((IMPL >> Unit) & 1))
			? tomForward : 0;					// Indicate Unit not
	}											//  implemented
	if(cchMax <= 0)
		cchMax = tomForward;					// No cch limit

	switch(Unit)
	{
	case tomCharacter:							// Smallest Unit
		cp += cUnit;							// Requested new cp
		ValidateCp(cp);							// Make sure it's OK
		cch = cUnit = cp - GetCp();				// How many cch, cUnits
		break;									//  actually moved

	case tomStory:								// Largest Unit
		cch = (cUnit > 0) ? cchText - cp : -cp;	// cch to start of story
		cUnit = cch ? iDir : 0;					// If already at end/start,
		break;									//  of story, no count

	case tomCharFormat:							// Constant CHARFORMAT
		cch = _rpCF.CountRuns(cUnit, cchMax, cchText);
		break;

	case tomParaFormat:							// Constant PARAFORMAT
		cch = _rpPF.CountRuns(cUnit, cchMax, cchText);
		break;

	case tomObject:
		if(!GetObjectCount())					// No objects: can't move, so
		{
			cUnit = 0;							//  set cUnit = 0 and
			return tomBackward;					//  signal Unit unavailable
		}
		cch = GetPed()->_pobjmgr->CountObjects(cUnit, GetCp());
		break;

	case tomLine:
		pdp = GetPed()->_pdp;
		if(pdp)									// If this story has a display
		{										//  use a CLinePtr
			CLinePtr rp(pdp);
			pdp->WaitForRecalc(cp, -1);
			rp.RpSetCp(cp, FALSE);
			cch = rp.CountRuns(cUnit, cchMax, cchText);
			break;
		}										// Else fall thru to treat as
												//  tomPara
	default:									// tp dependent cases
	  {											// Block to contain tp() which
		CTxtPtr tp(_rpTX);						//  takes time to construct

		if (cUnit < 0)							// Counting backward
		{
			action = (Unit == tomWord)
				? WB_MOVEWORDLEFT : tomBackward;
		}
		else									// Counting forward
		{
			action = (Unit == tomWord)
				? WB_MOVEWORDRIGHT : tomForward;
		}
	
		for (cch = 0, j = cUnit; j && abs(cch) < cchMax; j -= iDir)
		{
			cp = tp.GetCp();					// Save starting cp for
			switch (Unit)						//  calculating cch for this
			{									//  Unit
			case tomWord:
				tp.FindWordBreak(action);
				break;
	
			case tomSentence:
				tp.FindBOSentence(action);
				break;
		
			case tomLine:						// Story has no line array:
			case tomParagraph:					//  treat as tomParagraph
				tp.FindEOP(action);
				break;
		
			default:
				cUnit = 0;
				return tomForward;				// Return error
			}
			if(tp.GetCp() - cp == 0)			// No count:
				break;							//  don't decrement cUnit
			cch += tp.GetCp() - cp;
		}
		cUnit -= j;								// Discount any runs not
	  }											//  counted if |cch| >= cchMax
	}

	if(abs(cch) > cchMax)						// Keep cch within requested
	{											//  limit
		cch = cch > 0 ? cchMax : -cchMax;
		if(Unit == tomCharacter)
			cUnit = cch;
	}		

	Advance(cch);								// Move to new position
	return cch;									// Total cch counted
}

/*
 *	CRchTxtPtr::Zombie ()
 *
 *	@mfunc
 *		Turn this object into a zombie by NULLing out its _ped member
 */
void CRchTxtPtr::Zombie ()
{
	TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CRchTxtPtr::Zombie");

	_rpTX.Zombie();
	_rpCF.SetToNull();
	_rpPF.SetToNull();
}

⌨️ 快捷键说明

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