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

📄 tomrange.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
 *				  (if <p Cset> valid) ? S_FALSE : E_INVALIDARG
 *
 *	@devnote
 *		Argument validation of the MoveWhile and MoveUntil methods is done by
 *		the helper CTxtRange::Matcher (Cset, Count, pDelta, fExtend, fSpan)
 */
STDMETHODIMP CTxtRange::MoveWhile (
	VARIANT * Cset,				//@parm Character match set to use
	long 	  Count,			//@parm Max number of characters to move past
	long *	  pDelta)			//@parm Out parm to receive actual count of
								//		characters end is moved
{
	TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtRange::MoveWhile");
							
	return Matcher(Cset, Count, pDelta, MOVE_IP, MATCH_WHILE);
}

/*
 *	CTxtRange::Paste (pVar, ClipboardFormat)
 *
 *	@mfunc
 *		Paste the data object <p pVar> into this range.  If
 *		<p pVar> is null, paste from the clipboard. 
 *
 *	@rdesc
 *		HRESULT = (WriteAccessDenied) ? E_ACCESSDENIED :
 *				  (if success) ? NOERROR : E_OUTOFMEMORY
 */
STDMETHODIMP CTxtRange::Paste (
	VARIANT *pVar,				//@parm Data object to paste 
	long	 ClipboardFormat)	//@parm Desired clipboard format
{
#ifndef PEGASUS
	TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtRange::Paste");

	if(IsZombie())
		return CO_E_RELEASED;

	CCallMgr		callmgr(GetPed());
	HRESULT			hr;
	IDataObject *	pdo = NULL;			// Default clipboard
	CGenUndoBuilder	undobldr(GetPed(), UB_AUTOCOMMIT );

	if( WriteAccessDenied())
		return E_ACCESSDENIED;

	if(pVar)
		if (pVar->vt == VT_UNKNOWN)
			pVar->punkVal->QueryInterface(IID_IDataObject, (void **)&pdo);
		else if (pVar->vt == (VT_UNKNOWN | VT_BYREF))
			pdo = (IDataObject *)(*pVar->ppunkVal);

	hr = GetPed()->PasteDataObjectToRange (pdo, this,
		(WORD)ClipboardFormat, NULL, &undobldr, PDOR_NONE);

	if(pdo && pVar->vt == VT_UNKNOWN)
		pdo->Release();
	Update(TRUE);						// Update selection
	return hr;
#else
	return 0;
#endif
}

/*
 *	ITextRange::ScrollIntoView(long Code) 
 *
 *	@mfunc
 *		Method that scrolls this range into view according to the
 *		code Code defined below.
 *
 *	@rdesc
 *		HRESULT = (if success) ? NOERROR : S_FALSE
 */
STDMETHODIMP CTxtRange::ScrollIntoView (
	long Code)			//@parm Scroll code
{
#ifndef PEGASUS
	TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtRange::ScrollIntoView");

	// Validate parameter
	if (Code != tomStart && Code != tomEnd)
	{
		return E_INVALIDARG;
	}

	if(IsZombie())
		return CO_E_RELEASED;

	// Get local copy of ped to save some indirections.
	CTxtEdit *ped = GetPed();

	if (!ped->fInplaceActive())
	{
		// If the control is not active, we can't get the information
		// because no one knows what our client rect is.
		return E_FAIL;
	}

	// Get a local copy of display to save some indirections. 
	CDisplay *pdp = ped->_pdp;

	LONG cpStart;
	LONG cpForEnd;

	GetRange(cpStart, cpForEnd);

	// Get the view rectangle so we can compute the absolute x/y 
	RECT rcView;
	pdp->GetViewRect(rcView, NULL);

	// Set up tp for PointFromTp call
	CRchTxtPtr tp(ped, cpStart);

	// Values used for making returned point locations absolute since
	// PointFromTp adjusts the point returned to be relative to the
	// display.
	const LONG xScrollAdj = pdp->GetXScroll() - rcView.left;
	const LONG yScrollAdj = pdp->GetYScroll() - rcView.top;

	// Get the left/top for the start
	CLinePtr rpStart(pdp);
	POINT ptStart;
	LONG iliStart = 
		pdp->PointFromTp(tp, NULL, TRUE, ptStart, &rpStart, TA_TOP + TA_LEFT);
	ptStart.x += xScrollAdj;
	ptStart.y += yScrollAdj;

	// Get the right/bottom for the end
	CLinePtr rpEnd(pdp);
	POINT ptEnd;
	tp.SetCp(cpForEnd);
	LONG iliEnd = 
		pdp->PointFromTp(tp, NULL, TRUE, ptEnd, &rpEnd, TA_BOTTOM + TA_RIGHT);
	ptEnd.x += xScrollAdj;
	ptEnd.y += yScrollAdj;

	//
	// Calculate the yScroll 
	//

	// The basic idea is to display both the start and the end if possible. But 
	// if it is not possible then display the requested end based on the input 
	// parameter.

	LONG yHeightView = pdp->GetViewHeight();
	LONG yScroll;

	if (tomStart == Code)
	{
		// Scroll the Start cp to the top of the view
		yScroll = ptStart.y;
	}
	else
	{
		// Scroll the End cp to the bottom of the view
		yScroll = ptEnd.y - yHeightView;
	}

	//
	// Calculate the X Scroll
	// 

	// Default scroll to beginning of the line
	LONG xScroll = 0;

	// Make view local to save a number of indirections
	LONG xWidthView = pdp->GetViewWidth();

	if (iliStart == iliEnd)
	{
		// Entire selection is on the same line so we want to display as
		// much of it as is possible.
		LONG xWidthSel = ptEnd.x - ptStart.x;

		if (xWidthSel > xWidthView)
		{
			// Selection length is greater than display width
			if (tomStart == Code)
			{
				// Show Start requested - just start from beginning
				// of selection
				xScroll = ptStart.x;
			}
			else
			{
				// Show end requested - show as much of selection as
				// possible, ending with last character in the 
				// selection.
				xScroll = ptEnd.x - xWidthView;
			}
		}
		else if (ptEnd.x > xWidthView)
		{
			// End of selection is outside the view starting
			// at 0 so display as much as possible ending with
			// End.
			xScroll = ptEnd.x - xWidthView;
		}
	}
	else 
	{
		// Multiline selection. Display as much as possible of the requested
		// end's line.

		// Calc width of line
		LONG xWidthLine = (tomStart == Code)
			? rpStart->_xWidth + rpStart->_xLeft
			: rpEnd->_xWidth + rpEnd->_xLeft;


		// If line width is less than or equal to view, start at 
		// 0 otherwise we need to adjust starting position to 
		// show as much of the requested end's selection line 
		// as possible.
		if (xWidthLine > xWidthView)
		{
			if (tomStart == Code)
			{
				// Start end to be displayed

				if (xWidthLine - ptStart.x > xWidthView)
				{
					// Selection is bigger than the view
					// so start at the beginning and display
					// as much as possible.
					xScroll = ptStart.x;
				}
				else
				{
					// Remember that this is a multiline selection so the 
					// selection on this line goes from ptStart.x to the 
					// end of line. Since the selection width is less than 
					// the width of the view, we just back up the width
					// of view to show the entire selection.
					xScroll = xWidthLine - xWidthView;
				}
			}
			else
			{
				// Show the end of the selection. In the multiline case,
				// this goes from the beginning of the line to End. So
				// we only have to adjust if the End is beyond the view.
				if (ptEnd.x > xWidthView)
				{
					// End beyond the view. Show as much as possible
					// of the selection.
					xScroll = ptEnd.x - xWidthView;
				}
			}
		}
	}

	// Do the scroll
	pdp->ScrollView(xScroll, yScroll, FALSE, FALSE);

	return S_OK;
#else
	return 0;
#endif
}

/*
 *	CTxtRange::Select ()
 *
 *	@mfunc
 *		Copy this range's cp's and story ptr to the active selection.
 *
 *	@rdesc
 *		HRESULT = (if selection exists) ? NOERROR : S_FALSE
 */
STDMETHODIMP CTxtRange::Select ()
{
	TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtRange::Select");

	if(IsZombie())
		return CO_E_RELEASED;

	LONG	cpMin, cpMost;
 
	CTxtSelection *pSel = GetPed()->GetSel();

	if(pSel)
	{
		GetRange(cpMin, cpMost);
		pSel->SetRange(cpMin, cpMost);
		return NOERROR;
	}
	return S_FALSE;
}

/*
 *	CTxtRange::SetChar (Char)
 *
 *	@mfunc
 *		Set char at cpFirst = <p Char>
 *
 *	@rdesc
 *		HRESULT = (WriteAccessDenied) ? E_ACCESSDENIED :
 *				  (char stored) ? NOERROR : S_FALSE
 *
 *	@devnote
 *		Special cases could be much faster, e.g., just overtype the plain-
 *		text backing store unless at EOD or EOR.  Code below uses a cloned
 *		range to handle all cases easily and preserve undo capability.
 */
STDMETHODIMP CTxtRange::SetChar (
	long Char)				//@parm New value for char at cpFirst
{
	TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtRange::SetChar");
	
	if(IsZombie())
		return CO_E_RELEASED;

	CTxtEdit *		ped = GetPed();
	CCallMgr		callmgr(ped);
	TCHAR			ch = (TCHAR)Char;			// Avoid endian problems
	CTxtRange		rg(*this);
	CGenUndoBuilder undobldr(ped, UB_AUTOCOMMIT );

	if( WriteAccessDenied())
		return E_ACCESSDENIED;

	if(!ped->TxGetMultiLine() && IsEOP(Char))	// EOPs are not	allowed in
		return FALSE;							//  single-line edit controls

	undobldr.StopGroupTyping();

	rg.Collapser(tomStart);						// Collapse at cpMin 
	rg.SetExtend(TRUE);							// Setup to select
	rg.Advance(1);								// Try to select char at IP
	if(rg.ReplaceRange(1, &ch, &undobldr, SELRR_REMEMBERRANGE))
	{
		Update(TRUE);							// Update selection
		return NOERROR;
	}
	return S_FALSE;
}

/*
 *	CTxtRange::SetEnd (cp)
 *
 *	@mfunc
 *		Set this range's End cp
 *
 *	@rdesc
 *		HRESULT = (if change) ? NOERROR : S_FALSE
 *
 *	@comm
 *		Note that setting this range's cpMost to <p cp> also sets cpMin to
 *		<p cp> if <p cp> < cpMin.
 */
STDMETHODIMP CTxtRange::SetEnd (
	long cp)							//@parm Desired new End cp
{
	TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtRange::SetEnd");

	if(IsZombie())
		return CO_E_RELEASED;

	LONG cpMin = GetCpMin();

	ValidateCp(cp);
	return SetRange(min(cpMin, cp), cp);		// Active end is End
}

/*
 *	CTxtRange::SetFont (pFont)
 *
 *	@mfunc
 *		Set this range's character attributes to those given by <p pFont>.
 *		This method is a "character format painter".
 *
 *	@rdesc
 *		HRESULT = (!pFont) ? E_INVALIDARG :
 *				  (if success) ? NOERROR : 
 *				  (protected) ? E_ACCESSDENIED : E_OUTOFMEMORY
 */
STDMETHODIMP CTxtRange::SetFont (
	ITextFont * pFont)	//@parm Font object with desired character formatting  
{
	TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtRange::SetFont");

	if(!pFont)
		return E_INVALIDARG;
	
	if(IsZombie())
		return CO_E_RELEASED;

	ITextFont * pFontApply = (ITextFont *) new CTxtFont(this);

	if(!pFontApply)
		return E_OUTOFMEMORY;

	HRESULT
	hr = (*(LONG *)pFontApply == *(LONG *)pFont)		// If same vtable, use
	   ? CharFormatSetter(&((CTxtFont *)pFont)->_CF)	//  its _CF; else copy
	   : pFontApply->SetDuplicate(pFont);				//  to clone and apply

	pFontApply->Release();
	return hr;
}

/*
 *	CTxtRange::SetFormattedText (pRange)
 *
 *	@mfunc
 *		Replace this range's text with formatted text given by <p pRange>.
 *		If <p pRange> is NULL, paste from the clipboard.
 *
 *	@rdesc
 *		HRESULT = (WriteAccessDenied) ? E_ACCESSDENIED :
 *				  (if success) ? NOERROR : E_OUTOFMEMORY
 *
 *	@FUTURE
 *		Do this more efficiently if pRange points at a RichEdit range. This
 *		would also help with RichEdit D&D to RichEdit targets
 */
STDMETHODIMP CTxtRange::SetFormattedText (
	ITextRange * pRange)		//@parm Formatted text to replace this 
								// range's text
{
#ifndef PEGASUS
	TRACEBEGIN(TRCSUBSYSTOM, TRCSCOPEEXTERN, "CTxtRange::SetFormattedText");

	if(IsZombie())
		return CO_E_RELEASED;

	CCallMgr	callmgr(GetPed());
	LONG		cpMin = GetCpMin();
	HRESULT		hr;
	IUnknown *	pdo = NULL;
	VARIANT		vr;

	if(!pRange)
		return NOERROR;					// Nothing to paste

	if( WriteAccessDenied())
		return E_ACCESSDENIED;

	pVariantInit(&vr);
	vr.vt = VT_UNKNOWN | VT_BYREF;
	vr.ppunkVal = &pdo;

	hr = pRange->Copy(&vr);
	if(hr == NOERROR)
	{
		hr = Paste(&vr, 0);
		pdo->Release();					// Release the data object
		_cch = GetCp() - cpMin;			// Select the new text
	}
	return hr;
#else
	return 0;
#endif
}

/*
 *	CTxtRange::SetIndex (Unit, Index, Extend)
 *
 *	@mfunc
 *		If <p Extend> is zero, convert this range into an insertion point
 *		at the start of the	<p Index>th <p Unit> in the current story. If
 *		<p Extend> is nonzero, set this range to consist of this unit. The
 *		start of the story corresponds to <p Index> = 0 for all units.
 *
 *		Positive indices are 1-based and index relative to the beginning of
 *		the story.  Negative indices are -1-based and index relative to the
 *		end of the story.  So an index of 1 refers to the first Unit in the

⌨️ 快捷键说明

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