home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / addins / brkpntmgr / brkpnts.cpp < prev    next >
C/C++ Source or Header  |  1998-04-03  |  13KB  |  536 lines

  1. // BrkPnts.cpp : Implementation of CBrkPnts
  2. #include "stdafx.h"
  3. #include "resource.h"
  4. #include "Brkpntmgr.h"
  5. #include "BrkPnts.h"
  6. #include "DlgBrkPnts.h"
  7. #include <objmodel\dbgdefs.h>
  8.  
  9. /////////////////////////////////////////////////////////////////////////////
  10. // CBrkPnts
  11.  
  12. CBrkPnts::CBrkPnts()
  13. {
  14.     m_fOutputWnd = FALSE;
  15.     m_fSaveOnlyEnabled = FALSE;
  16.     m_dwAddInID = NULL;
  17.     m_dwAppEvents = NULL;
  18.     m_pDispBrkPnts = NULL;
  19. }
  20.  
  21. CBrkPnts::~CBrkPnts()
  22. {
  23. }
  24.  
  25.  
  26.  
  27. HRESULT CBrkPnts::OnConnection(IApplication* pApp, VARIANT_BOOL bFirstTime, long dwAddInID, VARIANT_BOOL* bOnConnection)
  28. {
  29.     HRESULT hr = S_OK;
  30.     m_spApplication = pApp;
  31.     m_dwAddInID = dwAddInID;
  32.  
  33.     // Connect up to application event sink
  34.     AtlAdvise(pApp, GetUnknown(), IID_IApplicationEvents, &m_dwAppEvents);
  35.  
  36.     // Connect up to debugger event sink
  37.     CComPtr<IDispatch> pDebugger;
  38.     hr = m_spApplication->get_Debugger(&pDebugger);
  39.     if (SUCCEEDED(hr))
  40.         AtlAdvise(pDebugger, GetUnknown(), IID_IDebuggerEvents, &m_dwDbgEvents);
  41.  
  42.     hr = pApp->SetAddInInfo((long)_Module.GetModuleInstance(), 
  43.         static_cast<IBrkPnts*>(this), IDB_TOOLBAR_MEDIUM_BRKPNTS, IDB_TOOLBAR_LARGE_BRKPNTS, dwAddInID);
  44.     LPCTSTR szCommand = _T("Break Point Manager");
  45.     VARIANT_BOOL bRet;
  46.     if (SUCCEEDED(hr))
  47.     {
  48.         hr = pApp->AddCommand(CComBSTR(_T("Break Point Manager\nBreak Point Manager\nBreak Point Manager\nBreak Point Manager")),CComBSTR(_T("BrkPntMgr")), 0, dwAddInID, &bRet);
  49.     }
  50.  
  51.     // Add toolbar buttons only if this is the first time the add-in
  52.     // is being loaded.  Toolbar buttons are automatically remembered
  53.     // by Developer Studio from session to session, so we should only
  54.     // add the toolbar buttons once.
  55.     if (bFirstTime)
  56.     {
  57.         if (SUCCEEDED(hr))
  58.         {
  59.             hr = pApp->AddCommandBarButton(dsGlyph, CComBSTR(_T("Break Point Manager")), dwAddInID);
  60.         }
  61.     }
  62.  
  63.     *bOnConnection = SUCCEEDED(hr) ? VARIANT_TRUE :VARIANT_FALSE;
  64.     return hr;
  65. }
  66.  
  67. HRESULT CBrkPnts::OnDisconnection(VARIANT_BOOL bLastTime)
  68. {
  69.     AtlUnadvise(m_spApplication, IID_IApplicationEvents, m_dwAppEvents);
  70.     AtlUnadvise(m_spApplication, IID_IDebuggerEvents, m_dwDbgEvents);
  71.     return S_OK;
  72. }
  73.  
  74. /////////////////////////////////////////////////////////////////////////////
  75. // Application events
  76. HRESULT CBrkPnts::BeforeBuildStart()
  77. {
  78.     return S_OK;
  79. }
  80. HRESULT CBrkPnts::BuildFinish(long nNumErrors, long nNumWarnings)
  81. {
  82.     return S_OK;
  83. }
  84. HRESULT CBrkPnts::BeforeApplicationShutDown()
  85. {
  86.     return S_OK;
  87. }
  88. HRESULT CBrkPnts::DocumentOpen(IDispatch* theDocument)
  89. {
  90.     return S_OK;
  91. }
  92. HRESULT CBrkPnts::BeforeDocumentClose(IDispatch* theDocument)
  93. {
  94.     return S_OK;
  95. }
  96. HRESULT CBrkPnts::DocumentSave(IDispatch* theDocument)
  97. {
  98.     return S_OK;
  99. }
  100. HRESULT CBrkPnts::NewDocument(IDispatch* theDocument)
  101. {
  102.     return S_OK;
  103. }
  104. HRESULT CBrkPnts::WindowActivate(IDispatch* theWindow)
  105. {
  106.     return S_OK;
  107. }
  108. HRESULT CBrkPnts::WindowDeactivate(IDispatch* theWindow)
  109. {
  110.     return S_OK;
  111. }
  112. HRESULT CBrkPnts::WorkspaceOpen()
  113. {
  114.     return S_OK;
  115. }
  116. HRESULT CBrkPnts::WorkspaceClose()
  117. {
  118.     return S_OK;
  119. }
  120. HRESULT CBrkPnts::NewWorkspace()
  121. {
  122.     return S_OK;
  123. }
  124.  
  125. /////////////////////////////////////////////////////////////////////////////
  126. // Debugger event
  127. HRESULT CBrkPnts::BreakpointHit(IDispatch* pBreakpoint)
  128. {
  129.     return S_OK;
  130. }
  131.  
  132. HRESULT CBrkPnts::GetBrkPnts()
  133. {
  134.     HRESULT hr = S_OK;
  135.     if (m_pDispBrkPnts == NULL)
  136.     {
  137.         CComPtr<IDispatch> pDispDebugger;
  138.         CComQIPtr<IDebugger, &IID_IDebugger> pDebugger;
  139.  
  140.         hr = m_spApplication->get_Debugger(&pDispDebugger);
  141.         pDebugger = pDispDebugger;
  142.         ASSERT(SUCCEEDED(hr));
  143.         if (SUCCEEDED(hr) && pDebugger)
  144.         {
  145.             hr = pDebugger->get_Breakpoints(&m_pDispBrkPnts);
  146.             m_pBrkPnts = m_pDispBrkPnts;
  147.         }
  148.     }
  149.     if (!m_pBrkPnts)
  150.         hr = E_FAIL;
  151.     return(hr);
  152. }
  153.  
  154. HRESULT CBrkPnts::BrkPntMgr()
  155. {
  156.     AFX_MANAGE_STATE(AfxGetStaticModuleState());
  157.     m_spApplication->EnableModeless(VARIANT_FALSE);
  158.     HRESULT hr;
  159.     int iRes;
  160.     CDlgBrkPnts dlgBrkPnts;
  161.  
  162.     hr = GetBrkPnts();
  163.     ASSERT(SUCCEEDED(hr));
  164.     if (m_pBrkPnts)
  165.     {
  166.         dlgBrkPnts.SetBrkPnts(this);
  167.         iRes = dlgBrkPnts.DoModal();
  168.  
  169.     }
  170.     m_spApplication->EnableModeless((VARIANT_BOOL)VARIANT_TRUE);
  171.     return S_OK;
  172. }
  173.  
  174.  
  175. HRESULT CBrkPnts::Save(BOOL fToOutputWindow, LPCTSTR szFile, BOOL fSaveOnlyEnabled, CString& strComment)
  176. {
  177.     long l, cBrks = 0;
  178.     CStringArray rgStrBrks;
  179.     HRESULT hr;
  180.     
  181.     m_strFile = szFile;
  182.     _ASSERTE(m_pBrkPnts);
  183.     hr = m_pBrkPnts->get_Count(&cBrks);
  184.     l = 0;
  185.     rgStrBrks.Add(strComment); // put the comment string first.
  186.     while (l < cBrks)
  187.     {
  188.         CComPtr<IDispatch> pDispBrkPnt;
  189.         CComQIPtr<IBreakpoint, &IID_IBreakpoint> pBrkPnt;
  190.         CComBSTR bstrLocation;
  191.         CComBSTR bstrFile;
  192.         CComBSTR bstrFunction;
  193.         //long lElements;
  194.         short sEnabled;
  195.         //DsWindowsMessage dsWndMsg;
  196.         //long lPassCount;
  197.         CComBSTR bstrExecutable;
  198.         DsBreakpointType lType;
  199.         CComBSTR bstrWndProc;
  200.         CComVariant varItem = l;
  201.         /* Type:
  202.         dsChangedExpression
  203.         dsLocation
  204.         dsLocationWithTrueExpression
  205.         dsLocationWithChangedExpression
  206.         dsMessage
  207.         dsTrueExpression  
  208.         */
  209.  
  210.         hr = m_pBrkPnts->Item(varItem, &pDispBrkPnt);
  211.         pBrkPnt = pDispBrkPnt;
  212.  
  213.         hr = pBrkPnt->get_Enabled(&sEnabled);
  214.         CString strOut, strT;
  215.         CComBSTR bstrT ;
  216.         hr = pBrkPnt->get_Type((long *)&lType);
  217.         hr = pBrkPnt->get_File(&bstrFile);
  218.         hr = pBrkPnt->get_Function(&bstrFunction);
  219.         hr = pBrkPnt->get_Executable(&bstrExecutable);
  220.         hr = pBrkPnt->get_Location(&bstrLocation);
  221.         strOut.Format("%d:",lType);
  222.         bstrT = bstrFile;
  223.         bstrT.Append(_T("("));
  224.         strT = bstrLocation;
  225.         if (strT.GetAt(0) == _T('.'))
  226.             strT.Delete(0); // remove leading "."
  227.         bstrT.Append(strT);
  228.         bstrT.Append(_T("): "));
  229.         bstrT.Append(strOut);
  230.         bstrT.AppendBSTR(bstrExecutable);
  231.         bstrT.Append(_T(";"));
  232.         bstrT.AppendBSTR(bstrFunction);
  233.         bstrT.Append(_T(";"));
  234.         if (fToOutputWindow)
  235.         {
  236.             m_spApplication->PrintToOutputWindow(bstrT);
  237.         }
  238.  
  239.         if (sEnabled || !fSaveOnlyEnabled)
  240.         {
  241.             strT = bstrT;
  242.             rgStrBrks.Add(strT);
  243.         }
  244.         
  245.         l++;
  246.     }
  247.     // save out the breakpoints
  248.     if (!m_strFile.IsEmpty())
  249.     {
  250.         CFile fileBrkList;
  251.         if (m_strFile.ReverseFind(_T('.')) == -1)
  252.         {
  253.             m_strFile += _T(".brk"); // add the missing extension
  254.         }
  255.         TRY
  256.         {
  257.             if (fileBrkList.Open(m_strFile, CFile::modeCreate | CFile::modeWrite))
  258.             {
  259.             CArchive ar( &fileBrkList, CArchive::store);
  260.             
  261.             rgStrBrks.Serialize(ar);
  262.             }
  263.         }
  264.         CATCH(CFileException, e)
  265.         {
  266.             CString strMsg;
  267.             CString strErr;
  268.             e->GetErrorMessage(strErr.GetBuffer(_MAX_PATH), _MAX_PATH);
  269.             strErr.ReleaseBuffer();
  270.             strMsg.Format("%s \n    %s", strErr, m_strFile);
  271.             MessageBox(NULL, strMsg, _T("Breakpoint Files"), MB_OK);
  272.         }
  273.         END_CATCH
  274.     }
  275.     return(S_OK);
  276. }
  277.  
  278. HRESULT CBrkPnts::Load(LPCTSTR szFile, CString& strComment)
  279. {
  280.     CStringArray rgStrBrks, rgStrBrksFailed;
  281.     CString strBrk;
  282.     CComBSTR bstrT;
  283.     HRESULT hr;
  284.  
  285.     m_strFile = szFile;
  286.     if (!m_strFile.IsEmpty())
  287.     {
  288.         CFile fileBrkList;
  289.         if (m_strFile.ReverseFind(_T('.')) == -1)
  290.         {
  291.             m_strFile += _T(".brk"); // add the missing extension
  292.         }
  293.         TRY
  294.         {
  295.             if (fileBrkList.Open(m_strFile, CFile::modeRead))
  296.             {
  297.             CArchive ar( &fileBrkList, CArchive::load);
  298.  
  299.             rgStrBrks.Serialize(ar);
  300.             }
  301.         }
  302.         CATCH(CFileException, e)
  303.         {
  304.             CString strMsg;
  305.             CString strErr;
  306.             e->GetErrorMessage(strErr.GetBuffer(_MAX_PATH), _MAX_PATH);
  307.             strErr.ReleaseBuffer();
  308.             strMsg.Format("%s \n    %s", strErr, m_strFile);
  309.             MessageBox(NULL, strMsg, _T("Breakpoint Files"), MB_OK);
  310.         }
  311.         END_CATCH;
  312.         if (rgStrBrks.GetUpperBound() >= 0)
  313.         {
  314.             int i, ich;
  315.             long l;
  316.             i = 0;
  317.             if (i <= rgStrBrks.GetUpperBound())
  318.             {
  319.                 strComment = rgStrBrks.GetAt(i);
  320.                 i++;
  321.             }
  322.             while (i <= rgStrBrks.GetUpperBound())
  323.             {    
  324.                 CString strLine;
  325.                 CComVariant varSel;
  326.                 CComPtr<IGenericDocument> pDoc = NULL;
  327.                 CComQIPtr<ITextDocument, &IID_ITextDocument> pTextDoc;
  328.                 CComPtr<IDispatch> pDispBrkPnt;
  329.                 CComPtr<IDispatch> pDispSel;
  330.                 CComQIPtr<ITextSelection, &IID_ITextSelection> pSel;
  331.                 strBrk = rgStrBrks.GetAt(i);
  332.                 ich = strBrk.Find(_T('('));
  333.                 _ASSERTE(ich >= 0);
  334.                 hr = FindDoc(strBrk.Left(ich), pDoc);
  335.                 if (SUCCEEDED(hr) && pDoc)
  336.                 {
  337.                     hr = pDoc->put_Active((VARIANT_BOOL)VARIANT_TRUE);
  338.                     pTextDoc = pDoc;
  339.                     if (pTextDoc)
  340.                     {
  341.                         strBrk = strBrk.Mid(ich+1);
  342.                         ich = strBrk.Find(_T(')'));
  343.                         strLine = strBrk.Left(ich);
  344.                         l = atol(strLine);
  345.  
  346.                         hr = pTextDoc->get_Selection(&pDispSel);
  347.                         if (SUCCEEDED(hr) && pDispSel)
  348.                         {
  349.                             CComVariant varSelMode = dsMove;
  350.                             pSel = pDispSel;
  351.                             hr = pSel->GoToLine(l, varSelMode);
  352.  
  353.                             varSel = l;
  354.                             hr = m_pBrkPnts->AddBreakpointAtLine(varSel, &pDispBrkPnt);
  355.                         }
  356.                     }
  357.                 }
  358.                 if (FAILED(hr))
  359.                 {
  360.                     rgStrBrksFailed.Add(rgStrBrks.GetAt(i));
  361.                 }
  362.                 i++;
  363.             }
  364.         }
  365.     }
  366.     return(S_OK);
  367. }
  368.  
  369.  
  370.  
  371. HRESULT CBrkPnts::FindDoc(LPCTSTR szFile, CComPtr<IGenericDocument>& pDoc, BOOL fOkToOpen /*= TRUE*/)
  372. {
  373.     HRESULT hr = E_FAIL;
  374.     CComPtr<IDispatch> pDispDocuments;
  375.     CComQIPtr<IDocuments, &IID_IDocuments> pDocuments;
  376.     CComBSTR bstrFile;
  377.     m_spApplication->get_Documents(&pDispDocuments);
  378.     pDocuments = pDispDocuments;
  379.     pDispDocuments = NULL;
  380.     BOOL fFound = FALSE;
  381.  
  382.     if (pDocuments)
  383.     {    // ENSURE DOC IS OPEN -- WE KEEP FILES AROUND THAT MAY HAVE BEEN CLOSED
  384.         CComVariant vtDocType = _T("Auto");
  385.         CComVariant vtBoolReadOnly = FALSE;
  386.         CComPtr<IDispatch> pDispDoc;
  387.         bstrFile = szFile;
  388.         CComQIPtr<IGenericDocument, &IID_IGenericDocument> pDocument;
  389.         if (fOkToOpen)
  390.         {
  391.             hr = pDocuments->Open(bstrFile, vtDocType, vtBoolReadOnly, &pDispDoc);
  392.             pDocument = pDispDoc;
  393.             if (SUCCEEDED(hr) && pDocument)
  394.             {
  395.                 fFound = TRUE;
  396.                 pDoc = pDocument;
  397.             }
  398.         }
  399.         if (!fFound)
  400.         {
  401.             CComPtr<IUnknown> pUnk;
  402.             CComQIPtr<IEnumVARIANT, &IID_IEnumVARIANT> pNewEnum;
  403.             if (SUCCEEDED(pDocuments->get__NewEnum(&pUnk)) && pUnk != NULL)
  404.             {
  405.                 pNewEnum = pUnk;
  406.                 VARIANT varGenericDocument;
  407.  
  408.                 while (!fFound && pNewEnum->Next(1, &varGenericDocument, NULL) == S_OK)
  409.                 {
  410.                     CComQIPtr<IGenericDocument, &IID_IGenericDocument> pGenericDocument;
  411.                     ASSERT (varGenericDocument.vt == VT_DISPATCH);
  412.                     pGenericDocument = varGenericDocument.pdispVal;
  413.                     VariantClear(&varGenericDocument);
  414.                     CComBSTR bstrFullName;
  415.                     pGenericDocument->get_FullName(&bstrFullName);
  416.                     if (bstrFullName == szFile)
  417.                     {
  418.                         fFound = TRUE;
  419.                         pDoc = pGenericDocument;
  420.                     }
  421.                 }
  422.             }
  423.  
  424.  
  425.         }
  426.     }
  427.  
  428.     return(hr);
  429. }
  430.  
  431.  
  432. HRESULT CBrkPnts::ClearAll()
  433. {
  434.     HRESULT hr;
  435.     long l, cBrks, lLine;
  436.     CString strT;
  437.     short sEnabled;
  438.     VARIANT_BOOL fRemoved;
  439.     CComBSTR bstrCommand;
  440.  
  441.     bstrCommand = _T("DebugRemoveAllBreakpoints");
  442.     hr = m_spApplication->ExecuteCommand(bstrCommand);
  443.     if (SUCCEEDED(hr))
  444.     {
  445.         return(hr);
  446.     }
  447.  
  448.     hr = GetBrkPnts();
  449.     if (SUCCEEDED(hr) && m_pBrkPnts)
  450.     {
  451.         hr = m_pBrkPnts->get_Count(&cBrks);
  452.         l = 0;
  453.         while (l < cBrks)
  454.         {
  455.             CComPtr<IDispatch> pDispBrkPnt;
  456.             CComQIPtr<IBreakpoint, &IID_IBreakpoint> pBrkPnt;
  457.             CComBSTR bstrLocation;
  458.             CComBSTR bstrFile;
  459.             CComVariant varItem = l;
  460.  
  461.             hr = m_pBrkPnts->Item(varItem, &pDispBrkPnt);
  462.             if (SUCCEEDED(hr) && pDispBrkPnt)
  463.             {
  464.                 pBrkPnt = pDispBrkPnt;
  465.  
  466.                 hr = pBrkPnt->get_Enabled(&sEnabled);
  467.                 hr = pBrkPnt->get_File(&bstrFile);
  468.                 hr = pBrkPnt->get_Location(&bstrLocation);
  469.  
  470.                 CComPtr<IGenericDocument> pDoc = NULL;
  471.                 CComQIPtr<ITextDocument, &IID_ITextDocument> pTextDoc;
  472.                 
  473.                 strT = bstrFile;
  474.                 hr = FindDoc(strT, pDoc);
  475.                 if (SUCCEEDED(hr) && pDoc)
  476.                 {
  477.                     hr = pDoc->put_Active((VARIANT_BOOL)VARIANT_TRUE);
  478.                     pTextDoc = pDoc;
  479.                     if (SUCCEEDED(hr) && pTextDoc)
  480.                     {
  481.                         strT = bstrLocation;
  482.                         strT.Remove(_T('.'));
  483.                         lLine = atol(strT);
  484.                         varItem = lLine;
  485.                         hr = m_pBrkPnts->RemoveBreakpointAtLine(varItem, &fRemoved);
  486.                     }
  487.                 }
  488.             }
  489.             l++;
  490.         }
  491.     }
  492.     return(hr);
  493. }
  494.  
  495. void CBrkPnts::SetSaveOnlyEnabled(BOOL fSaveOnlyEnabled)
  496. {
  497.     m_fSaveOnlyEnabled = fSaveOnlyEnabled;
  498. }
  499.  
  500. void CBrkPnts::SetFile(LPCTSTR szFile)
  501. {
  502.     m_strFile = szFile;
  503. }
  504.  
  505.  
  506. void CBrkPnts::GetCounts(long &lTotal, long &lEnabled)
  507. {
  508.     HRESULT hr;
  509.     long l;
  510.     lTotal = 0;
  511.     lEnabled = 0;
  512.     hr = m_pBrkPnts->get_Count(&lTotal);
  513.     _ASSERTE(SUCCEEDED(hr));
  514.  
  515.     l = 0;
  516.     while (l < lTotal)
  517.     {
  518.         CComPtr<IDispatch> pDispBrkPnt;
  519.         CComQIPtr<IBreakpoint, &IID_IBreakpoint> pBrkPnt;
  520.         short sEnabled;
  521.         CComVariant varItem = l;
  522.  
  523.         hr = m_pBrkPnts->Item(varItem, &pDispBrkPnt);
  524.         pBrkPnt = pDispBrkPnt;
  525.  
  526.         hr = pBrkPnt->get_Enabled(&sEnabled);
  527.         if (sEnabled)
  528.         {
  529.             lEnabled++;
  530.         }
  531.         
  532.         l++;
  533.     }
  534.  
  535. }
  536.