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

📄 select.cpp

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

	DWORD		dwScrollBars	= ped->TxGetScrollBars();

	if( ped->IsStreaming() )
	{
		// don't bother doing anything if we are loading in text or RTF
		// data.
		return FALSE;
	}
	_yCurrentDescent = -1;

	// We better be inplace active if we get here
	AssertSz(GetPed()->fInplaceActive(), 
		"CTxtSelection::UpdateCaret no inplace active");

	// Get the client rectangle once to save various
	// callers getting it.
	GetPed()->TxGetClientRect(&rcClient);

	_pdp->GetViewRect(rcView, &rcClient);

	// View can be bigger than client rect because insets can be negative.
	// We don't want the caret to be any bigger than the client view otherwise
	// the caret will leave pixel dust on other windows.
	yViewTop = max(rcView.top, rcClient.top);
	yViewBottom = min(rcView.bottom, rcClient.bottom);

	xWidthView = rcView.right - rcView.left;
	yHeightView = yViewBottom - yViewTop;

	if(fScrollIntoView)
	{
		fAutoVScroll = (dwScrollBars & ES_AUTOVSCROLL) != 0;
		fAutoHScroll = (dwScrollBars & ES_AUTOHSCROLL) != 0;

		// If we're not forcing a scroll, only scroll if window has focus
		// or selection isn't hidden
		fScrollIntoView = ped->_fFocus || !ped->fHideSelection();
	}

	if(!fScrollIntoView && (fAutoVScroll || fAutoHScroll))
	{											// Would scroll but don't have
		ped->_fScrollCaretOnFocus = TRUE;		//  focus. Signal to scroll
		fAutoVScroll = fAutoHScroll = FALSE;	//  when we do get focus
	}

	if(_pdp->PointFromTp(*this, &rcClient, _fCaretNotAtBOL, pt, &rp,
		TA_BASELINE) < 0 ||
		!_cch && IsInOutlineView() && (GetPF()->wEffects & PFE_COLLAPSED))
	{
		goto not_visible;
	}

	// HACK ALERT - Because plain-text multiline controls do not have the 
	// automatic EOP, we need to special case their processing here because 
	// if you are at the end of the document and last character is an EOP, 
	// you need to be on the next line in the display not the current line.

	if(CheckPlainTextFinalEOP())					//  terminated by an EOP
	{
		if (GetPF()->wAlignment == PFA_CENTER)
			pt.x = (rcView.left + rcView.right) >> 1;
		else
			// Set the x to the beginning of the line
			pt.x = rcView.left;

		pt.x -= xScroll;							// Absolute coordinate

		// Bump the y up a line. We get away with the calculation because 
		// the document is plain text so all lines have the same height. 
		// Also, note that the rp below is used only for height 
		// calculations, so it is perfectly valid for the same reason 
		// even though it is not actually pointing to the correct line. 
		// (I told you this is a hack.)
		pt.y += rp->_yHeight;
	}

	_xCaret = (LONG) pt.x;
	yBase   = (LONG) pt.y;
	
	// Compute caret height, ascent, and descent
	yAscent = GetCaretHeight(&yDescent);
	yAscent -= yDescent;

	// Default to line empty case. Use what came back from the default 
	// calculation above.
	yDescentLine = yDescent;
	yAscentLine = yAscent;

	if( rp.IsValid() )
	{
		if (rp->_yDescent != -1)
		{
			// Line has been measured so we can use the values in the
			// line.
			yDescentLine = rp->_yDescent;
			yAscentLine = rp->_yHeight - yDescentLine;
		}
	}

	if(yAscent + yDescent == 0)
	{
		yAscent = yAscentLine;
		yDescent = yDescentLine;
	}
	else
	{
		// this is a bit counter-intuitive at first.  Basically,
		// even if the caret should be large (i.e. due to a
		// large font at the insertion point), we can only make it
		// as big as the line.  If a character is inserted, then 
		// the line becomes bigger, and we can make the caret
		// the correct size.
		yAscent = min(yAscent, yAscentLine);
		yDescent = min(yDescent, yDescentLine);
	}

	if(fAutoVScroll)
	{
		Assert(yDescentLine >= yDescent);
		Assert(yAscentLine >= yAscent);

		yBelow = yDescentLine - yDescent;
		yAbove = yAscentLine - yAscent;

		ySum = yAscent;

		// Scroll as much as possible into view, giving priorities
		// primarily to IP and secondarily ascents
		if(ySum > yHeightView)
		{
			yAscent = yHeightView;
			yDescent = 0;
			yAbove = 0;
			yBelow = 0;
		}
		else if((ySum += yDescent) > yHeightView)
		{
			yDescent = yHeightView - yAscent;
			yAbove = 0;
			yBelow = 0;
		}
		else if((ySum += yAbove) > yHeightView)
		{
			yAbove = yHeightView - (ySum - yAbove);
			yBelow = 0;
		}
		else if((ySum += yBelow) > yHeightView)
			yBelow = yHeightView - (ySum - yBelow);
	}
#ifdef DEBUG
	else
	{
		AssertSz(yAbove == 0, "yAbove non-zero");
		AssertSz(yBelow == 0, "yBelow non-zero");
	}
#endif


// Update real caret x pos (constant during vertical moves)

	_xCaretReally = _xCaret - rcView.left + xScroll;
	Assert(_xCaretReally >= 0);
	
	if(_xCaret + GetCaretDelta() > rcView.right && 	// Caret off right edge,
		!((dwScrollBars & ES_AUTOHSCROLL) ||		//  not auto hscrolling
		_pdp->IsHScrollEnabled()))					//  and no scrollbar:
	{												// Back caret up to
		_xCaret = rcView.right - dxCaret;			//  exactly the right edge
	}

	// From this point on we need a new caret
	_fCaretCreated = FALSE;

	if( ped->_fFocus)
		ped->TxShowCaret(FALSE);					// Hide old caret before
													//  making a new one
	if(yBase + yDescent + yBelow > yViewTop &&
		yBase - yAscent - yAbove < yViewBottom)
	{
		if(yBase - yAscent - yAbove < yViewTop)		// Caret is partially
		{											//  visible
			if(fAutoVScroll)						// Top isn't visible
				goto scrollit;
			Assert(yAbove == 0);

			yAscent = yBase - yViewTop;				// Change ascent to amount
			if(yBase < yViewTop)					//  visible
			{										// Move base to top
				yDescent += yAscent;
				yAscent = 0;
				yBase = yViewTop;
			}
		}
		if(yBase + yDescent + yBelow > yViewBottom)
		{
			if(fAutoVScroll)						// Bottom isn't visible
				goto scrollit;
			Assert(yBelow == 0);

			yDescent = yViewBottom - yBase;			// Change descent to amount
			if(yBase > yViewBottom)					//  visible
			{										// Move base to bottom
				yAscent += yDescent;
				yDescent = 0;
				yBase = yViewBottom;
			}
		}

		// Anything still visible?
		if(yAscent <= 0 && yDescent <= 0)
			goto not_visible;

		// If left or right isn't visible, scroll or set non_visible
		if (_xCaret <= rcView.left + CDisplay::GetXWidthSys() && xScroll // Left isn't visible
			|| _xCaret + GetCaretDelta() > rcView.right)	// Right isn't visible
		{
			if(fAutoHScroll)
				goto scrollit;
			goto not_visible;
		}

		_yCaret = yBase - yAscent;
		_yHeightCaret = (INT) yAscent + yDescent;
		_yCurrentDescent = yDescent;
	}
	else if(fAutoHScroll || fAutoVScroll)			// Caret isn't visible
		goto scrollit;								//  scroll it into view
	else
	{

not_visible:
		// Caret isn't visible, don't show it
		_xCaret = -32000;
		_yCaret = -32000;
		_yHeightCaret = 1;
	}

// Now update caret for real on screen

	// We only want to show the caret if it is in the view
	// and there is no selection.
	if((ped->_fFocus) && _fShowCaret && (0 == _cch))
	{
		CreateCaret();
		ped->TxShowCaret(TRUE);
		CheckChangeKeyboardLayout( FALSE );
	}

#ifdef DBCS
	UpdateIMEWindow();
	FSetIMEFontH(ped->_hwnd, AttGetFontHandle(ped, ped->_cpCaret));
#endif
	return FALSE;


scrollit:

	if(fAutoVScroll)
	{
		// Scroll to top for cp = 0. This is important if the first line
		// contains object(s) taller than the client area is high.	The
		// resulting behavior agrees with the Word UI in all ways except in
		// Backspacing (deleting) the char at cp = 0 when it is followed by
		// other chars that preceed the large object.
		if(!GetCp())											
			yScroll = 0;

		else if(yBase - yAscent - yAbove < yViewTop)			// Top invisible
			yScroll -= yViewTop - (yBase - yAscent - yAbove);	// Make it so

		else if(yBase + yDescent + yBelow > yViewBottom)		// Bottom invisible
		{
			yScroll += yBase + yDescent + yBelow - yViewBottom;	// Make it so

			// Don't do following special adjust if the current line is bigger
			// than the client area
			if(rp->_yHeight < yViewBottom - yViewTop)
			{
				yScroll = _pdp->AdjustToDisplayLastLine(yBase + rp->_yHeight, 
					yScroll);
			}
		}
	}
	if(fAutoHScroll)
	{
		if(_xCaret <= (rcView.left + CDisplay::GetXWidthSys()))	// Left invisible
		{
			xScroll -= rcView.left - _xCaret;				// Make it visible
			if(xScroll > 0)									// Scroll left in
			{												//  chunks to make
				xScroll -= xWidthView / 3;					//  typing faster
				xScroll = max(0, xScroll);
			}
		}
		else if(_xCaret + GetCaretDelta() > rcView.right)	// right invisible
			xScroll += _xCaret + dxCaret - rcView.left		// Make it visible
					- xWidthView;							// We don't scroll
															// in chunks because
															// this more edit 
															// control like.
					//- xWidthView * 2 / 3;					//  scrolling in
	}														//  chunks

	if(yScroll != _pdp->GetYScroll() || xScroll != _pdp->GetXScroll())
		return _pdp->ScrollView(xScroll, yScroll, FALSE, FALSE);

#ifdef DBCS
	VwUpdateIMEWindow(ped);
	FSetIMEFontH(ped->_hwnd, AttGetFontHandle(ped, ped->_cpCaret));
#endif

	return FALSE;
}

/*
 *	CTxtSelection::GetCaretHeight(pyDescent)
 *
 *	@mfunc
 *		Add a given amount to _xCaret (to make special case of inserting 
 *		a character nice and fast)
 *
 *	@rdesc
 *		Caret height, <lt> 0 if failed
 */
INT CTxtSelection::GetCaretHeight (
	INT *pyDescent) const		//@parm Out parm to receive caret descent
{
	TRACEBEGIN(TRCSUBSYSSEL, TRCSCOPEINTERN, "CTxtSelection::GetCaretHeight");
								// (undefined if the return value is <lt> 0)
	_TEST_INVARIANT_

	const CCharFormat *pcf = GetPed()->GetCharFormat(_iFormat);
	const CDevDesc *pdd = _pdp->GetDdRender();
	INT			CaretHeight = -1;
	HDC			hdc;
	CCcs *		pccs;

    if ((NULL == pdd) || (NULL == pcf))
        return CaretHeight;


 	hdc = pdd->GetDC();

	if(!hdc)
		return -1;

	pccs = fc().GetCcs(hdc, pcf, _pdp->GetZoomNumerator(),
		_pdp->GetZoomDenominator(), GetDeviceCaps(hdc, LOGPIXELSY));

	if(!pccs)
		goto ret;

	if(pyDescent)
		*pyDescent = (INT) pccs->_yDescent;

	CaretHeight = pccs->_yHeight;
	
	pccs->Release();

ret:

	pdd->ReleaseDC(hdc);

	return CaretHeight;
}

/*
 *	CTxtSelection::ShowCaret(fShow)
 *
 *	@mfunc
 *		Hide or show caret
 *
 *	@rdesc
 *		TRUE if caret was previously shown, FALSE if it was hidden
 */
BOOL CTxtSelection::ShowCaret (
	BOOL fShow)		//@parm TRUE for showing, FALSE for hiding
{
	TRACEBEGIN(TRCSUBSYSSEL, TRCSCOPEINTERN, "CTxtSelection::ShowCaret");

	_TEST_INVARIANT_

	const BOOL fRet = _fShowCaret;

	if(fRet != fShow)
	{
		_fShowCaret = fShow;

		if (GetPed()->_fFocus)
		{
			if (fShow && !_fCaretCreated)
			{
				CreateCaret();
			}

			GetPed()->TxShowCaret(fShow);
		}
	}

	return fRet;
}

/*
 *	CTxtSelection::IsCaretInView()
 *
 *	@mfunc
 *		Returns TRUE iff caret is inside visible view
 */
BOOL CTxtSelection::IsCaretInView() const
{
	TRACEBEGIN(TRCSUBSYSSEL, TRCSCOPEINTERN, "CTxtSelection::IsCaretInView");

	_TEST_INVARIANT_

	RECT rc;
	_pdp->GetViewRect(rc);
		
	return  (_xCaret + dxCaret		 > rc.left) &&
			(_xCaret				 < rc.right) &&
		   	(_yCaret + _yHeightCaret > rc.top) &&
			(_yCaret				 < rc.bottom);
}

/*
 *	CTxtSelection::CaretNotAtBOL()
 *
 *	@mfunc
 *		Returns TRUE iff caret is not allowed at BOL
 */
BOOL CTxtSelection::CaretNotAtBOL() const
{
	TRACEBEGIN(TRCSUBSYSSEL, TRCSCOPEINTERN, "CTxtSelection::CaretNotAtBOL");

	_TEST_INVARIANT_

	return _cch ? (_cch > 0) : _fCaretNotAtBOL;
}

/*
 *	CTxtSelection::LineLength()
 *
 *	@mfunc
 *		get # unselected chars on lines touched by current selection
 *
 *	@rdesc
 *		said number of chars
 */
LONG CTxtSelection::LineLength() const
{
	TRACEBEGIN(TRCSUBSYSSEL, TRCSCOPEINTERN, "CTxtSelection::LineLength");

	_TEST_INVARIANT_

	LONG cch;
	CLinePtr rp(_pdp);

	if(!_cch)								// Insertion point
	{
		rp.RpSetCp(GetCp(), _fCaretNotAtBOL);
		cch = rp.GetAdjustedLineLength();
	}
	else
	{

⌨️ 快捷键说明

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