📄 runptr.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*
* @doc INTERNAL
*
* @module RUNPTR.C -- Text run and run pointer class |
*
* Original Authors: <nl>
* Original RichEdit code: David R. Fulmer
* Christian Fortini
* Murray Sargent
*
* History: <nl>
* 6/25/95 alexgo Commented and Cleaned up.
*/
#include "_common.h"
#include "_runptr.h"
#include "_text.h"
ASSERTDATA
//
// Invariant stuff
//
#define DEBUG_CLASSNAME CRunPtrBase
#include "_invar.h"
// =========================== CRunPtrBase class ==================================================
#ifdef DEBUG
/*
* CRunPtrBase::Invariant()
*
* @mfunc
* Debug-only function that validates the internal state consistency
* for CRunPtrBase
*
* @rdesc
* TRUE always (failures assert)
*/
BOOL CRunPtrBase::Invariant() const
{
if( _prgRun == NULL )
{
Assert(_iRun == 0);
// we let ich zoom around a conceptual
// run so it can stay in sync with a text pointer
Assert(_ich >= 0);
return TRUE;
}
if(!_prgRun->Count())
{
Assert(_iRun == 0);
// we let ich zoom around a conceptual
// run so it can stay in sync with a text pointer
Assert(_ich >= 0);
}
else
{
Assert(_iRun < _prgRun->Count() );
Assert(_ich <= _prgRun->Elem(_iRun)->_cch);
}
return TRUE;
}
/*
* CRunPtrBase::ValidatePtr(pRun)
*
* @mfunc
* Debug-only validation method that asserts if pRun doesn't point to a
* valid text run
*/
void CRunPtrBase::ValidatePtr(void *pRun) const
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CRunPtrBase::ValidatePtr");
AssertSz(pRun >= _prgRun->Elem(0) &&
pRun <= _prgRun->Elem(Count() - 1),
"CRunPtr::ValidatePtr: illegal ptr");
}
/*
* CRunPtrBase::GetCch()
*
* @mfunc
* Calculate length of text by summing text runs accessible by this
* run ptr
*
* @rdesc
* length of text so calculated, or -1 if failed
*/
DWORD CRunPtrBase::GetCch() const
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CRunPtrBase::GetCch");
DWORD cch;
DWORD iRun;
DWORD cchText = 0;
AssertSz(_prgRun, "CTxtPtr::GetCch() - Invalid operation on single run CRunPtr");
for(iRun = Count(); iRun && iRun--; )
{
cch = _prgRun->Elem(iRun)->_cch;
AssertSz(cch,
"CRunPtrBase::GetCch(): zero-length run");
cchText += cch;
}
return cchText;
}
#endif
/*
* CRunPtrBase::GetCchLeft()
*
* @mfunc
* Calculate length of text left in run starting at the current cp.
* Complements GetIch(), which is length of text up to this cp.
*
* @rdesc
* length of text so calculated
*/
DWORD CRunPtrBase::GetCchLeft() const
{
return GetRun(0)->_cch - GetIch();
}
/*
* CRunPtrBase::CRunPtrBase(prgRun)
*
* @mfunc constructor
*/
CRunPtrBase::CRunPtrBase(
CRunArray *prgRun) //@parm The Run array for the run ptr
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CRunPtrBase::CRunPtrBase");
_prgRun = prgRun;
_iRun = 0;
_ich = 0;
//make sure everything has been initialized
Assert(sizeof(CRunPtrBase) == (sizeof(_prgRun) + sizeof(_iRun)
+ sizeof(_ich)));
}
/*
* CRunPtrBase::CRunPtrBase(rp)
*
* Copy Constructor
*/
CRunPtrBase::CRunPtrBase(
CRunPtrBase& rp) //@parm the other pointer to initialize from
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CRunPtrBase::CRunPtrBase");
*this = rp;
}
/*
* CRunPtrBase::SetRun(iRun, ich)
*
* @mfunc
* Sets this run ptr to the given run. If it does not
* exist, then we set ourselves to the closest valid run
*
* @rdesc
* TRUE if moved to iRun
*/
BOOL CRunPtrBase::SetRun(
LONG iRun, //@parm Run index to use (must be LONG)
DWORD ich) //@parm Char index within run to use
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CRunPtrBase::SetRun");
_TEST_INVARIANT_
BOOL bRet = TRUE;
LONG count = Count();
CTxtRun *pRun;
// Set the run
if( !_prgRun ) // No text-run array:
return FALSE; // leave this rp alone
if( iRun >= count ) // Validate iRun
{
bRet = FALSE;
iRun = count - 1; // If (!count), negative iRun
} // is handled by following if
if (iRun < 0)
{
bRet = FALSE;
iRun = 0;
}
_iRun = iRun;
// Set the offset
pRun = _prgRun->Elem(iRun);
if( pRun )
_ich = min(ich, pRun->_cch);
return bRet;
}
/*
* CRunPtrBase::NextRun()
*
* @mfunc
* Change this RunPtr to that for the next text run
*
* @rdesc
* TRUE if succeeds, i.e., target run exists
*/
BOOL CRunPtrBase::NextRun()
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CRunPtrBase::NextRun");
_TEST_INVARIANT_
if( _prgRun )
{
if (_iRun < Count() - 1)
{
++_iRun;
_ich = 0;
return TRUE;
}
}
return FALSE;
}
/*
* CRunPtrBase::PrevRun()
*
* @mfunc
* Change this RunPtr to that for the previous text run
*
* @rdesc
* TRUE if succeeds, i.e., target run exists
*/
BOOL CRunPtrBase::PrevRun()
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CRunPtrBase::PrevRun");
_TEST_INVARIANT_
if( _prgRun )
{
_ich = 0;
if (_iRun > 0)
{
_iRun--;
return TRUE;
}
}
return FALSE;
}
/*
* CRunPtrBase::GetRun(cRun)
*
* @mfunc
* Get address of the TxtRun that is cRun runs away from the run
* pointed to by this RunPtr
*
* @rdesc
* ptr to the CTxtRun cRun's away
*/
CTxtRun* CRunPtrBase::GetRun(
LONG cRun) const //@parm signed count of runs to reach target CTxtRun
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CRunPtrBase::GetRun");
_TEST_INVARIANT_
Assert(_prgRun); // Common problem...
return _prgRun->Elem(_iRun + cRun);
}
/*
* CRunPtrBase::GetCp()
*
* @mfunc
* Get cp of this RunPtr
*
* @rdesc
* cp of this RunPtr
*
* @devnote
* May be computationally expensive if there are many elements
* in the array (we have to run through them all to sum cch's.
* Used by TOM collections and Move commands, so needs to be fast.
*/
DWORD CRunPtrBase::GetCp () const
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CRunPtrBase::GetCp");
DWORD cb;
DWORD cp = _ich; // Correct result if _iRun = 0
DWORD iRun = _iRun;
CTxtRun * pRun;
_TEST_INVARIANT_
if( _prgRun && iRun )
{
cb = _prgRun->Size();
pRun = GetRun(-1);
while(iRun--)
{
Assert(pRun);
cp += pRun->_cch;
pRun = (CTxtRun *)((BYTE *)pRun - cb);
}
}
return cp;
}
/*
* CRunPtrBase::BindToCp(cp)
*
* @mfunc
* Set this RunPtr to correspond to a cp.
*
* @rdesc
* the cp actually set to
*/
DWORD CRunPtrBase::BindToCp(
DWORD cp) //@parm character position to move this RunPtr to
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CRunPtrBase::BindToCp");
_iRun = 0;
_ich = 0;
return AdvanceCp(cp);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -