windows-nt/Source/XPSP1/NT/inetsrv/query/apps/srch/brview.cxx
2020-09-26 16:20:57 +08:00

1098 lines
28 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996 - 2000.
//
// File: brview.cxx
//
// Contents:
//
// History: 15 Aug 1996 DLee Created
//
//--------------------------------------------------------------------------
#include <pch.cxx>
#pragma hdrstop
#define TheModel _layout.GetModel()
#define UNICODE_PARAGRAPH_SEPARATOR 0x2029
const int BUFLEN = 256;
WCHAR LineBuffer[BUFLEN];
const int cpLeftMargin = 3;
int TrimEOL (WCHAR * pwcLine, int cwcLine)
{
// If the line ends in \r\n or \n, don't include that in the length.
// TabbedTextOut() prints garbage when it sees \r or \n
if ((cwcLine >= 2) && (pwcLine[cwcLine - 2] == L'\r'))
cwcLine -= 2;
else if ((cwcLine >= 1) &&
((pwcLine[cwcLine - 1] == L'\r') ||
(pwcLine[cwcLine - 1] == UNICODE_PARAGRAPH_SEPARATOR) ||
(pwcLine[cwcLine - 1] == L'\n')))
cwcLine--;
return cwcLine;
} //TrimEOL
void TextMetrics::GetSizes ( CharDim& dim )
{
dim.cxChar = _tm.tmAveCharWidth;
dim.cyChar = _tm.tmHeight + _tm.tmExternalLeading;
} //GetSizes
void View::_NoSelection()
{
_Selection.None();
} //NoSelection
void View::_UpdateSelection(
LPARAM lParam )
{
int x = (int) (short) LOWORD( lParam );
int y = (int) (short) HIWORD( lParam );
if ( y < 0 )
y = 0;
else if ( y > _cyClient )
y = _cyClient;
int para, o;
GetParaAndOffset( x, y, para, o );
if ( _fStartIsAnchor )
{
if ( ( para < _Selection.ParaStart() ) ||
( ( para == _Selection.ParaStart() ) &&
( o < _Selection.OffStart() ) ) )
{
_Selection.SetEnd( _Selection.ParaStart(), _Selection.OffStart() );
_Selection.SetStart( para, o );
_fStartIsAnchor = FALSE;
}
else
{
_Selection.SetEnd( para, o );
}
}
else
{
if ( ( para > _Selection.ParaEnd() ) ||
( ( para == _Selection.ParaEnd() ) &&
( o > _Selection.OffEnd() ) ) )
{
_Selection.SetStart( _Selection.ParaEnd(), _Selection.OffEnd() );
_Selection.SetEnd( para, o );
_fStartIsAnchor = TRUE;
}
else
{
_Selection.SetStart( para, o );
}
}
if ( _fFullSelRepaint )
{
InvalidateRect( _hwnd, NULL, FALSE );
_fFullSelRepaint = FALSE;
}
else
{
int yMin = __min( y, _cpLastSelY );
int yMax = __max( y, _cpLastSelY );
RECT rc;
rc.left = 0;
rc.right = _cxClient;
rc.top = yMin - LineHeight();
rc.bottom = yMax + LineHeight();
InvalidateRect( _hwnd, &rc, FALSE );
}
_cpLastSelY = y;
} //_UpdateSelection
void View::ButtonUp( WPARAM wParam, LPARAM lParam )
{
_fSelecting = FALSE;
if ( GetCapture() == _hwnd )
ReleaseCapture();
if ( _fDblClk )
return;
if ( _Selection.IsNull() )
{
_Selection.None();
return;
}
else
{
_UpdateSelection( lParam );
}
} //ButtonUp
void View::MouseMove( WPARAM wParam, LPARAM lParam )
{
if ( _fSelecting &&
( wParam & MK_LBUTTON ) )
_UpdateSelection( lParam );
} //MouseMove
void View::ButtonDown( WPARAM wParam, LPARAM lParam )
{
BOOL fOldSel = _Selection.SelectionExists();
_fDblClk = FALSE;
SetCapture( _hwnd );
_fStartIsAnchor = TRUE;
_fSelecting = TRUE;
_NoSelection();
int x = LOWORD( lParam );
int y = HIWORD( lParam );
_cpLastSelY = y;
int para, o;
GetParaAndOffset( x, y, para, o );
_Selection.SetStart( para, o );
_fFullSelRepaint = FALSE;
if ( fOldSel )
InvalidateRect( _hwnd, NULL, FALSE );
} //ButtonDown
int GetCharOffset(
HDC hdc,
int iClickX,
WCHAR * pwcLine,
int cwcLine,
int cpLeft )
{
// a click in the left margin counts
if ( 0 != cwcLine && iClickX < cpLeft )
return 0;
int l = cpLeft;
for ( int c = 0; c < cwcLine; c++ )
{
int dx = LOWORD( GetTabbedTextExtent( hdc, pwcLine, 1 + c, 0, 0 ) );
if ( iClickX >= l && iClickX <= dx + cpLeft )
break;
l = dx + cpLeft;
}
return c;
} //GetCharOffset
void View::GetParaAndOffset(
int x,
int y,
int & para,
int & offset )
{
offset = 0;
HDC hdc = GetDC( _hwnd );
if ( 0 == hdc )
return;
HFONT hOldFont = (HFONT) SelectObject( hdc, _layout.Font() );
para = _layout.FirstPara();
int paLine = _layout.FirstLineInPara(); // line within paragraph
int paOffBeg; // line beginning offset within paragraph
int paOffEnd; // line end offset within paragraph
int line = 0; // line # counting from top of window
int left = cpLeftMargin - _layout.XBegin();
while ( _layout.GetLineOffsets( para, paLine, paOffBeg, paOffEnd ) )
{
do
{
int top = _layout.Y ( line );
int bottom = top + _layout.CyChar();
if ( y >= top && y <= bottom )
{
// got the line, now find the word selected
int cwcLine = __min ( BUFLEN, paOffEnd - paOffBeg );
if ( TheModel.GetLine(para, paOffBeg, cwcLine, LineBuffer ) )
{
cwcLine = TrimEOL( LineBuffer, cwcLine );
offset = paOffBeg + GetCharOffset( hdc,
x,
LineBuffer,
cwcLine,
cpLeftMargin );
}
goto cleanup;
}
line++;
if (line >= _layout.MaxLines())
goto cleanup;
paLine++;
} while ( _layout.GetLineOffsets( para, paLine, paOffBeg, paOffEnd ) );
// next paragraph
para++;
paLine = 0;
}
cleanup:
SelectObject( hdc, hOldFont );
ReleaseDC( _hwnd, hdc );
} //GetParaAndOffset
void View::EditCopy( HWND hwnd, WPARAM wParam )
{
if ( _Selection.SelectionExists() )
{
// is everything in one paragraph? -- easy case
if ( _Selection.IsInOnePara() )
{
int cwcLine = __min ( BUFLEN,
_Selection.OffEnd() - _Selection.OffStart() );
TheModel.GetLine( _Selection.ParaStart(),
_Selection.OffStart(),
cwcLine, LineBuffer );
cwcLine = TrimEOL( LineBuffer, cwcLine );
LineBuffer[cwcLine] = 0;
PutInClipboard( LineBuffer );
}
else
{
// compute how much text to copy
int cwcTotal = 0;
for ( int p = _Selection.ParaStart();
p <= _Selection.ParaEnd();
p++ )
{
int cwcLine = BUFLEN;
if ( p == _Selection.ParaStart() )
{
TheModel.GetLine( p, _Selection.OffStart(),
cwcLine, LineBuffer );
}
else if ( p == _Selection.ParaEnd() )
{
TheModel.GetLine( p, 0, cwcLine, LineBuffer );
cwcLine = _Selection.OffEnd();
}
else
{
TheModel.GetLine( p, 0, cwcLine, LineBuffer );
}
cwcTotal += cwcLine;
}
// allocate a buffer and copy the text
XArray<WCHAR> aClip( cwcTotal + 1 );
WCHAR *pwc = (WCHAR *) aClip.GetPointer();
cwcTotal = 0;
for ( p = _Selection.ParaStart();
p <= _Selection.ParaEnd();
p++ )
{
int cwcLine = BUFLEN;
if ( p == _Selection.ParaStart() )
{
TheModel.GetLine( p, _Selection.OffStart(),
cwcLine, LineBuffer );
}
else if ( p == _Selection.ParaEnd() )
{
TheModel.GetLine( p, 0, cwcLine, LineBuffer );
cwcLine = _Selection.OffEnd();
}
else
{
TheModel.GetLine( p, 0, cwcLine, LineBuffer );
}
LineBuffer[cwcLine] = 0;
wcscpy( pwc + cwcTotal, LineBuffer );
cwcTotal += cwcLine;
}
PutInClipboard( pwc );
}
}
} //EditCopy
BOOL isWhite( WCHAR c )
{
// well, actually white space and C++ break characters
return ( L' ' == c ||
L'\r' == c ||
L'\n' == c ||
L'\t' == c ||
L'\\' == c ||
L'\'' == c ||
L'\"' == c ||
L':' == c ||
L';' == c ||
L',' == c ||
L'[' == c ||
L']' == c ||
L'{' == c ||
L'}' == c ||
L'(' == c ||
L')' == c ||
L'/' == c ||
L'+' == c ||
L'-' == c ||
L'=' == c ||
L'*' == c ||
L'^' == c ||
L'~' == c ||
L'&' == c ||
L'!' == c ||
L'?' == c ||
L'<' == c ||
L'>' == c ||
L'.' == c ||
L'|' == c ||
UNICODE_PARAGRAPH_SEPARATOR == c );
} //isWhite
BOOL GetSelectedWord(
HDC hdc,
int iClickX,
WCHAR *pwcLine,
int cwcLine,
int cpLeft,
int &rStart,
int &rEnd )
{
// what character had the click?
int c = GetCharOffset( hdc, iClickX, pwcLine, cwcLine, cpLeft );
// move left and right till white space is found
if ( c != cwcLine )
{
rEnd = c;
while ( rEnd < (cwcLine - 1) && !isWhite( pwcLine[ rEnd ] ) )
rEnd++;
// selection doesn't include end
if ( ( rEnd == ( cwcLine - 1 ) ) &&
( !isWhite( pwcLine[ rEnd ] ) ) )
rEnd++;
rStart = c;
while ( rStart > 0 && !isWhite( pwcLine[ rStart ] ) )
rStart--;
// don't include white space if not at start of line
if ( rStart < c && isWhite( pwcLine[ rStart ] ) )
rStart++;
// did we grab anything?
return ( rEnd > rStart );
}
else
{
return FALSE;
}
} //GetSelectedWord
int View::ParaFromY(
int y )
{
int para = _layout.FirstPara();
int paLine = _layout.FirstLineInPara(); // line within paragraph
int paOffBeg; // line beginning offset within paragraph
int paOffEnd; // line end offset within paragraph
int line = 0; // line # counting from top of window
int left = cpLeftMargin - _layout.XBegin();
while ( _layout.GetLineOffsets( para, paLine, paOffBeg, paOffEnd ) )
{
do
{
int top = _layout.Y( line );
int bottom = top + _layout.CyChar();
if ( y >= top && y <= bottom )
{
return 1 + para;
}
line++;
if (line >= _layout.MaxLines())
return _layout.FirstPara();
paLine++;
} while ( _layout.GetLineOffsets( para, paLine, paOffBeg, paOffEnd ) );
// next paragraph
para++;
paLine = 0;
}
return _layout.FirstPara();
} //ParaFromY
void View::DblClk( WPARAM wParam, LPARAM lParam )
{
_fDblClk = TRUE;
BOOL fCtrl = ( 0 != ( 0x8000 & GetAsyncKeyState( VK_CONTROL ) ) );
int x = LOWORD( lParam );
int y = HIWORD( lParam );
Selection oldSel( _Selection );
_Selection.None();
HDC hdc = GetDC( _hwnd );
if ( 0 == hdc )
return;
HFONT hOldFont = (HFONT) SelectObject( hdc, _layout.Font() );
int para = _layout.FirstPara();
int paLine = _layout.FirstLineInPara(); // line within paragraph
int paOffBeg; // line beginning offset within paragraph
int paOffEnd; // line end offset within paragraph
int line = 0; // line # counting from top of window
int left = cpLeftMargin - _layout.XBegin();
while (_layout.GetLineOffsets ( para, paLine, paOffBeg, paOffEnd ))
{
do
{
int top = _layout.Y ( line );
int bottom = top + _layout.CyChar();
if ( y >= top && y <= bottom )
{
// if ctrl key is down, attempt to fire up an editor
if ( fCtrl )
{
ViewFile( _pModel->Filename(), fileEdit, 1+para );
goto cleanup;
}
// got the line, now find the word selected
int cwcLine = __min ( BUFLEN, paOffEnd - paOffBeg );
if ( TheModel.GetLine(para, paOffBeg, cwcLine, LineBuffer ) )
{
cwcLine = TrimEOL( LineBuffer, cwcLine );
int iStart, iEnd;
if ( GetSelectedWord( hdc,
x,
LineBuffer,
cwcLine,
cpLeftMargin,
iStart,
iEnd ) )
_Selection.Set( para,
paOffBeg + iStart,
para,
paOffBeg + iEnd );
RECT rc;
rc.left = 0; rc.right = _cxClient;
rc.top = top; rc.bottom = bottom;
InvalidateRect( _hwnd, &rc, FALSE );
}
}
else if ( oldSel.IsInSelection( para ) )
{
RECT rc;
rc.left = 0; rc.right = _cxClient;
rc.top = top; rc.bottom = bottom;
InvalidateRect( _hwnd, &rc, FALSE );
}
line++;
if (line >= _layout.MaxLines())
goto cleanup;
paLine++;
} while (_layout.GetLineOffsets (para, paLine, paOffBeg, paOffEnd ));
// next paragraph
para++;
paLine = 0;
}
cleanup:
SelectObject( hdc, hOldFont );
ReleaseDC( _hwnd, hdc );
UpdateWindow( _hwnd );
} //DblClk
void View::Size ( int cx, int cy )
{
_cyClient = cy;
_cxClient = cx;
}
void View::SetScrollMax ()
{
int linesFromEnd = _cyClient / _layout.CyChar() - 2;
int cline;
for (int para = TheModel.Paras() - 1; para >= 0; para--)
{
cline = _layout.LinesInPara(para);
if (linesFromEnd < cline)
break;
linesFromEnd -= cline;
}
_paraVScrollMax = TheModel.Paras() - 1;
if ( _paraVScrollMax < 0 )
{
_paraVScrollMax = 0;
_paLineVScrollMax = 0;
}
else
{
_paLineVScrollMax = cline - 1 - linesFromEnd;
}
}
void View::SetRange ( int maxParaLen, int cParas )
{
_layout.SetParaRange(cParas);
#if 0
_nHScrollMax = 2 + maxParaLen - _cxClient / _layout.CxChar();
if ( _nHScrollMax < 0 )
#endif
_nHScrollMax = 0;
}
void View::SetScroll( Position & pos )
{
_fFullSelRepaint = TRUE;
int paLine, paOffBeg, paOffEnd;
_layout.Locate (pos.Para(), pos.BegOff(), paLine, paOffBeg, paOffEnd);
if (paLine >= 3)
{
_paraVScroll = pos.Para();
_paLineVScroll = paLine - 3;
}
else
{
// show last line of prev para
int iOffset = ( 0 == _cyClient ) ? 6 : ( VisibleLines() / 3 );
_paraVScroll = pos.Para() - iOffset;
if (_paraVScroll >= 0 )
{
_paLineVScroll = _layout.LinesInPara(_paraVScroll) - 1;
}
else
{
_paraVScroll = 0;
_paLineVScroll = 0;
}
}
#if 0
if ( pos.EndOff() - _nHScrollPos + 1 > _cxClient / _layout.CxChar() )
_nHScrollPos = pos.EndOff() - _cxClient / _layout.CxChar() + 1;
else
_nHScrollPos = 0;
_nHScrollPos = min ( _nHScrollPos, _nHScrollMax );
#else
_nHScrollPos = 0;
#endif
}
int View::JumpToPara ( int para )
{
_fFullSelRepaint = TRUE;
int delta = 0;
int paraStart;
int paraEnd;
if (para == _paraVScroll)
{
return 0;
}
else if (para < _paraVScroll)
{
// jumping backwards, delta negative
delta = -_paLineVScroll;
for ( int p = _paraVScroll - 1; p >= para; p--)
delta -= _layout.LinesInPara(p);
}
else
{
// jumping forward, delta positive
delta = _layout.LinesInPara(_paraVScroll) - _paLineVScroll;
for (int p = _paraVScroll + 1; p < para; p++)
delta += _layout.LinesInPara(p);
}
_paraVScroll = para;
_paLineVScroll = 0;
// return delta from previous position
return delta;
}
int View::IncVScrollPos ( int cLine )
{
_fFullSelRepaint = TRUE;
int para;
if (cLine >= 0)
{
// first back up to the beginning
// of the current para
int cLineLeft = cLine + _paLineVScroll;
// move forward
for (para = _paraVScroll; para <= _paraVScrollMax; para++)
{
int ln = _layout.LinesInPara(para);
if (cLineLeft < ln)
break;
cLineLeft -= ln;
}
if (para > _paraVScrollMax)
{
// overshot the end
// move back
_paraVScroll = _paraVScrollMax;
int cline = _layout.LinesInPara(_paraVScroll);
_paLineVScroll = _paLineVScrollMax;
cLineLeft += cline - _paLineVScrollMax;
cLine -= cLineLeft;
}
else if (para == _paraVScrollMax && cLineLeft > _paLineVScrollMax)
{
_paraVScroll = _paraVScrollMax;
_paLineVScroll = _paLineVScrollMax;
cLineLeft -= _paLineVScrollMax;
cLine -= cLineLeft;
}
else
{
// cLineLeft < Lines In Para
_paraVScroll = para;
_paLineVScroll = cLineLeft;
}
}
else if (cLine < 0)
{
// first skip to the end
// of the current para
int cLineLeft = - cLine + (_layout.LastLineInPara(_paraVScroll) - _paLineVScroll);
// move backward
for (para = _paraVScroll; para >= 0; para--)
{
int ln = _layout.LinesInPara(para);
if (ln > cLineLeft)
break;
cLineLeft -= ln;
}
if (para < 0)
{
// overshot the beginning.
// move up one line
_paraVScroll = 0;
_paLineVScroll = 0;
cLineLeft++;
cLine += cLineLeft;
}
else
{
// cLineLeft < Lines In Para
_paraVScroll = para;
_paLineVScroll = _layout.LinesInPara(para) - cLineLeft - 1;
}
}
return cLine;
}
int View::IncHScrollPos ( int delta )
{
Win4Assert ( FALSE );
// Clip the increment
if ( delta < -_nHScrollPos )
delta = -_nHScrollPos;
else if ( delta > _nHScrollMax - _nHScrollPos )
delta = _nHScrollMax - _nHScrollPos;
_nHScrollPos += delta;
return delta;
}
void View::Paint( HWND hwnd )
{
_layout.Adjust ( _cxClient, _cyClient, _paraVScroll, _paLineVScroll, _nHScrollPos);
PaintText paint (hwnd, _paraVScroll, _paLineVScroll, _layout, _Selection);
paint.PrintLines ();
paint.HiliteHits ();
}
PaintText::PaintText(HWND hwnd, int paraFirst, int paLineFirst, Layout& layout,
Selection & Selection )
: Paint(hwnd), _paraFirst(paraFirst), _paLineFirst(paLineFirst),
_layout(layout), _Selection( Selection )
{
_hOldFont = (HFONT) SelectObject ( hdc, _layout.Font() );
SetBkColor ( hdc, GetSysColor(COLOR_WINDOW) );
SetTextColor( hdc, GetSysColor(COLOR_WINDOWTEXT) );
}
PaintText::~PaintText()
{
SelectObject ( hdc, _hOldFont );
}
void Layout::SetParaRange (int cParas)
{
_cParas = cParas;
_aParaLine = _pModel->GetParaLine();
}
void Layout::Adjust (int cx, int cy, int& paraVScroll, int& paLineVScroll, int nHScrollPos)
{
_cLine = (cy + _dim.cyChar - 1) / _dim.cyChar;
_cCharWidth = cx / _dim.cxChar;
_xBegin = nHScrollPos * _dim.cxChar;
if ( paraVScroll < 0 )
{
paraVScroll = 0;
paLineVScroll = 0;
}
_paLineFirst = paLineVScroll;
_paraFirst = paraVScroll;
}
int Layout::Y (int line ) const
{
return line * _dim.cyChar;
}
void Layout::Locate (int para, int paOff, int& paLine, int& paOffBeg, int& paOffEnd ) const
{
Win4Assert(para < _cParas);
paLine = 0;
paOffBeg = 0;
for (ParaLine const* p = &_aParaLine[para]; p != 0 && p->offEnd <= paOff; p = p->next)
{
paOffBeg = p->offEnd;
paLine++;
}
if (p == 0)
paOffEnd = 0;
else
paOffEnd = p->offEnd;
}
BOOL Layout::GetLineOffsets (int para, int paLine, int& paOffBeg, int& paOffEnd) const
{
if (para < _paraFirst || para > LastPara() || para >= _cParas)
return FALSE;
ParaLine const * p = &_aParaLine[para];
paOffBeg = 0;
for (int line = 0; line < paLine; line++)
{
paOffBeg = p->offEnd;
p = p->next;
if (p == 0)
return FALSE;
}
paOffEnd = p->offEnd;
Win4Assert ( paOffEnd >= paOffBeg);
return TRUE;
}
int Layout::LastPara() const
{
// at most this number
return _paraFirst + _cLine;
}
int Layout::LineNumber (int para, int paLine) const
{
if (para == _paraFirst)
{
return paLine - _paLineFirst;
}
int curPara = _paraFirst + 1;
int curLine = LinesInPara(_paraFirst) - _paLineFirst;
while (curPara < para)
{
curLine += LinesInPara(curPara);
curPara++;
}
return curLine + paLine;
}
int Layout::LinesInPara (int para) const
{
Win4Assert(para < _cParas);
int line = 1;
for (ParaLine const * p = _aParaLine[para].next; p != 0; p = p->next)
line++;
return line;
}
void EnableHilite( HDC hdc )
{
SetBkColor( hdc, GetSysColor(COLOR_HIGHLIGHT) );
SetTextColor( hdc, GetSysColor(COLOR_HIGHLIGHTTEXT) );
}
void EnableHitHilite( HDC hdc )
{
// SetBkColor( hdc, GetSysColor(COLOR_ACTIVECAPTION) );
// SetTextColor( hdc, GetSysColor(COLOR_CAPTIONTEXT) );
// SetBkColor( hdc, GetSysColor(COLOR_INACTIVECAPTION) );
// SetTextColor( hdc, GetSysColor(COLOR_INACTIVECAPTIONTEXT) );
// SetBkColor( hdc, GetSysColor(COLOR_HIGHLIGHTTEXT) );
// SetTextColor( hdc, GetSysColor(COLOR_HIGHLIGHT) );
SetBkColor( hdc, GetSysColor(COLOR_WINDOWTEXT) );
SetTextColor( hdc, GetSysColor(COLOR_WINDOW) );
// SetBkColor( hdc, GetSysColor(COLOR_HIGHLIGHT) );
// SetTextColor( hdc, GetSysColor(COLOR_HIGHLIGHTTEXT) );
}
void EnableNonCurrentHitHilite( HDC hdc )
{
SetBkColor ( hdc, GetSysColor(COLOR_WINDOW) );
SetTextColor( hdc, GetSysColor(COLOR_HIGHLIGHT) );
}
void DisableHilite( HDC hdc )
{
SetBkColor ( hdc, GetSysColor(COLOR_WINDOW) );
SetTextColor ( hdc, GetSysColor(COLOR_WINDOWTEXT) );
}
void PaintText::PrintLines ()
{
int para = _layout.FirstPara();
int paLine = _layout.FirstLineInPara(); // line within paragraph
int paOffBeg; // line beginning offset within paragraph
int paOffEnd; // line end offset within paragraph
int line = 0; // line # counting from top of window
int left = cpLeftMargin - _layout.XBegin();
while (_layout.GetLineOffsets ( para, paLine, paOffBeg, paOffEnd ))
{
// print paragraph
do
{
// clip to the update rect
int top = _layout.Y ( line );
int bottom = top + _layout.CyChar();
if ( top <= rcPaint.bottom && bottom >= rcPaint.top)
{
int cwcLine = __min ( BUFLEN, paOffEnd - paOffBeg );
if (!TheModel.GetLine( para, paOffBeg, cwcLine, LineBuffer ))
return;
cwcLine = TrimEOL( LineBuffer, cwcLine );
if ( 0 == cwcLine )
{
// to make selections look better...
wcscpy(LineBuffer,L" ");
cwcLine = 1;
}
Win4Assert( cwcLine >= 0 );
if ( _Selection.IsInSelection( para ) )
{
if ( ( para > _Selection.ParaStart() ) &&
( para < _Selection.ParaEnd() ) )
{
EnableHilite( hdc );
TabbedTextOut( hdc, left, top, LineBuffer, cwcLine,
0, 0, left );
DisableHilite( hdc );
}
else
{
int l = left;
for ( int c = 0; c < cwcLine; c++ )
{
if ( _Selection.IsInSelection( para, c + paOffBeg ) )
EnableHilite( hdc );
LONG dim = TabbedTextOut( hdc, l, top,
LineBuffer + c, 1,
0, 0, left );
DisableHilite( hdc );
l += LOWORD(dim);
}
}
}
else
{
TabbedTextOut( hdc, left, top, LineBuffer, cwcLine,
0, 0, left );
}
}
line++;
if (line >= _layout.MaxLines())
return;
paLine++;
} while (_layout.GetLineOffsets( para, paLine, paOffBeg, paOffEnd ));
// next paragraph
para++;
paLine = 0;
}
} //PrintLines
void PaintText::HiliteHits ()
{
TheModel.HiliteAll( TRUE );
if ( TheModel.FirstHit() )
{
do
{
if ( !TheModel.isSavedCurrent() )
PrintCurrentHit( FALSE );
}
while( TheModel.NextHit() );
TheModel.RestoreHilite();
}
TheModel.HiliteAll( FALSE );
PrintCurrentHit( TRUE );
} //HiliteHits
const int WORDBUFLEN = 80;
static WCHAR WordBuffer [WORDBUFLEN];
void PaintText::PrintCurrentHit( BOOL fCurrent )
{
if ( fCurrent )
EnableHitHilite( hdc );
else
EnableNonCurrentHitHilite( hdc );
int cPos = TheModel.GetPositionCount();
int iPos = 0;
Position pos = TheModel.GetPosition(iPos);
int left = cpLeftMargin - _layout.XBegin();
while ( iPos < cPos )
{
int curPara = pos.Para();
if ( curPara > _layout.LastPara() )
break;
if (curPara >= _layout.FirstPara())
{
int paLine; // line within paragraph
int paOffBeg; // line beginning offset within paragraph
int paOffEnd; // line end offset within paragraph
_layout.Locate ( curPara, pos.BegOff(), paLine, paOffBeg, paOffEnd );
int line = _layout.LineNumber ( curPara, paLine );
// Output the line with highlights
int cwcLine = __min ( BUFLEN, paOffEnd - paOffBeg );
if (!TheModel.GetLine (curPara, paOffBeg, cwcLine, LineBuffer ))
break;
cwcLine = TrimEOL( LineBuffer, cwcLine );
int top = _layout.Y (line);
do
{
int cwc = __min( pos.Len(), WORDBUFLEN);
TheModel.GetWord( curPara, pos.BegOff(), cwc, WordBuffer );
Win4Assert ( cwc >= 0 );
// Find out how much space it takes before the highlight
DWORD dwExt = GetTabbedTextExtent ( hdc,
LineBuffer,
pos.BegOff() - paOffBeg,
0, 0 );
// Print hilighted text
TabbedTextOut ( hdc,
left + LOWORD(dwExt),
top,
WordBuffer,
cwc,
0, 0,
left );
iPos++;
if (iPos >= cPos)
break;
pos = TheModel.GetPosition(iPos);
} while ( pos.Para() == curPara );
}
else
{
iPos++;
}
}
DisableHilite( hdc );
} //PrintCurrentHit