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

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // File        : MsgTracerApp.cpp
  4. // Project     : MsgTrace
  5. // Component   : MsgTracer
  6. //---------------------------------------------------------------------------
  7. // Description : the trtacer application
  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 "resource.h"
  21. #include "initguid.h"
  22. #include "MsgTracer.h"
  23. #include "MsgTracerApp.h"
  24.  
  25. #include "MsgTracer_i.c"
  26. #include "MsgTracerComp.h"
  27.  
  28. #include "MainFrm.h"
  29. #include "OutputDoc.h"
  30. #include "OutputView.h"
  31.  
  32. #include "AboutDlg.h"
  33. #include "AttachDlg.h"
  34. #include "SettingsDlg.h"
  35.  
  36. #include "MsgTracerThread.h"
  37. #include "MsgTracerProcess.h"
  38.  
  39. /////////////////////////////////////////////////////////////////////////////
  40.  
  41. #define MSG_TRACER_RUNNING_EVENT "MsgTracerRunningEvent"
  42.  
  43. /////////////////////////////////////////////////////////////////////////////
  44. // ATL Module
  45. /////////////////////////////////////////////////////////////////////////////
  46.  
  47. CComModule _Module;
  48.  
  49. BEGIN_OBJECT_MAP(ObjectMap)
  50.     OBJECT_ENTRY(CLSID_MsgTracerComp, CMsgTracerComp)
  51. END_OBJECT_MAP()
  52.  
  53. /////////////////////////////////////////////////////////////////////////////
  54. // static helpers
  55. /////////////////////////////////////////////////////////////////////////////
  56.  
  57. static LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2)
  58. {
  59.     while (*p1 != NULL)
  60.     {
  61.         LPCTSTR p = p2;
  62.         while (*p != NULL)
  63.         {
  64.             if (*p1 == *p++)
  65.                 return p1+1;
  66.         }
  67.         p1++;
  68.     }
  69.     return( NULL );
  70. }
  71.  
  72. /////////////////////////////////////////////////////////////////////////////
  73. // CMsgTracerApp
  74. /////////////////////////////////////////////////////////////////////////////
  75.  
  76. CMsgTracerApp theApp;
  77.  
  78. BEGIN_MESSAGE_MAP(CMsgTracerApp, CWinApp)
  79.     //{{AFX_MSG_MAP(CMsgTracerApp)
  80.     ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
  81.     ON_COMMAND(ID_TRACE_ATTACH, OnTraceAttach)
  82.     ON_COMMAND(ID_TRACE_SETTINGS, OnTraceSettings)
  83.     ON_COMMAND(ID_TRACE_CONTINUE, OnTraceContinue)
  84.     ON_UPDATE_COMMAND_UI(ID_TRACE_CONTINUE, OnUpdateTraceContinue)
  85.     ON_COMMAND(ID_TRACE_PAUSE, OnTracePause)
  86.     ON_UPDATE_COMMAND_UI(ID_TRACE_PAUSE, OnUpdateTracePause)
  87.     ON_UPDATE_COMMAND_UI(ID_INDICATOR_RUNNING, OnUpdateIndicatorRun)
  88.     ON_UPDATE_COMMAND_UI(ID_INDICATOR_PROCESS, OnUpdateIndicatorProcess)
  89.     //}}AFX_MSG_MAP
  90.     ON_COMMAND(ID_HELP, CWinApp::OnHelp)
  91. END_MESSAGE_MAP()
  92.  
  93. /////////////////////////////////////////////////////////////////////////////
  94. // CMsgTracerApp construction
  95. /////////////////////////////////////////////////////////////////////////////
  96.  
  97. CMsgTracerApp::CMsgTracerApp() : 
  98.  
  99.     m_hRunningEvent( NULL ),
  100.     m_bFactoriedRegistered( FALSE ),
  101.  
  102.     m_pOutputDoc( NULL ),
  103.     m_pOutputTemplate( NULL ),
  104.  
  105.     m_bAllowAutoAttach( FALSE ),
  106.     m_bShowOnStartup( TRUE ),
  107.     m_nTimeoutWaitForDebugEvent( 5000 ),
  108.     m_nBufferedLines( 200 )
  109.  
  110. {
  111.     m_pTracerThread = new CMsgTracerThread;
  112.     m_pProcessList = new CMsgTracerProcessList;
  113. }
  114.  
  115. /////////////////////////////////////////////////////////////////////////////
  116.  
  117. CMsgTracerApp::~CMsgTracerApp()
  118. {
  119.     if( NULL != m_hRunningEvent )
  120.     {
  121.         CloseHandle( m_hRunningEvent );
  122.     }
  123.  
  124.     delete m_pTracerThread;
  125.     m_pTracerThread = NULL;
  126.  
  127.     delete m_pProcessList;
  128.     m_pProcessList = NULL;
  129. }
  130.  
  131. /////////////////////////////////////////////////////////////////////////////
  132. // CMsgTracerApp Initialisierung
  133. /////////////////////////////////////////////////////////////////////////////
  134.  
  135. BOOL CMsgTracerApp::InitInstance()
  136. {
  137.     //-----------------------------------------------------------------------
  138.     // only one instance allowed!
  139.     //-----------------------------------------------------------------------
  140.  
  141.     if( IsTracerAlreadyRunning() )
  142.     {
  143.         return( FALSE );
  144.     }
  145.  
  146.     //-----------------------------------------------------------------------
  147.     // settings are read from registry
  148.     //-----------------------------------------------------------------------
  149.  
  150.     SetRegistryKey( _T( "msg" ) );
  151.     ReadSettings();
  152.  
  153.     //-----------------------------------------------------------------------
  154.     // Initialize COM and ATL (apartment - for easier MFC access)
  155.     //-----------------------------------------------------------------------
  156.  
  157.     HRESULT hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );
  158.     _ASSERTE( SUCCEEDED( hr ) );
  159.  
  160.     HINSTANCE hInstance = AfxGetInstanceHandle();
  161.     _Module.Init( ObjectMap, hInstance );
  162.  
  163.     //-----------------------------------------------------------------------
  164.     // Check commandine arguments
  165.     //-----------------------------------------------------------------------
  166.  
  167.     TCHAR szTokens[] = _T("-/");
  168.     LPCTSTR lpCmdLine = GetCommandLine();
  169.     LPCTSTR lpszToken = FindOneOf( lpCmdLine, szTokens );
  170.     
  171.     while( lpszToken != NULL )
  172.     {
  173.         if( 0 == lstrcmpi( lpszToken, _T( "UnregServer" ) ) )
  174.         {
  175.             _Module.UpdateRegistryFromResource( IDR_MsgTracer, FALSE );
  176.             _Module.UnregisterServer();
  177.             return( FALSE );
  178.         }
  179.         if( 0 == lstrcmpi( lpszToken, _T( "RegServer" ) ) )
  180.         {
  181.             _Module.UpdateRegistryFromResource( IDR_MsgTracer, TRUE );
  182.             // typelib sits in MsgTracerPS
  183.             _Module.RegisterServer( FALSE );
  184.             return( FALSE );
  185.         }
  186.  
  187.         lpszToken = FindOneOf( lpszToken, szTokens );
  188.     }
  189.  
  190.     //-----------------------------------------------------------------------
  191.     // create main window
  192.     //-----------------------------------------------------------------------
  193.  
  194. #ifdef _AFXDLL
  195.     Enable3dControls();
  196. #else
  197.     Enable3dControlsStatic();
  198. #endif
  199.  
  200.     m_pOutputTemplate = new CSingleDocTemplate(
  201.         IDR_MAINFRAME,
  202.         RUNTIME_CLASS(COutputDoc),
  203.         RUNTIME_CLASS(CMainFrame),       // main SDI frame window
  204.         RUNTIME_CLASS(COutputView));
  205.  
  206.     AddDocTemplate( m_pOutputTemplate );
  207.  
  208.     m_pOutputDoc = (COutputDoc*) m_pOutputTemplate->OpenDocumentFile( NULL, FALSE );
  209.  
  210.     if( NULL == m_pOutputDoc )
  211.     {
  212.         return( FALSE );
  213.     }
  214.  
  215.     if( m_bShowOnStartup )
  216.     {
  217.         m_pMainWnd->ShowWindow(SW_SHOW);
  218.         m_pMainWnd->UpdateWindow();
  219.     }
  220.  
  221.     //-----------------------------------------------------------------------
  222.     // now we are ready to create components
  223.     //-----------------------------------------------------------------------
  224.  
  225.     hr = _Module.RegisterClassObjects( CLSCTX_LOCAL_SERVER,  REGCLS_MULTIPLEUSE);
  226.     _ASSERTE( SUCCEEDED( hr ) );
  227.  
  228.     m_bFactoriedRegistered = TRUE;
  229.  
  230.     return( TRUE );
  231. }
  232.  
  233. /////////////////////////////////////////////////////////////////////////////
  234.  
  235. int CMsgTracerApp::ExitInstance()
  236. {
  237.     if( ( NULL != m_pTracerThread ) && m_pTracerThread->IsRunning() )
  238.     {
  239.         m_pTracerThread->Stop();
  240.         m_pTracerThread->Resume();
  241.         m_pTracerThread->IsRunning( INFINITE );
  242.     }
  243.  
  244.     if( m_bFactoriedRegistered )
  245.     {
  246.         _Module.RevokeClassObjects();
  247.     }
  248.  
  249.     CoUninitialize();
  250.  
  251.     return( CWinApp::ExitInstance() );
  252. }
  253.  
  254. /////////////////////////////////////////////////////////////////////////////
  255. // CMsgTracerApp: running stuff
  256. /////////////////////////////////////////////////////////////////////////////
  257.  
  258. BOOL CMsgTracerApp::IsTracerAlreadyRunning()
  259. {
  260.     m_hRunningEvent = OpenEvent( EVENT_ALL_ACCESS, FALSE, MSG_TRACER_RUNNING_EVENT );
  261.  
  262.     if( NULL != m_hRunningEvent )
  263.     {
  264.         SetEvent( m_hRunningEvent );
  265.         CloseHandle( m_hRunningEvent );
  266.         return( TRUE );
  267.     }
  268.  
  269.     m_hRunningEvent = CreateEvent( NULL, TRUE, FALSE, MSG_TRACER_RUNNING_EVENT );
  270.  
  271.     if( NULL != m_hRunningEvent )
  272.     {
  273.         DWORD dwThreadId;
  274.         ::CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE) RunningProc, this, 0, &dwThreadId );
  275.     }
  276.  
  277.     return( FALSE );
  278. }
  279.  
  280. /////////////////////////////////////////////////////////////////////////////
  281.  
  282. DWORD CMsgTracerApp::RunningProc( CMsgTracerApp* pThis )
  283. {
  284.     while( WAIT_OBJECT_0 == WaitForSingleObject( pThis->m_hRunningEvent, INFINITE ) )
  285.     {
  286.         ResetEvent( pThis->m_hRunningEvent );
  287.         ShowWindow( pThis->m_pMainWnd->m_hWnd, SW_RESTORE );
  288.         SetForegroundWindow( pThis->m_pMainWnd->m_hWnd );
  289.     }
  290.  
  291.     return( 0 );
  292. }
  293.  
  294. /////////////////////////////////////////////////////////////////////////////
  295. // CMsgTracerApp command handlers
  296. /////////////////////////////////////////////////////////////////////////////
  297.  
  298. void CMsgTracerApp::OnAppAbout()
  299. {
  300.     CAboutDlg aboutDlg;
  301.     aboutDlg.DoModal();
  302. }
  303.  
  304. /////////////////////////////////////////////////////////////////////////////
  305. // CMsgTracerApp trace stuff
  306. /////////////////////////////////////////////////////////////////////////////
  307.  
  308. void CMsgTracerApp::AttachProcess( DWORD dwProcessId, BOOL bWait )
  309. {
  310.     if( NULL == m_pTracerThread )
  311.     {
  312.         return;
  313.     }
  314.  
  315.     CMsgTracerProcess* pProcess = NULL;
  316.     m_pProcessList->Add( dwProcessId, &pProcess );
  317.     
  318.     if( NULL != pProcess )
  319.     {
  320.         m_pTracerThread->AttachProcess( pProcess, bWait );
  321.     }
  322. }
  323.  
  324. /////////////////////////////////////////////////////////////////////////////
  325.  
  326. HANDLE CMsgTracerApp::ProcessIdToHandle( DWORD dwProcessId )
  327. {
  328.     CMsgTracerProcess* pProcess = m_pProcessList->Find( dwProcessId );
  329.  
  330.     if( NULL == pProcess )
  331.     {
  332.         return( NULL );
  333.     }
  334.  
  335.     return( pProcess->GetProcessHandle() );
  336. }
  337.  
  338. /////////////////////////////////////////////////////////////////////////////
  339.  
  340. BOOL CMsgTracerApp::IsAttached( DWORD dwProcessId, CMsgTracerProcess** pp )
  341. {
  342.     CMsgTracerProcess* pProcess = m_pProcessList->Find( dwProcessId );
  343.  
  344.     if( NULL != pp )
  345.     {
  346.         *pp = pProcess;
  347.     }
  348.  
  349.     return( NULL != pProcess );
  350. }
  351.  
  352. /////////////////////////////////////////////////////////////////////////////
  353.  
  354. CMsgTracerProcessList* CMsgTracerApp::GetAttachedProcessList()
  355. {
  356.     return( m_pProcessList );
  357. }
  358.  
  359. /////////////////////////////////////////////////////////////////////////////
  360.  
  361. void CMsgTracerApp::OnTraceAttach() 
  362. {
  363.     CAttachDlg dlg;
  364.     dlg.DoModal();    
  365. }
  366.  
  367. /////////////////////////////////////////////////////////////////////////////
  368.  
  369. BOOL CMsgTracerApp::IsTracePaused()
  370. {
  371.     return( !m_pTracerThread->m_bWantOutputDebugStringEvents );
  372. }
  373.  
  374. /////////////////////////////////////////////////////////////////////////////
  375.  
  376. void CMsgTracerApp::OnUpdateIndicatorRun( CCmdUI* pCmdUI )
  377. {
  378.     CString s;
  379.     s.LoadString( m_pTracerThread->m_bWantOutputDebugStringEvents ? 
  380.                   ID_INDICATOR_RUNNING : 
  381.                   ID_INDICATOR_STOPPED );
  382.  
  383.     pCmdUI->SetText( s );
  384. }
  385.  
  386. /////////////////////////////////////////////////////////////////////////////
  387.  
  388. void CMsgTracerApp::OnUpdateIndicatorProcess( CCmdUI* pCmdUI )
  389. {
  390.     COutputView* pView =
  391.         (COutputView*) ( (CFrameWnd*) AfxGetMainWnd() )->GetActiveView();
  392.  
  393.     ASSERT( NULL != pView );
  394.  
  395.     CString s = pView->GetCurRowAsString();
  396.  
  397.     if( !s.IsEmpty() )
  398.     {
  399.         DWORD dwProcessId = strtol( ( (LPCSTR) s ) + 1, NULL, 16 );
  400.         CMsgTracerProcess* pProcess = NULL;
  401.  
  402.         if( IsAttached( dwProcessId, &pProcess ) )
  403.         {
  404.             s = pProcess->GetBaseName();
  405.         }
  406.         else
  407.         {
  408.             s.Empty();
  409.         }
  410.     }
  411.  
  412.     pCmdUI->SetText( s );
  413. }
  414.  
  415. /////////////////////////////////////////////////////////////////////////////
  416.  
  417. void CMsgTracerApp::OnTraceContinue() 
  418. {
  419.     m_pTracerThread->m_bWantOutputDebugStringEvents = TRUE;
  420.  
  421.     CString s;
  422.     s.LoadString( IDS_TRACE_CONTINUED );
  423.     m_pOutputDoc->AddLine( s );
  424. }
  425.  
  426. /////////////////////////////////////////////////////////////////////////////
  427.  
  428. void CMsgTracerApp::OnUpdateTraceContinue(CCmdUI* pCmdUI) 
  429. {
  430.     pCmdUI->Enable( !m_pTracerThread->m_bWantOutputDebugStringEvents );
  431. }
  432.  
  433. /////////////////////////////////////////////////////////////////////////////
  434.  
  435. void CMsgTracerApp::OnTracePause() 
  436. {
  437.     m_pTracerThread->m_bWantOutputDebugStringEvents = FALSE;
  438.  
  439.     CString s;
  440.     s.LoadString( IDS_TRACE_PAUSED );
  441.     m_pOutputDoc->AddLine( s );
  442. }
  443.  
  444. /////////////////////////////////////////////////////////////////////////////
  445.  
  446. void CMsgTracerApp::OnUpdateTracePause(CCmdUI* pCmdUI) 
  447. {
  448.     pCmdUI->Enable( m_pTracerThread->m_bWantOutputDebugStringEvents );
  449. }
  450.  
  451. /////////////////////////////////////////////////////////////////////////////
  452.  
  453. void CMsgTracerApp::WriteOutput( LPCTSTR lpszMessage )
  454. {
  455.     if( m_pTracerThread->m_bWantOutputDebugStringEvents )
  456.     {
  457.         m_pOutputDoc->AddLine( lpszMessage );
  458.     }
  459. }
  460.  
  461. /////////////////////////////////////////////////////////////////////////////
  462. // CMsgTracerApp settings stuff
  463. /////////////////////////////////////////////////////////////////////////////
  464.  
  465. void CMsgTracerApp::OnTraceSettings() 
  466. {
  467.     CSettingsDlg dlg;
  468.  
  469.     dlg.m_bAllowAutoAttach = m_bAllowAutoAttach;
  470.     dlg.m_bShowOnStartup = m_bShowOnStartup;
  471.     dlg.m_nTimeoutWaitForDebugEvent = m_nTimeoutWaitForDebugEvent;
  472.     dlg.m_nBufferedLines = m_nBufferedLines;
  473.  
  474.     if( IDOK == dlg.DoModal() )
  475.     {
  476.         m_bAllowAutoAttach = dlg.m_bAllowAutoAttach;
  477.         m_bShowOnStartup = dlg.m_bShowOnStartup;
  478.         m_nTimeoutWaitForDebugEvent = dlg.m_nTimeoutWaitForDebugEvent;
  479.         m_nBufferedLines = dlg.m_nBufferedLines;
  480.  
  481.         WriteSettings();
  482.         m_pOutputDoc->SetMaxBufferedLines( m_nBufferedLines );
  483.     }
  484. }
  485.  
  486. /////////////////////////////////////////////////////////////////////////////
  487.  
  488. void CMsgTracerApp::ReadSettings()
  489. {
  490.     m_bAllowAutoAttach = GetProfileInt( "Settings", "AllowAutoAttach", m_bAllowAutoAttach  );
  491.     m_bShowOnStartup = GetProfileInt( "Settings", "ShowOnStartup", m_bShowOnStartup );
  492.     m_nTimeoutWaitForDebugEvent = GetProfileInt( "Settings", "TimeoutWaitForDebugEvent", m_nTimeoutWaitForDebugEvent );
  493.     m_nBufferedLines = GetProfileInt( "Settings", "BufferedLines", 1000 );
  494. }
  495.  
  496. /////////////////////////////////////////////////////////////////////////////
  497.  
  498. void CMsgTracerApp::WriteSettings()
  499. {
  500.     WriteProfileInt( "Settings", "AllowAutoAttach", (int) m_bAllowAutoAttach );
  501.     WriteProfileInt( "Settings", "ShowOnStartup", (int) m_bShowOnStartup );
  502.     WriteProfileInt( "Settings", "TimeoutWaitForDebugEvent", m_nTimeoutWaitForDebugEvent );
  503.     WriteProfileInt( "Settings", "BufferedLines", m_nBufferedLines );
  504. }
  505.  
  506.