home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 23 / IOPROG_23.ISO / SOFT / MSGTRACE.ZIP / MyProjects / MsgTrace / MsgTracer / OutputDoc.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-05-30  |  7.7 KB  |  320 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // File        : OutputDoc.cpp
  4. // Project     : MsgTrace
  5. // Component   : MsgTracer
  6. //---------------------------------------------------------------------------
  7. // Description : output-document
  8. //
  9. /////////////////////////////////////////////////////////////////////////////
  10. //
  11. // SourceSafe Strings. Do not change.
  12. //---------------------------------------------------------------------------
  13. // $Author: jeskes $
  14. // $Date: $
  15. // $Revision: $
  16. //
  17. /////////////////////////////////////////////////////////////////////////////
  18.  
  19. #include "stdafx.h"
  20. #include "MsgTracerApp.h"
  21. #include "OutputDoc.h"
  22. #include "OutputLine.h"
  23.  
  24. /////////////////////////////////////////////////////////////////////////////
  25.  
  26. #ifdef _DEBUG
  27. #undef THIS_FILE
  28. static char BASED_CODE THIS_FILE[] = __FILE__;
  29. #endif
  30.  
  31. /////////////////////////////////////////////////////////////////////////////
  32.  
  33. #define CMD_EXT_UPDATE_ALL_VIEWS (999)
  34.  
  35. /////////////////////////////////////////////////////////////////////////////
  36. // COutputDoc
  37. /////////////////////////////////////////////////////////////////////////////
  38.  
  39. IMPLEMENT_SERIAL(COutputDoc, CDocument, 0 /* schema number*/ )
  40.  
  41. BEGIN_MESSAGE_MAP(COutputDoc, CDocument)
  42.     //{{AFX_MSG_MAP(COutputDoc)
  43.     ON_COMMAND(ID_EDIT_CLEAR_ALL, OnEditClearAll)
  44.     //}}AFX_MSG_MAP
  45.     ON_COMMAND_EX( CMD_EXT_UPDATE_ALL_VIEWS, OnExtUpdateAllViews )
  46. END_MESSAGE_MAP()
  47.  
  48. /////////////////////////////////////////////////////////////////////////////
  49. // COutputDoc construction
  50. /////////////////////////////////////////////////////////////////////////////
  51.  
  52. COutputDoc::COutputDoc() :
  53.  
  54.     m_nMaxBufferedLines( ThisApp().m_nBufferedLines ),
  55.     m_psLineArray( NULL ),
  56.     m_nMaxLines( 0 ),
  57.     m_nNextFreeLine( 0 ),
  58.     m_nMaxLineLen( 80 ),
  59.     m_pCurrentFormat( NULL )
  60.  
  61. {
  62.     m_pCurrentFormat = new COutputLineFormat;
  63. }
  64.  
  65. /////////////////////////////////////////////////////////////////////////////
  66.  
  67. COutputDoc::~COutputDoc()
  68. {
  69.     delete[] m_psLineArray;
  70.     m_psLineArray = NULL;
  71.  
  72.     delete m_pCurrentFormat;
  73.     m_pCurrentFormat = NULL;
  74. }
  75.  
  76. /////////////////////////////////////////////////////////////////////////////
  77.  
  78. BOOL COutputDoc::OnNewDocument()
  79. {
  80.     if( !CDocument::OnNewDocument() )
  81.     {
  82.         return( FALSE );
  83.     }
  84.     
  85.     //-----------------------------------------------------------------------
  86.     // setup some things
  87.     //-----------------------------------------------------------------------
  88.  
  89.     m_nMaxLines = 0;
  90.     m_nNextFreeLine = 0;
  91.     m_nMaxLineLen = 80;
  92.     
  93.     m_psLineArray = new COutputLine[ m_nMaxBufferedLines ];
  94.     
  95.     return( NULL != m_psLineArray );
  96. }
  97.  
  98. /////////////////////////////////////////////////////////////////////////////
  99.  
  100. void COutputDoc::DeleteContents()
  101. {
  102.     CDocument::DeleteContents();
  103.  
  104.     if( NULL != m_psLineArray )
  105.     {
  106.         delete [] m_psLineArray;
  107.         m_psLineArray = NULL;
  108.     }
  109. }
  110.  
  111. /////////////////////////////////////////////////////////////////////////////
  112.  
  113. void COutputDoc::Serialize( CArchive& ar )
  114. {
  115.     if( !ar.IsStoring() )
  116.     {
  117.         return;
  118.     }
  119.  
  120.     // support only writing to file
  121.  
  122.     for( int n = 0; n < m_nMaxLines; n++ )
  123.     {
  124.         CString& sLine = GetLine( n );
  125.         
  126.         ar.Write( (const char*) sLine, sLine.GetLength() );
  127.         ar << (BYTE) '\r' << (BYTE) '\n';
  128.     }
  129. }
  130.  
  131. /////////////////////////////////////////////////////////////////////////////
  132. // max-buffered-lines
  133. /////////////////////////////////////////////////////////////////////////////
  134.  
  135. void COutputDoc::SetMaxBufferedLines( int nMaxBufferedLines )
  136. {
  137.     if( m_nMaxBufferedLines != nMaxBufferedLines )
  138.     {
  139.         m_nMaxBufferedLines = nMaxBufferedLines;
  140.         OnEditClearAll();
  141.     }
  142. }
  143.  
  144. /////////////////////////////////////////////////////////////////////////////
  145. // Current Format for Output Lines
  146. /////////////////////////////////////////////////////////////////////////////
  147.  
  148. void COutputDoc::InitTabStops( int nTabStops )
  149. {
  150.     m_pCurrentFormat->InitTabStops( nTabStops );
  151. }
  152.  
  153. void COutputDoc::SetTabStop( int nIndex, int nTabPos )
  154. {
  155.     m_pCurrentFormat->SetTabStop( nIndex, nTabPos );
  156. }
  157.  
  158. const COutputLineFormat& COutputDoc::GetCurrentFormat() const
  159. {
  160.     return( *m_pCurrentFormat );
  161. }
  162.  
  163. /////////////////////////////////////////////////////////////////////////////
  164. // COutputDoc line stuff
  165. /////////////////////////////////////////////////////////////////////////////
  166.  
  167. void COutputDoc::AddLine( LPCSTR lpsz )
  168. {
  169.     CSingleLock lock( &m_mutexAddLine );
  170.     if( !lock.Lock( 1000 ) )
  171.     {
  172.         return;
  173.     }
  174.  
  175.     LPSTR lpszText = (LPSTR) lpsz;
  176.     
  177.     if( NULL == lpszText )
  178.     {
  179.         lpszText = "";
  180.     }
  181.  
  182.     LPSTR lpszLF = strchr( lpszText, '\n' );
  183.     
  184.     if( NULL != lpszLF )
  185.     {
  186.         int nLen = (int)(DWORD)( lpszLF - lpszText );
  187.  
  188.         if( 0 < nLen )
  189.         {
  190.             if( '\r' == lpszText[ nLen - 1 ] )
  191.             {
  192.                 nLen--;
  193.             }
  194.         }
  195.                 
  196.         if( 0 == nLen )
  197.         {
  198.             m_psLineArray[ m_nNextFreeLine ] = "";
  199.         }    
  200.         else
  201.         {
  202.             LPSTR lpszTemp = 
  203.                 m_psLineArray[ m_nNextFreeLine ].GetBufferSetLength( nLen + 1 );
  204.                 
  205.             lstrcpyn( lpszTemp, lpszText, nLen + 1 );
  206.             m_psLineArray[ m_nNextFreeLine ].ReleaseBuffer();
  207.         }
  208.     }
  209.     else
  210.     {
  211.         // ignore empty lines
  212.         if( '\0' == *lpszText )
  213.         {
  214.             return;
  215.         }
  216.         m_psLineArray[ m_nNextFreeLine ] = lpszText;
  217.     }
  218.  
  219.     
  220.     m_psLineArray[ m_nNextFreeLine ].SetFormat( GetCurrentFormat() );
  221.     
  222.     m_nMaxLines = min( m_nMaxLines + 1, m_nMaxBufferedLines );
  223.        m_nMaxLineLen = max( m_nMaxLineLen, lstrlen( lpszText ) );
  224.  
  225.     ThreadSafeUpdateAllViews( NULL, OUTPUTDOC_LINEADDED, (CObject*) &m_psLineArray[ m_nNextFreeLine ] );
  226.     m_nNextFreeLine = ( m_nNextFreeLine + 1 ) % m_nMaxBufferedLines;
  227.        
  228.     if( NULL != lpszLF )
  229.     {
  230.         AddLine( lpszLF + 1 );
  231.     }
  232. }
  233.  
  234. /////////////////////////////////////////////////////////////////////////////
  235.  
  236. COutputLine& COutputDoc::GetLine( int nLine )
  237. {
  238.     if( nLine > m_nMaxLines )
  239.     {
  240.         return( COutputLine( "" ) );
  241.     }
  242.     
  243.     if( m_nMaxLines == m_nMaxBufferedLines )
  244.     {
  245.         nLine = ( m_nNextFreeLine + nLine ) % m_nMaxBufferedLines;
  246.     }
  247.     
  248.     return( m_psLineArray[ nLine ] );
  249. }
  250.  
  251. /////////////////////////////////////////////////////////////////////////////
  252.  
  253. void COutputDoc::OnEditClearAll()
  254. {
  255.     OnNewDocument();
  256.     
  257.     ThreadSafeUpdateAllViews( NULL, OUTPUTDOC_CLEARED, NULL );
  258.  
  259.     CString sMessage;
  260.     sMessage.LoadString( IDS_OUTPUT_CLEARED );
  261.     
  262.     AddLine( sMessage );
  263. }
  264.  
  265. /////////////////////////////////////////////////////////////////////////////
  266.  
  267. void COutputDoc::OnChangedViewList()
  268. {
  269. }
  270.  
  271. /////////////////////////////////////////////////////////////////////////////
  272.  
  273. HMENU COutputDoc::GetDefaultMenu()
  274. {
  275.     return( NULL );
  276. }
  277.  
  278. /////////////////////////////////////////////////////////////////////////////
  279. // Threadsafe view notifications
  280. /////////////////////////////////////////////////////////////////////////////
  281.  
  282. void COutputDoc::ThreadSafeUpdateAllViews( CView* pView, LPARAM lHint, CObject* pHint )
  283. {
  284.     // if running thread is the main thread normal operation
  285.  
  286.     if( ( AfxGetThread() == AfxGetApp() ) ||
  287.         ( NULL == AfxGetApp()->m_pMainWnd ) || 
  288.         !::IsWindow( AfxGetApp()->m_pMainWnd->m_hWnd ) )
  289.     {
  290.         UpdateAllViews( pView, lHint, pHint );
  291.         return;
  292.     }
  293.  
  294.     CSingleLock lock( &m_mutexThreadSafeUpdateAllViews );
  295.  
  296.     // get m_sUpdateAllViews to do notification
  297.  
  298.     if( !lock.Lock( 5000 ) )
  299.     {
  300.         return;
  301.     }
  302.  
  303.     m_sUpdateAllViews.m_pView = pView;
  304.     m_sUpdateAllViews.m_lHint = lHint;
  305.     m_sUpdateAllViews.m_pHint = pHint;
  306.  
  307.     AfxGetApp()->m_pMainWnd->SendMessage( WM_COMMAND, MAKELONG( CMD_EXT_UPDATE_ALL_VIEWS, 0 ), 0 );
  308. }
  309.  
  310. /////////////////////////////////////////////////////////////////////////////
  311.  
  312. BOOL COutputDoc::OnExtUpdateAllViews( UINT u )
  313. {
  314.     UpdateAllViews( m_sUpdateAllViews.m_pView,
  315.                     m_sUpdateAllViews.m_lHint,
  316.                     m_sUpdateAllViews.m_pHint );
  317.  
  318.     return( TRUE );
  319. }
  320.