home *** CD-ROM | disk | FTP | other *** search
- /////////////////////////////////////////////////////////////////////////////
- //
- // File : OutputView.cpp
- // Project : MsgTrace
- // Component : MsgTracer
- //---------------------------------------------------------------------------
- // Description : output-view class
- //
- /////////////////////////////////////////////////////////////////////////////
- //
- // SourceSafe Strings. Do not change.
- //---------------------------------------------------------------------------
- // $Author: jeskes $
- // $Date: $
- // $Revision: $
- //
- /////////////////////////////////////////////////////////////////////////////
-
- #include "stdafx.h"
-
- #include "MsgTracerApp.h"
- #include "mainfrm.h"
-
- #include "OutputDoc.h"
- #include "OutputLine.h"
- #include "OutputView.h"
-
- #include "ColFont.h"
-
- /////////////////////////////////////////////////////////////////////////////
-
- #ifdef _DEBUG
- #undef THIS_FILE
- static char BASED_CODE THIS_FILE[] = __FILE__;
- #endif
-
- /////////////////////////////////////////////////////////////////////////////
-
- #define ENDOFLINE ((int) 0x7fff )
- #define ENDOFLINES ((int) 0x7fff )
- #define CURRENT_VALUE ((int) 0xffff )
-
- #define SCROLL_RIGHT 0x0001
- #define SCROLL_LEFT 0x0002
- #define SCROLL_UP 0x0010
- #define SCROLL_DOWN 0x0020
- #define SCROLL_POSITION 0x0100
-
- #define CARET_WIDTH 2
- #define CARET_HEIGHT m_nRowHeight
-
- #define CAPTURE_TIMER 100
- #define CAPTURE_TIMER_TIMEOUT 50
-
- /////////////////////////////////////////////////////////////////////////////
- // COutputView
- /////////////////////////////////////////////////////////////////////////////
-
- IMPLEMENT_DYNCREATE(COutputView, CScrollView)
-
- BEGIN_MESSAGE_MAP(COutputView, CScrollView)
- //{{AFX_MSG_MAP(COutputView)
- ON_WM_SIZE()
- ON_WM_CREATE()
- ON_WM_SETFOCUS()
- ON_COMMAND(ID_VIEW_FONT, OnViewFont)
- ON_WM_KILLFOCUS()
- ON_WM_SETCURSOR()
- ON_WM_LBUTTONDOWN()
- ON_WM_RBUTTONUP()
- ON_WM_KEYDOWN()
- ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
- ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
- ON_WM_LBUTTONUP()
- ON_WM_TIMER()
- ON_WM_MOUSEMOVE()
- //}}AFX_MSG_MAP
-
- // Standard Print commands (print only - not preview)
- ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
- END_MESSAGE_MAP()
-
- /////////////////////////////////////////////////////////////////////////////
- // COutputView: construction
- /////////////////////////////////////////////////////////////////////////////
-
- COutputView::COutputView() :
-
- m_hPrinterFont( NULL ),
-
- m_nPrintRowHeight( 0 ),
- m_nPrintLinesPerPage( 0 ),
-
- m_nMaxVisibleLines( 0 ),
- m_nRowWidth( 0 ),
- m_nRowHeight( 0 ),
-
- m_nCurCol( 0 ),
- m_nCurRow( 0 ),
- m_nSelCol( 0 ),
- m_nSelRow( 0 ),
-
- m_bWhileSelecting( FALSE ),
-
- m_nIDCaptureTimer( 0 )
-
- {
- m_pColoredFont = new CColoredFont( "out" );
- m_pTrackMenu = new CMenu;
-
- m_pTrackMenu->LoadMenu( IDR_PROPS_OUTPUTTYPE );
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- COutputView::~COutputView()
- {
- if( NULL != m_hPrinterFont )
- {
- ::DeleteObject( m_hPrinterFont );
- }
-
- delete m_pColoredFont;
- m_pColoredFont = NULL;
-
- delete m_pTrackMenu;
- m_pTrackMenu = NULL;
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- int COutputView::OnCreate( LPCREATESTRUCT lpCreateStruct )
- {
- if( CScrollView::OnCreate( lpCreateStruct ) == -1 )
- {
- return( -1 );
- }
-
- return( 0 );
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- COutputDoc* COutputView::GetDocument()
- {
- return( (COutputDoc*) m_pDocument );
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::OnInitialUpdate()
- {
- CScrollView::OnInitialUpdate();
- UpdateScrollSizes();
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::OnUpdate( CView* pSender, LPARAM lHint, CObject* pHint )
- {
- if( OUTPUTDOC_LINEADDED == lHint )
- {
- COutputLine* pLine = (COutputLine*) pHint;
-
- if( NULL == pLine )
- {
- return;
- }
-
- CClientDC dc( this );
-
- CSize sizeText = dc.GetTabbedTextExtent( (const char*) *pLine,
- pLine->GetLength(),
- pLine->GetFormat().GetTabStops(),
- (int*) pLine->GetFormat().GetTabStopPositionsPixel( dc ) );
-
- m_nRowWidth = max( m_nRowWidth, sizeText.cx );
-
- UpdateScrollSizes();
-
-
- /***
- int nMax = GetDocument()->GetMaxLines();
- int nVis = GetMaxVisibleLines();
-
- if( nMax > nVis )
- {
- ScrollToDevicePosition( CPoint( 0, ( nMax - nVis ) * m_nRowHeight ) );
- }
- ***/
-
- Invalidate();
- SetCurPos( 0, GetDocument()->GetMaxLines() - 1 );
- }
- else if( OUTPUTDOC_CLEARED == lHint )
- {
- m_nSelCol = 0;
- m_nSelCol = 0;
- m_bWhileSelecting = FALSE;
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::OnPrepareDC( CDC* pDC, CPrintInfo* pInfo )
- {
- CScrollView::OnPrepareDC( pDC, pInfo );
-
- if( NULL != pInfo )
- {
- pInfo->m_bContinuePrinting =
- ( (int) pInfo->m_nCurPage <=
- GetDocument()->GetMaxLines() / m_nPrintLinesPerPage + 1 );
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // COutputView: drawing stuff
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::OnDraw( CDC* pDC )
- {
- //-----------------------------------------------------------------------
- // prepare for drawing
- //-----------------------------------------------------------------------
-
- HideCaret();
-
- pDC->SelectObject( *ColoredFontGet() );
- pDC->SetTextColor( *ColoredFontGet() );
-
- //-----------------------------------------------------------------------
- // draw only neccessary lines of document
- //-----------------------------------------------------------------------
-
- int nFirstLine;
- int nLastLine;
-
- CRect rectClip;
- pDC->GetClipBox( &rectClip );
-
- RectToRange( rectClip, nFirstLine, nLastLine );
-
- int y = m_nRowHeight * nFirstLine;
-
- for( int nLine = nFirstLine
- ;
- nLine <= nLastLine
- ;
- nLine++, y+= m_nRowHeight )
- {
- OnDrawLine( pDC, nLine, y, FALSE );
- }
-
- ShowCaret();
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::OnDrawLine( CDC* pDC, int nLine, int y, BOOL bSelected )
- {
- //-----------------------------------------------------------------------
- // draw neccessary lines of document
- //-----------------------------------------------------------------------
-
- COutputDoc* pDoc = GetDocument();
- COutputLine& sLine = pDoc->GetLine( nLine );
-
- if( "$LINE" == sLine )
- {
- y += m_nRowHeight / 2;
-
- pDC->MoveTo( 0, y );
- pDC->LineTo( 10000, y );
- }
- else
- {
- int nStartCol, nEndCol;
- GetSelForRow( nLine, nStartCol, nEndCol );
- if( ENDOFLINE == nEndCol )
- {
- nEndCol = sLine.GetLength();
- }
-
- LPCSTR lpszLine = (LPCSTR) sLine;
-
- COLORREF rgbNormalTextColor = pDC->GetTextColor();
- COLORREF rgbNormalBkColor = pDC->GetBkColor();
-
- CSize sizeLeft =
- pDC->TabbedTextOut( 0,
- y,
- lpszLine,
- nStartCol,
- sLine.GetFormat().GetTabStops(),
- (int*) sLine.GetFormat().GetTabStopPositionsPixel( *pDC ),
- 0 );
-
- pDC->SetTextColor( rgbNormalBkColor );
- pDC->SetBkColor( rgbNormalTextColor );
-
- CSize sizeMid =
- pDC->TabbedTextOut( sizeLeft.cx,
- y,
- lpszLine + nStartCol,
- nEndCol - nStartCol,
- sLine.GetFormat().GetTabStops(),
- (int*) sLine.GetFormat().GetTabStopPositionsPixel( *pDC ),
- 0 );
-
- pDC->SetTextColor( rgbNormalTextColor );
- pDC->SetBkColor( rgbNormalBkColor );
-
- CSize sizeRight =
- pDC->TabbedTextOut( sizeLeft.cx + sizeMid.cx,
- y,
- lpszLine + nEndCol,
- sLine.GetLength() - nEndCol,
- sLine.GetFormat().GetTabStops(),
- (int*) sLine.GetFormat().GetTabStopPositionsPixel( *pDC ),
- 0 );
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::OnSize( UINT nType, int cx, int cy )
- {
- CScrollView::OnSize( nType, cx, cy );
-
- UpdateScrollSizes();
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::UpdateScrollSizes()
- {
- //-----------------------------------------------------------------------
- // UpdateScrollSizes() is called when it is necessary to adjust the
- // scrolling range or page/line sizes. There are two occassions
- // where this is necessary: (1) when a new row is added-- see
- // OnUpdate()-- and (2) when the window size changes-- see OnSize().
- //-----------------------------------------------------------------------
-
- CRect rectClient;
- GetClientRect( &rectClient );
-
- CClientDC dc( this );
- dc.SelectObject( *ColoredFontGet() );
-
- TEXTMETRIC tm;
- dc.GetTextMetrics( &tm );
- m_nRowHeight = tm.tmHeight;
-
- //-----------------------------------------------------------------------
- // The vert scrolling range is the total display height of all the rows
- // the horz scrolling range is the width of a row
- //-----------------------------------------------------------------------
-
- CSize sizeTotal( m_nRowWidth + rectClient.right,
- m_nRowHeight * GetDocument()->GetMaxLines() );
-
- //-----------------------------------------------------------------------
- // The vertical per-page scrolling distance is equal to the
- // how many rows can be displayed in the current window, less
- // one row for paging overlap.
- //-----------------------------------------------------------------------
-
- m_nMaxVisibleLines = rectClient.bottom / m_nRowHeight;
-
- CSize sizePage( m_nRowWidth / 5,
- max( m_nRowHeight,
- m_nRowHeight * m_nMaxVisibleLines ) );
-
- //-----------------------------------------------------------------------
- // The vertical per-line scrolling distance is equal to the
- // height of the row.
- //-----------------------------------------------------------------------
-
- CSize sizeLine( tm.tmMaxCharWidth, m_nRowHeight );
-
- SetScrollSizes( MM_TEXT, sizeTotal, sizePage, sizeLine );
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::RectToRange( const CRect& rect, int& nFirst, int& nLast )
- {
- nFirst = rect.top / m_nRowHeight;
-
- nLast = min( nFirst + rect.Height() / m_nRowHeight + 1,
- GetDocument()->GetMaxLines() - 1 );
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // COutputView: printing stuff
- /////////////////////////////////////////////////////////////////////////////
-
- BOOL COutputView::OnPreparePrinting( CPrintInfo* pInfo )
- {
- return( DoPreparePrinting( pInfo ) );
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::OnBeginPrinting( CDC* pDC, CPrintInfo* pInfo )
- {
- if( NULL != m_hPrinterFont )
- {
- ::DeleteObject( m_hPrinterFont );
- m_hPrinterFont = NULL;
- }
-
- //-----------------------------------------------------------------------
- // get display font...
- //-----------------------------------------------------------------------
-
- CFont* pFont = *ColoredFontGet();
-
- LOGFONT lf;
- pFont->GetObject( sizeof( LOGFONT ), &lf );
-
- //-----------------------------------------------------------------------
- // ...map to printer font metrics...
- //-----------------------------------------------------------------------
-
- HDC hDCFrom = ::GetDC( NULL );
-
- lf.lfHeight = ::MulDiv( lf.lfHeight,
- pDC->GetDeviceCaps( LOGPIXELSY ),
- ::GetDeviceCaps( hDCFrom, LOGPIXELSY ) );
-
- lf.lfWidth = 0;
- /***
- lf.lfWidth = ::MulDiv( lf.lfWidth,
- pDC->GetDeviceCaps( LOGPIXELSX ),
- ::GetDeviceCaps( hDCFrom, LOGPIXELSX ) );
- ***/
-
- ::ReleaseDC( NULL, hDCFrom );
-
- //-----------------------------------------------------------------------
- // ...and create font for printing
- //-----------------------------------------------------------------------
-
- m_hPrinterFont = ::CreateFontIndirect( &lf );
-
- //-----------------------------------------------------------------------
- // ...and create font for printing
- //-----------------------------------------------------------------------
-
- pDC->SetMapMode( MM_TEXT );
- pDC->SelectObject( CFont::FromHandle( m_hPrinterFont ) );
-
- TEXTMETRIC tm;
- pDC->GetTextMetrics( &tm );
-
- int nVertRes = pDC->GetDeviceCaps( VERTRES );
-
- m_nPrintRowHeight = tm.tmHeight + tm.tmExternalLeading;
- m_nPrintLinesPerPage = pDC->GetDeviceCaps( VERTRES ) / m_nPrintRowHeight;
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::OnEndPrinting( CDC*, CPrintInfo* )
- {
- if( NULL != m_hPrinterFont )
- {
- ::DeleteObject( m_hPrinterFont );
- m_hPrinterFont = NULL;
- }
-
- m_nPrintRowHeight = 0;
- m_nPrintLinesPerPage = 0;
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::OnPrint( CDC* pDC, CPrintInfo* pInfo )
- {
- CFont* pOldFont = pDC->SelectObject( CFont::FromHandle( m_hPrinterFont ) );
- pDC->SetBkMode( TRANSPARENT );
-
- int y = 0;
-
- int nPageStartRow = ( pInfo->m_nCurPage - 1 ) * m_nPrintLinesPerPage;
- int nPageMaxEndRow = min( GetDocument()->GetMaxLines(),
- nPageStartRow + m_nPrintLinesPerPage );
-
- for( int nLine = nPageStartRow; nLine < nPageMaxEndRow; nLine++ )
- {
- OnDrawLine( pDC, nLine, y, FALSE );
- y+= m_nPrintRowHeight;
- }
-
- pDC->SelectObject( pOldFont );
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::OnViewFont()
- {
- if( ColoredFontGet()->ChooseColoredFont() )
- {
- InvalidateRect( NULL );
- UpdateScrollSizes();
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // COutputView: caret and cursor stuff
- /////////////////////////////////////////////////////////////////////////////
-
- BOOL COutputView::OnSetCursor( CWnd* pWnd, UINT nHitTest, UINT message )
- {
- if( HTCLIENT == nHitTest )
- {
- ::SetCursor( ::LoadCursor( NULL, MAKEINTRESOURCE( IDC_IBEAM ) ) );
- return( TRUE );
- }
-
- return( CScrollView::OnSetCursor( pWnd, nHitTest, message ) );
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::OnSetFocus(CWnd* pOldWnd)
- {
- CScrollView::OnSetFocus(pOldWnd);
-
- /******
- // we must invalidate active view - otherwise Ctrl-F6 doesn't work
- // after we have activated the output view in Split Mode
-
- CMainFrame* pFrame = (CMainFrame*) AfxGetMainWnd();
- ASSERT( NULL != pFrame );
-
- pFrame->SetActiveView( NULL, FALSE );
- pFrame->OnUpdateFrameMenu( GetDocument()->GetDefaultMenu() );
- **********/
- // caret stuff
-
- ::CreateCaret( m_hWnd, (HBITMAP) NULL, CARET_WIDTH, CARET_HEIGHT );
- ShowCaret();
- MoveCaretToCurPos();
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::OnKillFocus(CWnd* pNewWnd)
- {
- CScrollView::OnKillFocus(pNewWnd);
-
- ::DestroyCaret();
-
- CMainFrame* pFrame = (CMainFrame*) AfxGetMainWnd();
- ASSERT( NULL != pFrame );
- pFrame->OnUpdateFrameMenu( NULL );
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::OnLButtonDown(UINT nFlags, CPoint point)
- {
- CScrollView::OnLButtonDown( nFlags, point );
-
- BOOL bMoveCaret = TRUE;
- BOOL bClearSelection = !( GetAsyncKeyState( VK_SHIFT ) < 0 );
-
- SetCapture();
- SetCurPos( point, bMoveCaret, bClearSelection );
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::OnLButtonUp(UINT nFlags, CPoint point)
- {
- CScrollView::OnLButtonUp(nFlags, point);
-
- SetCurPos( point, TRUE, FALSE );
- ReleaseCapture();
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::OnRButtonUp(UINT nFlags, CPoint point)
- {
- CScrollView::OnRButtonUp(nFlags, point);
-
- MapWindowPoints( NULL, &point, 1 );
-
- CMenu* pTrackPopup = m_pTrackMenu->GetSubMenu( 0 );
-
- if( NULL != pTrackPopup )
- {
- pTrackPopup->TrackPopupMenu( TPM_LEFTALIGN | TPM_LEFTBUTTON,
- point.x,
- point.y,
- this );
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::OnMouseMove(UINT nFlags, CPoint point)
- {
- CScrollView::OnMouseMove(nFlags, point);
-
- if( !( MK_LBUTTON & nFlags ) )
- {
- return;
- }
-
- // point is restricted to ClientRect
-
- CRect rectClient;
- GetClientRect( rectClient );
-
- point.x = max( min( point.x, rectClient.right ), rectClient.left );
- point.y = max( min( point.y, rectClient.bottom ), rectClient.top );
-
- // set caret - and do scrolling if neccessary..
-
- SetCurPos( point, TRUE, FALSE );
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::SetCapture()
- {
- CScrollView::SetCapture();
-
- m_nIDCaptureTimer = SetTimer( CAPTURE_TIMER, CAPTURE_TIMER_TIMEOUT, NULL );
- }
-
- void COutputView::ReleaseCapture()
- {
- KillTimer( m_nIDCaptureTimer );
- ::ReleaseCapture();
- }
-
- void COutputView::OnTimer(UINT nIDEvent)
- {
- CScrollView::OnTimer(nIDEvent);
-
- // simulate a mouse move...
-
- CPoint point;
- GetCursorPos( &point );
- ScreenToClient( &point );
-
- UINT nFlags = 0;
-
- if( GetAsyncKeyState( VK_CONTROL ) < 0 )
- {
- nFlags |= MK_CONTROL;
- }
- if( GetAsyncKeyState( VK_LBUTTON ) < 0 )
- {
- nFlags |= MK_LBUTTON;
- }
- if( GetAsyncKeyState( VK_MBUTTON ) < 0 )
- {
- nFlags |= MK_MBUTTON;
- }
- if( GetAsyncKeyState( VK_RBUTTON ) < 0 )
- {
- nFlags |= MK_RBUTTON;
- }
- if( GetAsyncKeyState( VK_SHIFT ) < 0 )
- {
- nFlags |= MK_SHIFT;
- }
-
- OnMouseMove( nFlags, point );
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
- {
- CScrollView::OnKeyDown(nChar, nRepCnt, nFlags);
-
- BOOL bMoveCaret = TRUE;
- BOOL bClearSelection = !( GetAsyncKeyState( VK_SHIFT ) < 0 );
-
- switch( nChar )
- {
- case VK_HOME:
- if( GetAsyncKeyState( VK_CONTROL ) < 0 )
- {
- SetCurPos( 0, 0, bMoveCaret, bClearSelection );
- }
- else
- {
- SetCurPos( 0, CURRENT_VALUE, bMoveCaret, bClearSelection );
- }
- break;
-
- case VK_END:
- if( GetAsyncKeyState( VK_CONTROL ) < 0 )
- {
- SetCurPos( ENDOFLINE, ENDOFLINES, bMoveCaret, bClearSelection );
- }
- else
- {
- SetCurPos( ENDOFLINE, CURRENT_VALUE, bMoveCaret, bClearSelection );
- }
- break;
-
- case VK_PRIOR:
- {
- CPoint pt = GetCaretPos();
- pt.y -= ( ( m_nMaxVisibleLines - 1 ) * m_nRowHeight );
- SetCurPos( pt, bMoveCaret, bClearSelection );
- break;
- }
- case VK_NEXT:
- {
- CPoint pt = GetCaretPos();
- pt.y += ( ( m_nMaxVisibleLines - 1 ) * m_nRowHeight );
- SetCurPos( pt, bMoveCaret, bClearSelection );
- break;
- }
- case VK_LEFT:
- SetCurPos( GetCurCol() - 1, CURRENT_VALUE, bMoveCaret, bClearSelection );
- break;
-
- case VK_RIGHT:
- SetCurPos( GetCurCol() + 1, CURRENT_VALUE, bMoveCaret, bClearSelection );
- break;
-
- case VK_UP:
- {
- CPoint pt = GetCaretPos();
- pt.y -= m_nRowHeight;
- SetCurPos( pt, bMoveCaret, bClearSelection );
- break;
- }
- case VK_DOWN:
- {
- CPoint pt = GetCaretPos();
- pt.y += m_nRowHeight;
- SetCurPos( pt, bMoveCaret, bClearSelection );
- break;
- }
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- CPoint COutputView::VirtCharPosFromCoords( int nCol, int nRow )
- {
- CClientDC dc( this );
- dc.SelectObject( *ColoredFontGet() );
-
- COutputLine& sLine = GetDocument()->GetLine( nRow );
-
- if( nCol > sLine.GetLength() )
- {
- nCol = sLine.GetLength();
- }
-
- CSize size = dc.GetTabbedTextExtent( (const char*) sLine,
- nCol,
- sLine.GetFormat().GetTabStops(),
- (int*) sLine.GetFormat().GetTabStopPositionsPixel( dc ) );
-
- return( CPoint( size.cx, nRow * m_nRowHeight ) );
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::CharCoordsFromVirtPoint( CPoint pt, int& nCol, int& nRow )
- {
- nCol = 0;
- nRow = min( pt.y / m_nRowHeight, GetDocument()->GetMaxLines() - 1 );
- nRow = max( nRow, 0 );
-
- COutputLine& sLine = GetDocument()->GetLine( nRow );
-
- CClientDC dc( this );
- dc.SelectObject( *ColoredFontGet() );
-
- while( nCol < sLine.GetLength() )
- {
- CSize size = dc.GetTabbedTextExtent( (const char*) sLine,
- nCol + 1,
- sLine.GetFormat().GetTabStops(),
- (int*) sLine.GetFormat().GetTabStopPositionsPixel( dc ) );
-
- if( size.cx > pt.x )
- {
- break;
- }
-
- nCol++;
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::SetCurPos( int nCol, int nRow, BOOL bMoveCaret, BOOL bClearSelection )
- {
- // convienince values
-
- if( CURRENT_VALUE == nCol )
- {
- nCol = m_nCurCol;
- }
-
- if( CURRENT_VALUE == nRow )
- {
- nRow = m_nCurRow;
- }
-
- // check and correct position values
-
- nRow = min( nRow, GetDocument()->GetMaxLines() - 1 );
- nRow = max( nRow, 0 );
-
- COutputLine& sLine = GetDocument()->GetLine( nRow );
-
- nCol = min( nCol, sLine.GetLength() );
- nCol = max( nCol, 0 );
-
- // check for selection
-
- if( bClearSelection )
- {
- if( m_bWhileSelecting )
- {
- InvalidateSelRange();
- m_bWhileSelecting = FALSE;
- }
-
- m_nSelCol = nCol;
- m_nSelRow = nRow;
- }
- else
- {
- m_bWhileSelecting = TRUE;
- InvalidateNewRange( nCol, nRow );
- }
-
- // now remember position
-
- m_nCurCol = nCol;
- m_nCurRow = nRow;
-
- // move the caret if neccessary
-
- if( bMoveCaret )
- {
- MoveCaretToCurPos();
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::SetCurPos( CPoint pt, BOOL bMoveCaret, BOOL bClearSelection )
- {
- pt.x += GetDeviceScrollPosition().x;
- pt.y += GetDeviceScrollPosition().y;
-
- int nCol;
- int nRow;
-
- CharCoordsFromVirtPoint( pt, nCol, nRow );
-
- SetCurPos( nCol, nRow, bMoveCaret, bClearSelection );
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::MoveCaretToCurPos()
- {
- HideCaret();
- CPoint ptCaret = GetCaretPos();
- InvalidateRect( CRect( ptCaret, CSize( CARET_WIDTH, CARET_HEIGHT ) ) );
-
- CPoint pt = VirtCharPosFromCoords( m_nCurCol, m_nCurRow );
- AdjustScrollToVirtPoint( pt );
-
- pt.x -= GetDeviceScrollPosition().x;
- pt.y -= GetDeviceScrollPosition().y;
-
- SetCaretPos( pt );
-
- ShowCaret();
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- CString COutputView::GetCurRowAsString()
- {
- return( GetDocument()->GetLine( m_nCurRow ) );
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- BOOL COutputView::GetSelForRow( int nRow, int& nStartCol, int& nEndCol ) const
- {
- nStartCol = 0;
- nEndCol = 0;
-
- int nSelStartCol, nSelEndCol, nSelStartRow, nSelEndRow;
- GetSelRange( nSelStartCol, nSelStartRow, nSelEndCol, nSelEndRow );
-
- if( ( nRow < nSelStartRow ) || ( nRow > nSelEndRow ) )
- {
- return( FALSE );
- }
-
- if( nRow == nSelStartRow )
- {
- nStartCol = nSelStartCol;
- }
-
- if( nRow == nSelEndRow )
- {
- nEndCol = nSelEndCol;
- }
-
- if( nRow < nSelEndRow )
- {
- nEndCol = ENDOFLINE;
- }
-
- return( TRUE );
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::InvalidateSelRange()
- {
- int nStartCol, nStartRow, nEndCol, nEndRow;
- GetSelRange( nStartCol, nStartRow, nEndCol, nEndRow );
-
- InvalidateRange( nStartCol, nStartRow, nEndCol, nEndRow );
- }
-
- void COutputView::InvalidateNewRange( int nCol, int nRow )
- {
- int nStartCol, nStartRow, nEndCol, nEndRow;
-
- if( m_nCurRow < nRow )
- {
- nStartRow = m_nCurRow;
- nStartCol = m_nCurCol;
-
- nEndRow = nRow;
- nEndCol = nCol;
- }
- else if( m_nCurRow > nRow )
- {
- nStartRow = nRow;
- nStartCol = nCol;
-
- nEndRow = m_nCurRow;
- nEndCol = m_nCurCol;
- }
- else
- {
- nStartRow = nRow;
- nStartCol = min( m_nCurCol, nCol );
-
- nEndRow = m_nCurRow;
- nEndCol = max( m_nCurCol, nCol );
- }
-
- InvalidateRange( nStartCol, nStartRow, nEndCol, nEndRow );
- }
-
- void COutputView::InvalidateRange( int nStartCol, int nStartRow, int nEndCol, int nEndRow )
- {
- if( !::IsWindow( m_hWnd ) )
- {
- return;
- }
-
- CPoint ptScroll = GetDeviceScrollPosition();
-
- CPoint ptStart = VirtCharPosFromCoords( nStartCol, nStartRow );
- ptStart.x -= ptScroll.x;
- ptStart.y -= ptScroll.y;
-
- CPoint ptEnd = VirtCharPosFromCoords( nEndCol, nEndRow );
- ptEnd.x -= ptScroll.x;
- ptEnd.y -= ptScroll.y;
-
- CRect rect;
- rect.top = ptStart.y;
- rect.bottom = ptEnd.y + m_nRowHeight;
-
- if( nStartRow == nEndRow )
- {
- rect.left = ptStart.x;
- rect.right = ptEnd.x;
- }
- else
- {
- CRect rectClient;
- GetClientRect( rectClient );
-
- rect.left = 0;
- rect.right = rectClient.Width();
- }
-
- InvalidateRect( rect, FALSE );
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- BOOL COutputView::GetSelRange( int& nSelStartCol, int& nSelStartRow, int& nSelEndCol, int& nSelEndRow ) const
- {
- if( m_nCurRow < m_nSelRow )
- {
- nSelStartRow = m_nCurRow;
- nSelStartCol = m_nCurCol;
-
- nSelEndRow = m_nSelRow;
- nSelEndCol = m_nSelCol;
- }
- else if( m_nCurRow > m_nSelRow )
- {
- nSelStartRow = m_nSelRow;
- nSelStartCol = m_nSelCol;
-
- nSelEndRow = m_nCurRow;
- nSelEndCol = m_nCurCol;
- }
- else
- {
- nSelStartRow = m_nSelRow;
- nSelStartCol = min( m_nCurCol, m_nSelCol );
-
- nSelEndRow = m_nCurRow;
- nSelEndCol = max( m_nCurCol, m_nSelCol );
- }
-
- return( ( nSelStartCol != nSelEndRow ) || ( nSelStartCol != nSelEndCol ) );
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::GetSelectedText( CString& strResult )
- {
- int nSelStartCol, nSelEndCol, nSelStartRow, nSelEndRow;
- GetSelRange( nSelStartCol, nSelStartRow, nSelEndCol, nSelEndRow );
-
- if( nSelStartRow == nSelEndRow )
- {
- strResult = GetDocument()->GetLine( nSelStartRow ).Mid( nSelStartCol, nSelEndCol - nSelStartCol );
- }
- else
- {
- strResult = GetDocument()->GetLine( nSelStartRow ).Mid( nSelStartCol );
-
- for( int nRow = nSelStartRow + 1; nRow < nSelEndRow; nRow++ )
- {
- strResult += CString( "\r\n" );
- strResult += GetDocument()->GetLine( nRow );
- }
-
- strResult += CString( "\r\n" );
- strResult += GetDocument()->GetLine( nSelEndRow ).Left( nSelEndCol );
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::AdjustScrollToVirtPoint( CPoint ptVirt )
- {
- CPoint ptScroll = GetDeviceScrollPosition();
- CPoint ptCaret = ptVirt - ptScroll;
- CRect rectCaret( ptCaret, CSize( CARET_WIDTH, CARET_HEIGHT ) );
-
- CRect rectClient;
- GetClientRect( rectClient );
-
- // rectCaret fully contained in rectClient ??
-
- CRect rectIntersect;
- rectIntersect.IntersectRect( rectClient, rectCaret );
-
- if( rectCaret == rectIntersect )
- {
- return;
- }
-
- int nMapMode;
- CSize sizeTotal, sizePage, sizeLine;
-
- GetDeviceScrollSizes( nMapMode, sizeTotal, sizePage, sizeLine );
- //sizePage.cx -= sizeLine.cx;
- //sizePage.cy -= sizeLine.cy;
-
- // maybe scroll a char to the left
-
- if( ( rectCaret.left < rectClient.left ) && ( rectCaret.left >= rectClient.left - sizeLine.cx ) &&
- ( rectCaret.top >= rectClient.top ) && ( rectCaret.bottom <= rectClient.bottom ) )
- {
- ptScroll.x -= sizeLine.cx;
- }
-
- // maybe scroll a char to the right
-
- else if( ( rectCaret.right > rectClient.right ) && ( rectCaret.right <= rectClient.right + sizeLine.cx ) &&
- ( rectCaret.top >= rectClient.top ) && ( rectCaret.bottom <= rectClient.bottom ) )
- {
- ptScroll.x += sizeLine.cx;
- }
-
- // maybe scroll a page to the left
-
- else if( ( rectCaret.left < rectClient.left ) && ( rectCaret.left > rectClient.left - sizePage.cx ) &&
- ( rectCaret.top >= rectClient.top ) && ( rectCaret.bottom <= rectClient.bottom ) )
-
- {
- ptScroll.x -= sizePage.cx;
- }
-
- // maybe scroll a page to the right
-
- else if( ( rectCaret.right > rectClient.right ) && ( rectCaret.right < rectClient.right + sizePage.cx ) &&
- ( rectCaret.top >= rectClient.top ) && ( rectCaret.bottom <= rectClient.bottom ) )
-
- {
- ptScroll.x += sizePage.cx;
- }
-
- // maybe scroll a line up
-
- else if( ( rectCaret.top < rectClient.top ) && ( rectCaret.top >= rectClient.top - sizeLine.cy ) &&
- ( rectCaret.left >= rectClient.left ) && ( rectCaret.right <= rectClient.right ) )
-
- {
- ptScroll.y -= sizeLine.cy;
- }
-
- // maybe scroll a line down
-
- else if( ( rectCaret.bottom > rectClient.bottom ) && ( rectCaret.bottom <= rectClient.bottom + sizeLine.cy ) &&
- ( rectCaret.left >= rectClient.left ) && ( rectCaret.right <= rectClient.right ) )
- {
- ptScroll.y += sizeLine.cy;
- }
-
- // maybe scroll a page up
-
- else if( ( rectCaret.top < rectClient.top ) && ( rectCaret.top > rectClient.top - sizePage.cy ) &&
- ( rectCaret.left >= rectClient.left ) && ( rectCaret.right <= rectClient.right ) )
- {
- ptScroll.y -= sizePage.cy;
- }
-
- // maybe scroll a page down
-
- else if( ( rectCaret.bottom > rectClient.bottom ) && ( rectCaret.bottom < rectClient.bottom + sizePage.cy ) &&
- ( rectCaret.left >= rectClient.left ) && ( rectCaret.right <= rectClient.right ) )
- {
- ptScroll.y += sizePage.cy;
- }
-
- // otherwise position direct
-
- else
- {
- ptScroll = ptVirt;
-
- // as far left as possible
-
- ptScroll.x -= ( rectClient.Width() - sizeLine.cx );
- ptScroll.x = max( 0, ptScroll.x );
- }
-
- ptScroll.x = max( 0, ptScroll.x );
- ptScroll.y = max( 0, ptScroll.y );
-
- ScrollToDevicePosition( ptScroll );
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::OnEditCopy()
- {
- CString sSelText;
- GetSelectedText( sSelText );
-
- if( ::OpenClipboard( m_hWnd ) )
- {
- HGLOBAL hData = ::GlobalAlloc( GHND, sSelText.GetLength() + 1 );
- char* psz = (char*) ::GlobalLock( hData );
- ASSERT( NULL != psz );
- strcpy( psz, (const char*) sSelText );
- ::GlobalUnlock( hData );
-
- ::SetClipboardData( CF_TEXT, hData );
- ::CloseClipboard();
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////
-
- void COutputView::OnUpdateEditCopy(CCmdUI* pCmdUI)
- {
- int nSelStartCol, nSelEndCol, nSelStartRow, nSelEndRow;
- GetSelRange( nSelStartCol, nSelStartRow, nSelEndCol, nSelEndRow );
-
- pCmdUI->Enable( ( nSelStartRow != nSelEndRow ) || ( nSelStartCol != nSelEndCol ) );
- }
-