📄 doc.cpp
字号:
{
Assert(Elem(itb) != NULL);
Elem(itb++)->FreeBlock();
}
Remove(itbFirst, ctbDel, AF_KEEPMEM);
}
/*
* CTxtArray::CombineBlocks(itb)
*
* @mfunc combine adjacent text blocks
*
* @rdesc
* nothing
*
* @comm
* Side Effects: <nl>
* moves text block array
*
* @devnote
* scans blocks from itb - 1 through itb + 1 trying to combine
* adjacent blocks
*/
void CTxtArray::CombineBlocks(
DWORD itb) //@parm index of the first block modified
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtArray::CombineBlocks");
_TEST_INVARIANT_
DWORD ctb;
DWORD cbT;
CTxtBlk *ptb, *ptb1;
if(itb > 0)
itb--;
ctb = min(3, Count() - itb);
if(ctb <= 1)
return;
for(; ctb > 1; ctb--)
{
ptb = Elem(itb); // Can we combine current
ptb1 = Elem(itb+1); // and next blocks ?
cbT = CbOfCch(ptb->_cch + ptb1->_cch + cchGapInitial);
if(cbT <= cbBlockInitial)
{ // Yes
if(cbT != ptb->_cbBlock && !ptb->ResizeBlock(cbT))
continue;
ptb ->MoveGap(ptb->_cch); // Move gaps at ends of
ptb1->MoveGap(ptb1->_cch); // both blocks
CopyMemory(ptb->_pch + ptb->_cch, // Copy next block text
ptb1->_pch, CbOfCch(ptb1->_cch)); // into current block
ptb->_cch += ptb1->_cch;
ptb->_ibGap += CbOfCch(ptb1->_cch);
RemoveBlocks(itb+1, 1); // Remove next block
}
else
itb++;
}
}
/*
* CTxtArray::GetChunk(ppch, cch, pchChunk, cchCopy)
*
* @mfunc
* Get content of text chunk in this text array into a string
*
* @rdesc
* remaining count of characters to get
*/
LONG CTxtArray::GetChunk(
TCHAR **ppch, //@parm ptr to ptr to buffer to copy text chunk into
DWORD cch, //@parm length of pch buffer
TCHAR *pchChunk, //@parm ptr to text chunk
DWORD cchCopy) const //@parm count of characters in chunk
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtArray::GetChunk");
_TEST_INVARIANT_
if(cch > 0 && cchCopy > 0)
{
if(cch < cchCopy)
cchCopy = cch; // Copy less than full chunk
CopyMemory(*ppch, pchChunk, cchCopy*sizeof(TCHAR));
*ppch += cchCopy; // Adjust target buffer ptr
cch -= cchCopy; // Fewer chars to copy
}
return cch; // Remaining count to copy
}
// ======================== CTxtBlk class =================================
/*
* CTxtBlk::InitBlock(cb)
*
* @mfunc
* Initialize this text block
*
* @rdesc
* TRUE if success, FALSE if allocation failed
*/
BOOL CTxtBlk::InitBlock(
DWORD cb) //@parm initial size of the text block
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtBlk::InitBlock");
_pch = NULL;
_cch = 0;
_ibGap = 0;
_cbBlock= cb;
if (cb)
_pch = (TCHAR*)PvAlloc(cb, GMEM_ZEROINIT);
return _pch != 0;
}
/*
* CTxtBlk::FreeBlock()
*
* @mfunc
* Free this text block
*
* @rdesc
* nothing
*/
VOID CTxtBlk::FreeBlock()
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtBlk::FreeBlock");
FreePv(_pch);
_pch = NULL;
_cch = 0;
_ibGap = 0;
_cbBlock= 0;
}
/*
* CTxtBlk::MoveGap(ichGap)
*
* @mfunc
* move gap in this text block
*
* @rdesc
* nothing
*/
void CTxtBlk::MoveGap(
DWORD ichGap) //@parm new position for the gap
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtBlk::MoveGap");
DWORD cbMove;
DWORD ibGapNew = CbOfCch(ichGap);
LPBYTE pbFrom = (LPBYTE) _pch;
LPBYTE pbTo;
if(ibGapNew == _ibGap)
return;
if(ibGapNew < _ibGap)
{
cbMove = _ibGap - ibGapNew;
pbFrom += ibGapNew;
pbTo = pbFrom + _cbBlock - CbOfCch(_cch);
}
else
{
cbMove = ibGapNew - _ibGap;
pbTo = pbFrom + _ibGap;
pbFrom = pbTo + _cbBlock - CbOfCch(_cch);
}
MoveMemory(pbTo, pbFrom, cbMove);
_ibGap = ibGapNew;
}
/*
* CTxtBlk::ResizeBlock(cbNew)
*
* @mfunc
* resize this text block
*
* @rdesc
* FALSE if block could not be resized <nl>
* non-FALSE otherwise
*
* @comm
* Side Effects: <nl>
* moves text block
*/
BOOL CTxtBlk::ResizeBlock(
DWORD cbNew) //@parm the new size
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtBlk::ResizeBlock");
TCHAR *pch;
DWORD cbMove;
AssertSz(cbNew > 0, "resizing block to size <= 0");
AssertSz(cbNew <= cbBlockMost, "CTxtBlk::ResizeBlock() - block too big");
if(cbNew < _cbBlock)
{
if(_ibGap != CbOfCch(_cch))
{
// move text after gap down so that it doesn't get dropped
cbMove = CbOfCch(_cch) - _ibGap;
pch = _pch + CchOfCb(_cbBlock - cbMove);
MoveMemory(pch - CchOfCb(_cbBlock - cbNew), pch, cbMove);
}
_cbBlock = cbNew;
}
pch = (TCHAR*)PvReAlloc(_pch, cbNew);
if(!pch)
return _cbBlock == cbNew; // FALSE if grow, TRUE if shrink
_pch = pch;
if(cbNew > _cbBlock)
{
if(_ibGap != CbOfCch(_cch)) // Move text after gap to end so that
{ // we don't end up with two gaps
cbMove = CbOfCch(_cch) - _ibGap;
pch += CchOfCb(_cbBlock - cbMove);
MoveMemory(pch + CchOfCb(cbNew - _cbBlock), pch, cbMove);
}
_cbBlock = cbNew;
}
return TRUE;
}
// ======================== CTxtStory class ============================
/*
* CTxtStory::CTxtStory
*
* @mfunc Constructor
*
* @devnote Automatically allocates a text array. If we want to have a
* completely empty edit control, then don't allocate a story. NB!
*
*/
CTxtStory::CTxtStory()
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtStory::CTxtStory");
_pCFRuns = NULL;
_pPFRuns = NULL;
}
/*
* CTxtStory::~CTxtStory
*
* @mfunc Destructor
*/
CTxtStory::~CTxtStory()
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtStory::~CTxtStory");
// Remove formatting.
DeleteFormatRuns();
}
/*
* DeleteRuns ()
*
* @mfunc
* Helper function for DeleteFormatRuns() below. Releases
* formats used by format run collection before deleting the
* collection
*/
void DeleteRuns(CFormatRuns *pRuns, IFormatCache *pf)
{
if(pRuns) // Format runs exist
{
DWORD n = pRuns->Count(); // n of them
if(n)
{
CFormatRun *pRun = pRuns->Elem(0);
for( ; n--; pRun++)
pf->ReleaseFormat(pRun->_iFormat); // Free run's format
}
delete pRuns;
}
}
/*
* CTxtStory::DeleteFormatRuns ()
*
* @mfunc Convert to plain - remove format runs
*/
void CTxtStory::DeleteFormatRuns()
{
TRACEBEGIN(TRCSUBSYSBACK, TRCSCOPEINTERN, "CTxtStory::ConvertToPlain");
IFormatCache * pf;
GetCharFormatCache((ICharFormatCache **)&pf);
DeleteRuns(_pCFRuns, pf);
_pCFRuns = NULL;
GetParaFormatCache((IParaFormatCache **)&pf);
DeleteRuns(_pPFRuns, pf);
_pPFRuns = NULL;
}
#ifdef DEBUG
//This dumps the contents of the CTxtStory
//TxtBlk & FormatRun arrays to the debug output.
void CTxtStory::DbgDumpStory(void)
{
CTxtBlk * pblk;
CFormatRun * pcfr;
CFormatRun * ppfr;
DWORD ctxtr = 0;
DWORD ccfr = 0;
DWORD cpfr = 0;
DWORD i;
ctxtr = _TxtArray.Count();
if (_pCFRuns)
ccfr = _pCFRuns->Count();
if (_pPFRuns)
cpfr = _pPFRuns->Count();
for(i = 0; i < ctxtr; i++)
{
pblk = (CTxtBlk*)_TxtArray.Elem(i);
Tracef(TRCSEVNONE, "TxtBlk #%d: cch = %d.", (i + 1), pblk->_cch);
}
for(i = 0; i < ccfr; i++)
{
pcfr = (CFormatRun*)_pCFRuns->Elem(i);
Tracef(TRCSEVNONE, "CFR #%d: cch = %d, iFormat = %d.",(i + 1), pcfr->_cch, pcfr->_iFormat);
}
for(i = 0; i < cpfr; i++)
{
ppfr = (CFormatRun*)_pPFRuns->Elem(i);
Tracef(TRCSEVNONE, "PFR #%d: cch = %d, iFormat = %d.",(i + 1), ppfr->_cch, ppfr->_iFormat);
}
return;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -