📄 select.cpp
字号:
&& !_fAutoSelectAborted
&& (cp < _cpWordMin || cp > _cpWordMost);
if(_fInAutoWordSel && !fWasInAutoWordSel)
{
CTxtPtr txtptr(GetPed(), _cpAnchor);
// Extend both ends dead to word boundaries
ExtendToWordBreak(fAfterEOP,
_cch < 0 ? WB_MOVEWORDLEFT : WB_MOVEWORDRIGHT);
if (_cch < 0)
{
// Direction is left so update word border on left
_cpWordPrev = _cpWordMin;
_cpWordMin = GetCp();
}
else
{
// Direction is right so update word border on right
_cpWordPrev = _cpWordMost;
_cpWordMost = GetCp();
}
//If we are at the beginning of a word already, we don't
//need to extend the selection in the other direction.
if (!txtptr.IsAtBOWord() && txtptr.GetChar() != ' ')
{
FlipRange();
// start extending from the anchor
Advance(_cpAnchor - GetCp());
FindWordBreak(_cch < 0 ? WB_MOVEWORDLEFT : WB_MOVEWORDRIGHT);
if (_cch > 0)
{
// Direction is right so update word border on right
_cpWordMost = GetCp();
}
else
{
// Direction is left so update word border on left
_cpWordMin = GetCp();
}
FlipRange();
}
}
else if(_fInAutoWordSel || _SelMode == smWord)
{
// Save direction
iDir = cp <= _cpWordMin ? WB_MOVEWORDLEFT : WB_MOVEWORDRIGHT;
// Extend selection by word
if (_SelMode == smWord)
{
if(cp > _cpAnchorMost || cp < _cpAnchorMin)
FindWordBreak(iDir);
else
Set(_cpAnchorMin, _cpAnchorMin - _cpAnchorMost);
}
else
{
ExtendToWordBreak(fAfterEOP, iDir);
}
if (_fInAutoWordSel)
{
if (WB_MOVEWORDLEFT == iDir)
{
// Direction is left so update word border on left
_cpWordPrev = _cpWordMin;
_cpWordMin = GetCp();
}
else
{
// Direction is right so update word border on right
_cpWordPrev = _cpWordMost;
_cpWordMost = GetCp();
}
}
}
else if(fWasInAutoWordSel)
{
// If we are in between where the previous word ended and
// the cp we auto selected to, then we want to stay in
// auto select mode.
if (_cch < 0)
{
if (cp >= _cpWordMin && cp < _cpWordPrev)
{
// Set direction for end of word search
iDir = WB_MOVEWORDLEFT;
// Mark that we are still in auto select mode
_fInAutoWordSel = TRUE;
}
}
else if (cp <= _cpWordMost && cp >= _cpWordPrev)
{
// Mark that we are still in auto select mode
_fInAutoWordSel = TRUE;
// Set direction for end of word search
iDir = WB_MOVEWORDRIGHT;
}
//We have to check to see if we are on the boundary between
//words because we don't want to extend the selection until
//we are actually beyond the current word.
if (cp != _cpWordMost && cp != _cpWordMin)
{
if (_fInAutoWordSel)
{
// Auto selection still on so make sure we have the
// entire word we are on selected
ExtendToWordBreak(fAfterEOP, iDir);
}
else
{
// FUTURE: Word has a behavior where it extends the
// selection one word at a time unless you back up
// and then start extending the selection again, in
// which case it extends one char at a time. We
// follow this behavior. However, Word will resume
// extending a word at a time if you continue extending
// for several words. We just keep extending on char
// at a time. We might want to change this sometime.
_fAutoSelectAborted = TRUE;
}
}
}
if (_fAutoSelectAborted)
{
// If we are in the range of a word we previously selected
// we want to leave that selected. If we have moved back
// a word we want to pop back an entire word. Otherwise,
// leave the cp were it is.
if (_cch < 0)
{
if (cp > _cpWordMin && cp < _cpWordPrev)
{
// In the range leave the range at the beginning of the word
ExtendToWordBreak(fAfterEOP, WB_MOVEWORDLEFT);
}
else if (cp >= _cpWordPrev)
{
AutoSelGoBackWord(&_cpWordMin,
WB_MOVEWORDRIGHT, WB_MOVEWORDLEFT);
}
}
else if (cp < _cpWordMost && cp >= _cpWordPrev)
{
// In the range leave the range at the beginning of the word
ExtendToWordBreak(fAfterEOP, WB_MOVEWORDRIGHT);
}
else if (cp < _cpWordPrev)
{
AutoSelGoBackWord(&_cpWordMost,
WB_MOVEWORDLEFT, WB_MOVEWORDRIGHT);
}
}
}
// Save the current state of the _fCaretNotAtBOL flag since it affects a
// a number of places.
BOOL fCaretNotAtBOLSave = _fCaretNotAtBOL;
// Is the selection at the beginning of the line?
if (rp.RpGetIch() == 0)
{
_fCaretNotAtBOL = FALSE;
}
// Restore the flag to its original state.
_fCaretNotAtBOL = fCaretNotAtBOLSave;
// An OLE object cannot have an anchor point <b> inside </b> it,
// but sometimes we'd like it to behave like a word. So, if
// the direction changed, the object has to stay selected --
// this is the "right thing" (kind of word selection mode)
// if we had something selected and the direction changed
if (cchPrev && (_cch ^ cchPrev) < 0)
{
FlipRange();
// see if an object was selected on the other end
BOOL fObjectWasSelected = (_cch > 0 ? _rpTX.GetChar()
: _rpTX.GetPrevChar()) == WCH_EMBEDDING;
// if it was, we want it to stay selected
if (fObjectWasSelected)
Advance(_cch > 0 ? 1 : -1);
FlipRange();
}
Update(TRUE);
}
/*
* CTxtSelection::ExtendToWordBreak (fAfterEOP, iAction)
*
* @mfunc
* Moves active end of selection to the word break in the direction
* given by iDir unless fAfterEOP = TRUE. When this is TRUE, the
* cursor just follows an EOP marker and selection should be suppressed.
* Otherwise moving the cursor to the left of the left margin would
* select the EOP on the line above, and moving the cursor to the
* right of the right margin would select the first word in the line
* below.
*/
void CTxtSelection::ExtendToWordBreak (
BOOL fAfterEOP, //@parm Cursor is after an EOP
INT iAction) //@parm Word break action (WB_MOVEWORDRIGHT/LEFT)
{
if(!fAfterEOP)
FindWordBreak(iAction);
}
/*
* CTxtSelection::CancelModes(fAutoWordSel)
*
* @mfunc
* Cancel either all modes or Auto Select Word mode only
*/
void CTxtSelection::CancelModes (
BOOL fAutoWordSel) //@parm TRUE cancels Auto Select Word mode only
{ // FALSE cancels word, line and para sel mode
TRACEBEGIN(TRCSUBSYSSEL, TRCSCOPEINTERN, "CTxtSelection::CancelModes");
_TEST_INVARIANT_
if(fAutoWordSel)
{
if(_fInAutoWordSel)
{
_fInAutoWordSel = FALSE;
_fAutoSelectAborted = FALSE;
}
}
else
_SelMode = smNone;
}
/////////////////////////////////// Keyboard movements ////////////////////////////////////
/*
* CTxtSelection::Left(fCtrl)
*
* @mfunc
* do what cursor-keypad left-arrow key is supposed to do
*
* @rdesc
* TRUE iff movement occurred
*
* @comm
* Left/Right-arrow IPs can go to within one character (treating CRLF
* as a character) of EOL. They can never be at the actual EOL, so
* _fCaretNotAtBOL is always FALSE for these cases. This includes
* the case with a right-arrow collapsing a selection that goes to
* the EOL, i.e, the caret ends up at the next BOL. Furthermore,
* these cases don't care whether the initial caret position is at
* the EOL or the BOL of the next line. All other cursor keypad
* commands may care.
*
* @devnote
* _fExtend is TRUE iff Shift key is pressed or being simulated
*/
BOOL CTxtSelection::Left (
BOOL fCtrl) //@parm TRUE iff Ctrl key is pressed (or being simulated)
{
TRACEBEGIN(TRCSUBSYSSEL, TRCSCOPEINTERN, "CTxtSelection::Left");
_TEST_INVARIANT_
LONG cp;
CancelModes();
StopGroupTyping();
if(!_fExtend && _cch) // Collapse selection to
{ // nearest whole Unit before
if(fCtrl) // cpMin
Expander(tomWord, FALSE, NULL, &cp, NULL);
Collapser(tomStart); // Collapse to cpMin
}
else // Not collapsing selection
{
if (!GetCp() || // Already at beginning of
!BypassHiddenText(tomBackward)) // story
{
Beep();
return FALSE;
}
if(IsInOutlineView() && (_fSelHasEOP || // If outline view with EOP
_fExtend && _rpTX.IsAfterEOP())) // now or will have after
{ // this command,
return Up(FALSE); // treat as up arrow
}
if(fCtrl) // WordLeft
FindWordBreak(WB_MOVEWORDLEFT);
else // CharLeft
BackupCRLF();
}
_fCaretNotAtBOL = FALSE; // Caret always OK at BOL
Update(TRUE);
return TRUE;
}
/*
* CTxtSelection::Right(fCtrl)
*
* @mfunc
* do what cursor-keypad right-arrow key is supposed to do
*
* @rdesc
* TRUE iff movement occurred
*
* @comm
* Right-arrow selection can go to the EOL, but the cp of the other
* end identifies whether the selection ends at the EOL or starts at
* the beginning of the next line. Hence here and in general for
* selections, _fCaretNotAtBOL is not needed to resolve EOL/BOL
* ambiguities. It should be set to FALSE to get the correct
* collapse character. See also comments for Left() above.
*
* @devnote
* _fExtend is TRUE iff Shift key is pressed or being simulated
*/
BOOL CTxtSelection::Right (
BOOL fCtrl) //@parm TRUE iff Ctrl key is pressed (or being simulated)
{
TRACEBEGIN(TRCSUBSYSSEL, TRCSCOPEINTERN, "CTxtSelection::Right");
_TEST_INVARIANT_
LONG cchText;
LONG cp;
CancelModes();
StopGroupTyping();
if(!_fExtend && _cch) // Collapse selection to
{ // nearest whole Unit after
if(fCtrl) // cpMost
Expander(tomWord, FALSE, NULL, NULL, &cp);
Collapser(tomEnd);
}
else // Not collapsing selection
{
cchText = _fExtend ? GetTextLength() : GetAdjustedTextLength();
if (GetCp() >= cchText || // Already at end of story
!BypassHiddenText(tomForward))
{
Beep(); // Tell the user
return FALSE;
}
if(IsInOutlineView() && _fSelHasEOP) // If outline view with EOP,
return Down(FALSE); // treat as down arrow
if(fCtrl) // WordRight
FindWordBreak(WB_MOVEWORDRIGHT);
else // CharRight
AdvanceCRLF();
}
_fCaretNotAtBOL = _fExtend; // If extending to EOL, need
Update(TRUE); // TRUE to get _xCaretReally
return TRUE; // at EOL
}
/*
* CTxtSelection::Up(fCtrl)
*
* @mfunc
* do what cursor-keypad up-arrow key is supposed to do
*
* @rdesc
* TRUE iff movement occurred
*
* @comm
* Up arrow doesn't go to EOL regardless of _xCaretPosition (stays
* to left of EOL break character), so _fCaretNotAtBOL is always FALSE
* for Up arrow. Ctrl-Up/Down arrows always end up at BOPs or the EOD.
*
* @devnote
* _fExtend is TRUE iff Shift key is pressed or being simulated
*/
BOOL CTxtSelection::Up (
BOOL fCtrl) //@parm TRUE iff Ctrl key is pressed (or being simulated)
{
TRACEBEGIN(TRCSUBSYSSEL, TRCSCOPEINTERN, "CTxtSelection::Up");
_TEST_INVARIANT_
LONG cchSave = _cch; // Save starting position for
LONG cpSave = GetCp(); // change check
BOOL fCollapse = _cch && !_fExtend; // Collapse nondegenerate sel
BOOL fPTNotAtEnd;
CLinePtr rp(_pdp);
LONG xCaretReally = _xCaretReally; // Save desired caret x pos
CancelModes();
StopGroupTyping();
if(fCollapse) // Collapse selection at cpMin
{
Collapser(tomTrue);
_fCaretNotAtBOL = FALSE; // Selections can't begin at
} // EOL
rp.RpSetCp(GetCp(), _fCaretNotAtBOL); // Initialize line ptr
if(fCtrl) // Move to beginning of para
{
if(!fCollapse && // If no selection collapsed
rp > 0 && !rp.RpGetIch()) // and are at BOL,
{ // backup to prev BOL to make
rp--; // sure we move to prev. para
Advance(-(LONG)rp->_cch);
}
Advance(rp.FindParagraph(FALSE)); // Go to beginning of para
_fCaretNotAtBOL = FALSE; // Caret always OK at BOL
}
else // Move up a line
{ // If on first line, can't go
fPTNotAtEnd = !CheckPlainTextFinalEOP();// up
if(rp <= 0 && fPTNotAtEnd) // (Don't use !rp, which means
{ // rp that's out of range)
if(!_fExtend)// &&_pdp->GetYScroll())
UpdateCaret(TRUE); // Be sure caret in view
}
else
{
LONG cch;
BOOL fSelHasEOPInOV = IsInOutlineView() && _fSelHasEOP;
if(fSelHasEOPInOV && _cch > 0)
{
rp.AdjustBackward();
cch = rp->_cch;
rp.AdvanceCp(-cch); // Go to start of line
Assert(!rp.GetIch());
cch -= rp.FindParagraph(FALSE); // Be sure that's the start
} // of para in case of wrap
else
{
cch = 0;
if(fPTNotAtEnd)
{
cch = rp.RpGetIch();
rp--;
}
cch += rp->_cch;
}
Advance(-cch); // Move to previous BOL
if (fSelHasEOPInOV && !_fSelHasEOP) // If sel had EOP but doesn't
{ // after Advance, must be IP
Assert(!_cch); // Suppress restore of
xCaretReally = -1; // _xCaretReally
}
else if(!SetXPosition(xCaretR
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -