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

📄 select.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		LONG cpMin, cpMost, cchLast;
		GetRange(cpMin, cpMost);
		rp.RpSetCp(cpMin, FALSE);		// Selections can't start at EOL
		cch = rp.RpGetIch();
		rp.RpSetCp(cpMost, TRUE);		// Selections can't end at BOL

		// now remove the trailing EOP (if it exists and isn't
		// already selected).
		cchLast = rp.GetAdjustedLineLength() - rp.RpGetIch();
		if( cchLast > 0 )
		{
			cch += cchLast;
		}
	}
	return cch;
}

/*
 *	CTxtSelection::ShowSelection(fShow)
 *
 *	@mfunc
 *		Update, hide or show selection on screen
 *
 *	@rdesc
 *		TRUE iff selection was previously shown
 */
BOOL CTxtSelection::ShowSelection (
	BOOL fShow)			//@parm TRUE for showing, FALSE for hiding
{
	TRACEBEGIN(TRCSUBSYSSEL, TRCSCOPEINTERN, "CTxtSelection::ShowSelection");

	_TEST_INVARIANT_

	const BOOL fShowPrev = _fShowSelection;
	const BOOL fInplaceActive = GetPed()->fInplaceActive();
	LONG cpSelSave = _cpSel;
	LONG cchSelSave = _cchSel;

	// Sleep(1000);
	_fShowSelection = fShow;

	if(fShowPrev && !fShow)
	{
		if(cchSelSave)			// Hide old selection
		{
			// Set up selection before telling the display to update
			_cpSel = 0;
			_cchSel = 0;

			if (fInplaceActive)
			{
				_pdp->InvertRange(cpSelSave, cchSelSave, selSetNormal);
			}
		}
	}
	else if(!fShowPrev && fShow)
	{
		if(_cch)								// Show new selection
		{
			// Set up selection before telling the display to update
			_cpSel = GetCp();
			_cchSel = _cch;

			if (fInplaceActive)
			{
				_pdp->InvertRange(GetCp(), _cch, selSetHiLite);
			}

		}
	}

	return fShowPrev;
}

/*
 *	CTxtSelection::UpdateSelection()
 *
 *	@mfunc
 *		Updates selection on screen 
 *
 *	Note:
 *		This method inverts the delta between old and new selections
 */
void CTxtSelection::UpdateSelection()
{
	TRACEBEGIN(TRCSUBSYSSEL, TRCSCOPEINTERN, "CTxtSelection::UpdateSelection");

	_TEST_INVARIANT_
	
	LONG	cp = GetCp();
	LONG	cpNA	= cp - _cch;
	LONG	cpSelNA = _cpSel - _cchSel;
	LONG 	cpMin, cpMost, cpMinSel, cpMostSel;
	CObjectMgr* pobjmgr = NULL;
	LONG	NumObjInSel = 0, NumObjInOldSel = 0;
	LONG	cpSelSave = _cpSel;
	LONG	cchSelSave = _cchSel;

	GetRange(cpMin, cpMost);

	//We need to know if there were objects is the previous and current
	//selections to determine how they should be selected.
	if (GetPed()->HasObjects())
	{
		pobjmgr = GetPed()->GetObjectMgr();
 
		if (pobjmgr)
		{
			CTxtRange	tr(GetPed(), _cpSel, _cchSel);

			tr.GetRange(cpMinSel, cpMostSel);
			NumObjInSel = pobjmgr->CountObjectsInRange(cpMin, cpMost);
			NumObjInOldSel = pobjmgr->CountObjectsInRange(cpMinSel, cpMostSel);
		}
	}

	//If the old selection contained a single object and nothing else
	//we need to notify the object manager that this is no longer the
	//case if the selection is changing.
	if (NumObjInOldSel && (abs(_cchSel) == 1) &&
		!(cpMin == cpMinSel && cpMost == cpMostSel))
	{
		if (pobjmgr)
		{
			pobjmgr->HandleSingleSelect(GetPed(), cpMinSel, /* fHilite */ FALSE);
		}
	}

	// Update selection data before the invert so the selection can be
	// painted by the render
	_cpSel  = GetCp();
	_cchSel = _cch;

	if( _fShowSelection )
	{
		if( !_cch || !cchSelSave ||				// Old/new selection missing,
			cpMost < min(cpSelSave, cpSelNA) ||	//  or new preceeds old,
			cpMin  > max(cpSelSave, cpSelNA))	//  or new follows old, so
		{										//  they don't intersect
			if(_cch)
				_pdp->InvertRange(cp, _cch, selSetHiLite);
			if(cchSelSave)
				_pdp->InvertRange(cpSelSave, cchSelSave, selSetNormal);
		}
		else
		{
			if(cpNA != cpSelNA)					// Old & new dead ends differ
			{									// Invert text between them
				_pdp->InvertRange(cpNA, cpNA - cpSelNA, selUpdateNormal);
			}
			if(cp != cpSelSave)					// Old & new active ends differ
			{									// Invert text between them
				_pdp->InvertRange(cp, cp - cpSelSave, selUpdateHiLite);
			}
		}
	}

	//If the new selection contains a single object and nothing else
	//we need to notify the object manager as long as it's not the same
	//object.
	if (NumObjInSel && (abs(_cch) == 1) &&
		!(cpMin == cpMinSel && cpMost == cpMostSel))
	{
		if (pobjmgr)
		{
			pobjmgr->HandleSingleSelect(GetPed(), cpMin, /* fHiLite */ TRUE);
		}
	}
}

/*
 * 	CTxtSelection::SetSelection(cpFirst, cpMost)
 *
 *	@mfunc
 *		Set selection between two cp's
 *	
 *	@devnote
 *		<p cpFirst> and <p cpMost> must be greater than 0, but may extend
 *		past the current max cp.  In that case, the cp will be truncated to
 *		the max cp (at the end of the text).	
 */
void CTxtSelection::SetSelection (
	LONG cpMin,				//@parm Start of selection and dead end
	LONG cpMost)			//@parm End of selection and active end
{
	TRACEBEGIN(TRCSUBSYSSEL, TRCSCOPEINTERN, "CTxtSelection::SetSelection");

	_TEST_INVARIANT_

	StopGroupTyping();

	_fCaretNotAtBOL = FALSE;			// Put caret for ambiguous cp at BOL
	Set(cpMost, cpMost - cpMin);		// Set() validates cpMin, cpMost

	if (GetPed()->fInplaceActive())
	{
		// Inplace active - update the selection now.
		Update(TRUE);
	}
	else
	{
		// Update the selection data used for screen display
		// so whenever we get displayed the selection will be
		// displayed.
		_cpSel  = GetCp();
		_cchSel = _cch;	

		if (!GetPed()->fHideSelection())
		{
			// Selection is not hidden so tell container to 
			// update the display when it feels like.
        	GetPed()->TxInvalidateRect(NULL, FALSE);
			GetPed()->TxUpdateWindow();
		}
	}

	CancelModes();						// Cancel word selection mode
}

/*
 *	CTxtSelection::PointInSel(pt, prcClient)
 *
 *	@mfunc
 *		Figures whether a given point is within the selection
 *
 *	@rdesc
 *		TRUE if point inside selection, FALSE otherwise
 */
BOOL CTxtSelection::PointInSel (
	const POINT pt,			//@parm Point in containing window client coords
	const RECT *prcClient,	//@parm Client rectangle can be NULL if active
	HITTEST		Hit) const	//@parm Possibly computer Hit value
	
{
	TRACEBEGIN(TRCSUBSYSSEL, TRCSCOPEINTERN, "CTxtSelection::PointInSel");

	LONG	cp;
	LONG	cpMin,  cpMost;
	POINT	temppt;
	CRchTxtPtr	rtp(GetPed(), 0);

	_TEST_INVARIANT_

	if (!_cch || Hit && Hit < HT_Text)	// Degenerate range (no selection):
		return FALSE;					//  mouse can't be in, or Hit not
										//  in text
	cp = _pdp->CpFromPoint(pt, prcClient, NULL, NULL, FALSE, &Hit);

	if(Hit < HT_Text)
		return FALSE;

	GetRange(cpMin, cpMost);

	// we have to test boundary cases separately--we want to make
	// sure the point is in the bounding box of the selection, but cp
	// from point will artificially extend that bounding box to half of
	// the next/previous character.  Think of it this way, when you click
	// in the middle of a character, the insertion point has to go
	// somewhere to the left or the right.
	if( cp > cpMin && cp < cpMost )
	{
		return TRUE;
	}
	else if( cp == cpMin )
	{
		rtp.SetCp(cp);
		_pdp->PointFromTp(rtp, prcClient, FALSE, temppt, NULL, TA_TOP);

		if( pt.x >= temppt.x )
		{
			return TRUE;
		}
	}
	else if( cp == cpMost )
	{
		rtp.SetCp(cp);
		_pdp->PointFromTp(rtp, prcClient, TRUE, temppt, NULL, TA_TOP);

		if( pt.x <= temppt.x )
		{
			return TRUE;
		}
	}

	return FALSE;
}

//////////////////////////////////  Selection with the mouse  ///////////////////////////////////

/*
 * 	CTxtSelection::SetCaret(pt, fUpdate)
 *
 *	@mfunc
 *		Sets caret at a given point
 *
 *	@devnote
 *		In the plain-text case, placing the caret at the beginning of the
 *		line following the final EOP requires some extra code, since the
 *		underlying rich-text engine doesn't assign a line to a final EOP
 *		(plain-text doesn't currently have the rich-text final EOP).  We
 *		handle this by checking to see if the count of lines times the
 *		plain-text line height is below the actual y position.  If so, we
 *		move the cp to the end of the story.
 */
void CTxtSelection::SetCaret(
	const POINT pt,		//@parm Point of click
	BOOL fUpdate)		//@parm If TRUE, update the selection/caret
{
	TRACEBEGIN(TRCSUBSYSSEL, TRCSCOPEINTERN, "CTxtSelection::SetCaret");

	_TEST_INVARIANT_

	LONG		cp;
    RECT		rcView;
	CLinePtr	rp(_pdp);
	CRchTxtPtr  rtp(GetPed());
	LONG		y;

	StopGroupTyping();

	// Set caret at point
	if (_pdp->CpFromPoint(pt, NULL, &rtp, &rp, FALSE) >= 0)
	{
		// Set the selection to the correct location.  If plain-text
		// multiline control, we need to check to see if pt.y is below
		// the last line of text.  If so and if the text ends with an EOP,
		// we need to set the cp at the end of the story and set up to
		// display the caret at the beginning of the line below the last
		// line of text
		cp = rtp.GetCp();
		if (!GetPed()->IsRich() &&					// Plain-text,
			GetPed()->TxGetMultiLine())				//  multiline control
		{
			_pdp->GetViewRect(rcView, NULL);
			y = pt.y + _pdp->GetYScroll() - rcView.top;
													
			if(y > (LONG)rp.Count()*rp->_yHeight)	// Below last line of
			{										//  text
				rtp.Advance(tomForward);			// Move rtp to end of text
				if(rtp._rpTX.IsAfterEOP())			// If text ends with an
				{									//  EOP, set up to move
					cp = rtp.GetCp();				//  selection there
					rp.AdvanceCp(-(LONG)rp.GetIch());// Set rp._ich = 0 to
				}									//  set _fCaretNotAtBOL
			}										//  = FALSE to display
		}											//  caret at next BOL


#ifndef TARGET_NT
		// GuyBark JupiterJ IME:
		// We must take action to ensure the ime knows the caret's moved.

		if(GetPed()->IsIMEComposition())
		{
		    // Select another clause if necessary. If we do highlight 
		    // another clause, then don't set the IME caret position.
		    // Otherwise the IME caret setting action interferes with
		    // the clause highlighting.

		    if(SetIMEHighlight(&cp, pt, &rtp))
		    {
		        // Didn't highlight another clause. We may freeze the 
		        // display beneath here, until we've finished walking 
		        // the caret if we need to.
		        SetIMECaret(&cp);

		        // Store the final caret cp here, so we can move any candidate
		        // list to that position if necessary later.
		        _pdp->PointFromTp(rtp, NULL, FALSE, GetPed()->_ime->_pt, NULL, TA_TOP);
		    }
		}
#endif // !TARGET_NT

		Set(cp, 0);

		_fCaretNotAtBOL = rp.RpGetIch() != 0;	// Caret OK at BOL if click
		if(fUpdate)
			Update(TRUE);
		else
			UpdateForAutoWord();

		_SelMode = smNone;						// Cancel word selection mode
	}
}

#ifndef TARGET_NT
/*
 *  CTxtSelection::SetIMECaret(pcpNew)
 *
 *  GUYBARK ADD THIS!
 *
 *  Without this, RichEdit know the caret's moved, but the ime doesn't.
 *
 *  Returns FALSE if no errors, else TRUE
 */
BOOL CTxtSelection::SetIMECaret(LONG *pcpNew)
{
    LONG cpMin, cpMost, cpMove, cpUndeterminedStart, cchUndetermined;
    UINT vkCode;
    HWND hWndRE;
    UINT nShift;
    UINT chCode;
    CTxtEdit *ped;

    if(!pcpNew || !(ped = GetPed()))
    {
        return TRUE;
    }

    // Don't do anything here if we're not in undetermined text.
    if(!ped->IsIMEComposition())
    {
        // No errors.
        return FALSE;
    }

    // Get the current cp.
    GetRange(cpMin, cpMost);

    // Force the caret to stay in the undetermined text.
    if(ped->_ime->GetUndeterminedInfo((INT*)&cpUndeterminedStart, (INT*)&cchUndetermined))
    {
        return TRUE;
    }

    if(*pcpNew < cpUndeterminedStart)
    {
        *pcpNew = cpUndeterminedStart;
    }
    else if(*pcpNew > cpUndeterminedStart + cchUndetermined)
    {
        *pcpNew = cpUndeterminedStart + cchUndetermined;
    }

    // Get the offset to the new caret position.
    cpMove = *pcpNew - cpMin;

    // Is the caret moving left or right?
    vkCode = cpMove < 0 ? VK_LEFT : VK_RIGHT;

    // Get the RichEdit window handle.
    if(ped->TxGetWindow(&hWndRE) != NOERROR)
    {
        return TRUE;
    }

    // Don't need to do anything if the user's tapped where the caret already sits.
    if(cpMove != 0)
    {
        HIMC hIMC = ped->TxImmGetContext();

        if(!hIMC || !ImmEscape((HKL)NULL, hIMC, IME_ESC_SETCURSOR, (LPVOID)cpMove))
        {
            // Now loop through as though the user pressed the arrow keys.
            cpMove = abs(cpMove);

            // Freeze the display to stop the caret running around. This
            // gets thawed later when we process the last key up.
            _pdp->Freeze();

            ped->_fDisplayFrozen = TRUE;

            for(; cpMove > 0; cpMove-- )
            {

⌨️ 快捷键说明

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