home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sdktools / winnt / perfmon / addline.c next >
Text File  |  1995-10-29  |  63KB  |  2,046 lines

  1. //==========================================================================//
  2. //                                  Includes                                //
  3. //==========================================================================//
  4.  
  5.  
  6.  
  7. #include <stdio.h>
  8. #include <math.h>
  9.  
  10. #include "perfmon.h"
  11. #include "addline.h"
  12.  
  13. #include "alert.h"      // for AlertInsertLine, AlertDeleteLine
  14. #include "grafdata.h"   // for ChartInsertLine, ChartDeleteLine
  15. #include "graph.h"      // for SizeGraphComponents
  16. #include "legend.h"     // for LegendAddItem
  17. #include "line.h"       // for LineAllocate, LineFree.
  18. #include "pmemory.h"    // for MemoryXXX (mallloc-type) routines
  19. #include "perfdata.h"   // for QueryPerformanceData
  20. #include "perfmops.h"   // for dlg_error_box
  21. #include "playback.h"   // for PlaybackLines
  22. #include "report.h"     // for ReportInsertLine, ReportDeleteLine
  23. #include "system.h"     // for SystemGet
  24. #include "utils.h"
  25. #include "playback.h"   // for PlayingBackLog
  26. #include "counters.h"
  27. #include "pmhelpid.h"   // Help IDs
  28.  
  29. //==========================================================================//
  30. //                                  Constants                               //
  31. //==========================================================================//
  32.  
  33.  
  34. #ifdef ADVANCED_PERFMON
  35. #define ADDLINEDETAILLEVEL    PERF_DETAIL_WIZARD
  36. #else
  37. #define ADDLINEDETAILLEVEL    PERF_DETAIL_NOVICE
  38. #endif
  39.  
  40. #define iInitialExplainLen    256
  41.  
  42. // defines used in owner-drawn items
  43. #define OWNER_DRAWN_ITEM      2
  44. #define OWNER_DRAW_FOCUS      1
  45.  
  46. //==========================================================================//
  47. //                                Local Data                                //
  48. //==========================================================================//
  49.  
  50. // defined in PerfData.c
  51. extern WCHAR   NULL_NAME[] ;
  52.  
  53.  
  54. COLORREF argbColors[] = 
  55.    {
  56.    RGB (0xff, 0x00, 0x00), 
  57.    RGB (0x00, 0x80, 0x00), 
  58.    RGB (0x00, 0x00, 0xff), 
  59.    RGB (0xff, 0xff, 0x00), 
  60.    RGB (0xff, 0x00, 0xff), 
  61.    RGB (0x00, 0xff, 0xff), 
  62.    RGB (0x80, 0x00, 0x00), 
  63.    RGB (0x40, 0x40, 0x40), 
  64.    RGB (0x00, 0x00, 0x80), 
  65.    RGB (0x80, 0x80, 0x00), 
  66.    RGB (0x80, 0x00, 0x80), 
  67.    RGB (0x00, 0x80, 0x80), 
  68.    RGB (0x40, 0x00, 0x00), 
  69.    RGB (0x00, 0x40, 0x00), 
  70.    RGB (0x00, 0x00, 0x40), 
  71.    RGB (0x00, 0x00, 0x00)
  72.    } ;
  73.  
  74.  
  75. TCHAR *apszScaleFmt[] =
  76.    {
  77.    TEXT("%6.6f"),
  78.    TEXT("%5.5f"),
  79.    TEXT("%4.4f"),
  80.    TEXT("%3.3f"),
  81.    TEXT("%2.2f"),
  82.    TEXT("%1.1f"),
  83.    TEXT("%2.1f"),
  84.    TEXT("%3.1f"),
  85.    TEXT("%4.1f"),
  86.    TEXT("%5.1f"),
  87.    TEXT("%6.1f"),
  88.    TEXT("%7.1f")
  89.    } ;
  90. #define DEFAULT_SCALE 0
  91. #define NUMBER_OF_SCALE sizeof(apszScaleFmt)/sizeof(apszScaleFmt[0])
  92.  
  93. int               iLineType ;
  94. static PPERFDATA  pPerfData ;
  95. PPERFSYSTEM       pSystem ;
  96. PLINESTRUCT       pLineEdit ;
  97. PPERFSYSTEM       *ppSystemFirst ;
  98. PLINEVISUAL       pVisual ;
  99.  
  100. #define bEditLine (pLineEdit != NULL)
  101.  
  102.  
  103. BOOL              ComputerChange ;
  104. LPTSTR            pCurrentSystem ;
  105.  
  106. //=============================//
  107. // Alert-related locals        //
  108. //=============================//
  109.  
  110.  
  111. BOOL           bAlertOver ;         // over or under?
  112. FLOAT          eAlertValue ;        // value to compare
  113. BOOL           bEveryTime ;         // run every time or once?
  114.  
  115. // program to run; 
  116. LPTSTR          pszAlertProgram ;  
  117.  
  118.  
  119. //==========================================================================//
  120. //                                   Macros                                 //
  121. //==========================================================================//
  122.  
  123.  
  124. #define InChartAdd()             \
  125.    (iLineType == LineTypeChart)
  126.  
  127.  
  128. #define InAlertAdd()             \
  129.    (iLineType == LineTypeAlert)
  130.  
  131. #define InReportAdd()            \
  132.    (iLineType == LineTypeReport)
  133.  
  134.  
  135.  
  136.  
  137. #define NumColorIndexes()     \
  138.    (sizeof (argbColors) / sizeof (argbColors[0]))
  139.  
  140. #define NumWidthIndexes()  5
  141.  
  142. #define NumStyleIndexes()  4
  143.  
  144.  
  145. //==========================================================================//
  146. //                              Forward Declarations                        //
  147. //==========================================================================//
  148.  
  149. BOOL /*static*/ OnObjectChanged (HDLG hDlg) ;
  150.  
  151.  
  152. //==========================================================================//
  153. //                              Local Functions                             //
  154. //==========================================================================//
  155.  
  156.  
  157. PPERFINSTANCEDEF ParentInstance (PPERFINSTANCEDEF pInstance)
  158.    {  // ParentInstance
  159.    PPERFOBJECT          parent_obj ;
  160.    PPERFINSTANCEDEF     parent_instance ;
  161.    PERF_COUNTER_BLOCK   *counter_blk;
  162.    LONG                 i ;
  163.  
  164.    parent_obj = 
  165.       GetObjectDefByTitleIndex (pPerfData, 
  166.                                 pInstance->ParentObjectTitleIndex) ;
  167.    if (!parent_obj)
  168.       return (NULL) ;
  169.  
  170.  
  171.    // Then get the parent instance.
  172.    // NOTE: can use unique ID field to match here instead
  173.    // of name compare.
  174.    for (i = 0, 
  175.         parent_instance = (PERF_INSTANCE_DEFINITION *) ( (PBYTE)parent_obj
  176.         + parent_obj->DefinitionLength);
  177.         i < parent_obj->NumInstances;
  178.         i++, parent_instance = (PERF_INSTANCE_DEFINITION *) ( (PBYTE)counter_blk
  179.         + counter_blk->ByteLength))
  180.       {  // for
  181.       counter_blk = (PERF_COUNTER_BLOCK *) ( (PBYTE)parent_instance
  182.                    + parent_instance->ByteLength);
  183.      if ((DWORD)i == pInstance->ParentObjectInstance)
  184.         return (parent_instance) ;
  185.      }
  186.  
  187.    return (NULL) ;
  188.    }  // ParentInstance
  189.  
  190.  
  191. PPERFOBJECT SelectedObject (HWND hWndObjects, 
  192.                             LPTSTR lpszObjectName)
  193. /*
  194.    Effect:        Return the pObject associated with the currently selected
  195.                   combo-box item of hWndObjects. Set lpszObjectName to 
  196.                   the object's name.
  197.  
  198.                   If no item is selected in the combobox, return NULL.
  199.  
  200.    Assert:        The pObject for each CB item was added when the string
  201.                   was added to the CB, by CBLoadObjects.
  202.  
  203.    See Also:      LoadObjects.
  204. */
  205.    {  // SelectedObject
  206.    int            iIndex ;
  207.  
  208.    iIndex = CBSelection (hWndObjects) ;
  209.    if (iIndex == CB_ERR)
  210.       return (NULL) ;
  211.  
  212.    if (lpszObjectName)
  213.       CBString (hWndObjects, iIndex, lpszObjectName) ;
  214.  
  215.    return ((PPERFOBJECT) CBData (hWndObjects, iIndex)) ;
  216.    }  // SelectedObject
  217.  
  218.  
  219.  
  220. PPERFCOUNTERDEF SelectedCounter (HWND hWndCounters, 
  221.                                  LPTSTR lpszCounterName)
  222. /*
  223.    Effect:        Return the pCounter associated with the currently selected
  224.                   LB item of hWndCounters. Set lpszCounterName to 
  225.                   the Counter's name.
  226.  
  227.                   If no item is selected in the listbox, return NULL.
  228.  
  229.    Assert:        The pCounter for each LB item was added when the string
  230.                   was added to the LB, by LoadCounters.
  231.  
  232.    See Also:      LoadCounters.
  233. */
  234.    {  // SelectedCounter
  235.    int            iIndex ;
  236.  
  237.    iIndex = LBSelection (hWndCounters) ;
  238.    if (iIndex == LB_ERR)
  239.       return (NULL) ;
  240.  
  241.    if (lpszCounterName)
  242.       LBString (hWndCounters, iIndex, lpszCounterName) ;
  243.    return ((PPERFCOUNTERDEF) LBData (hWndCounters, iIndex)) ;
  244.    }  // SelectedCounter
  245.  
  246.  
  247.  
  248. void VisualIncrement (PLINEVISUAL pVisual)
  249. /*
  250.    Effect:        Cycle through the combinations of color, width, and
  251.                   style to distinguish between lines.  The color attributes
  252.                   are like a number:
  253.                         <style> <width> <color>
  254.  
  255.                   Since color is the LSB, it is always incremented. The
  256.                   others are incremented whenever the color rolls over.
  257.  
  258.                   If a current index is -1, that means don't increment
  259.                   that visual attribute.
  260. */
  261.    {  // VisualIncrement
  262.    pVisual->iColorIndex = 
  263.       (pVisual->iColorIndex + 1) % NumColorIndexes () ;
  264.  
  265.    if (pVisual->iColorIndex)
  266.       return ;
  267.  
  268.  
  269.    if (pVisual->iWidthIndex == -1)
  270.       return ;
  271.  
  272.  
  273.    pVisual->iWidthIndex =
  274.       (pVisual->iWidthIndex + 1) % NumWidthIndexes () ;
  275.  
  276.    if (pVisual->iWidthIndex)
  277.        return ;
  278.  
  279.  
  280.    if (pVisual->iStyleIndex == -1)
  281.       return ;
  282.  
  283.  
  284.    pVisual->iStyleIndex = 
  285.       (pVisual->iStyleIndex + 1) % NumStyleIndexes () ;
  286.    }  // VisualIncrement
  287.  
  288.  
  289. COLORREF LineColor (int iColorIndex)
  290.    {
  291.    return (argbColors [iColorIndex]) ;
  292.    }
  293.  
  294.  
  295. int LineWidth (int iWidthIndex)
  296.    {
  297.    switch (iWidthIndex)
  298.       {  // switch
  299.       case 0:
  300.           return (1) ;
  301.           break ;
  302.  
  303.       case 1:
  304.           return (3) ;
  305.           break ;
  306.  
  307.       case 2:
  308.           return (5) ;
  309.           break ;
  310.  
  311.       case 3:
  312.           return (7) ;
  313.           break ;
  314.  
  315.       case 4:
  316.           return (9) ;
  317.           break ;
  318.       }  // switch
  319.    }  // LineWidth
  320.  
  321.  
  322.  
  323. int LineStyle (int iStyleIndex)
  324.    {
  325.    return (iStyleIndex) ;
  326.    }
  327.  
  328.  
  329. BOOL /*static*/ LoadInstances (HDLG hDlg)
  330.    {
  331.    PPERFOBJECT       pObject ;
  332.    PPERFINSTANCEDEF  pInstance, pInstanceParent ;
  333.    TCHAR             szInstance [256], szInstanceParent [256] ;
  334.    TCHAR             szCompositeName [256 * 2] ;
  335.    TCHAR             szInstCompositeName [256 * 2] ;
  336.                            
  337.    LONG              iInstance ;
  338.    UINT              iIndex ;
  339.  
  340.    int               xTextExtent = 0 ;
  341.    int               currentTextExtent ;
  342.    HFONT             hFont ;
  343.    HDC               hDC = 0 ;
  344.    HWND              hWndObjects = DialogControl (hDlg, IDD_ADDLINEOBJECT);
  345.    HWND              hWndInstances = DialogControl (hDlg, IDD_ADDLINEINSTANCE);
  346.  
  347.    // turn off horiz. scrollbar
  348.    LBSetHorzExtent (hWndInstances, 0) ;
  349.    LBReset (hWndInstances) ;
  350.  
  351.    pObject = SelectedObject (hWndObjects, NULL) ;
  352.    if (!pObject)
  353.       return (FALSE) ;
  354.  
  355.    if (pObject->NumInstances <= 0)
  356.       {
  357.       MLBSetSelection (hWndInstances, 0, TRUE) ;
  358.       return (FALSE) ;
  359.       }
  360.  
  361.    // turn off Listbox redraw
  362.    LBSetRedraw (hWndInstances, FALSE) ;
  363.  
  364.    if (bEditLine)
  365.       {
  366.       if (pLineEdit->lnObject.NumInstances > 0)
  367.          {
  368.          if (pLineEdit->lnInstanceDef.ParentObjectTitleIndex)
  369.             {
  370.             // Get the Parent Object Instance Name.
  371.             // and prefix it to the Instance Name, to make
  372.             // the string we want to display.
  373.             TSPRINTF (szInstCompositeName,
  374.                      TEXT("%s ==> %s"),
  375.                      pLineEdit->lnPINName,
  376.                      pLineEdit->lnInstanceName) ;
  377.             }
  378.          else
  379.             {
  380.             lstrcpy (szInstCompositeName, pLineEdit->lnInstanceName) ;
  381.             }
  382.          }
  383.       else
  384.          {
  385.          szInstCompositeName[0] = TEXT('\0');
  386.          }
  387.       }
  388.  
  389.    if (!bEditLine && (hDC = GetDC (hWndInstances)))
  390.       {
  391.       hFont = (HFONT)SendMessage(hWndInstances, WM_GETFONT, 0, 0L);
  392.       if (hFont)
  393.          SelectObject(hDC, hFont);
  394.       }
  395.  
  396.  
  397.    for (iInstance = 0, pInstance = FirstInstance (pObject) ;
  398.         iInstance < pObject->NumInstances; 
  399.         iInstance++, pInstance = NextInstance (pInstance))
  400.       {  // for
  401.       GetInstanceNameStr (pInstance, szInstance) ;
  402.       pInstanceParent = ParentInstance (pInstance) ;
  403.     
  404.       if (pInstanceParent)
  405.          {
  406.          GetInstanceNameStr (pInstanceParent, szInstanceParent) ;
  407.          TSPRINTF (szCompositeName, TEXT("%s ==> %s"), 
  408.                    szInstanceParent, szInstance) ;
  409.          }
  410.      else
  411.         lstrcpy (szCompositeName, szInstance) ;
  412.  
  413.       iIndex = LBAdd (hWndInstances, szCompositeName) ;
  414.    if (iIndex != LB_ERR)
  415.       {
  416.       LBSetData (hWndInstances, iIndex, (LPARAM) pInstance) ;
  417.       }
  418.  
  419.    // get the biggest text width
  420.    if (hDC)
  421.       {
  422.       currentTextExtent = TextWidth (hDC, szCompositeName) + xScrollWidth / 2  ;
  423.       if (currentTextExtent > xTextExtent)
  424.          {
  425.          xTextExtent = currentTextExtent ;
  426.          }
  427.       }
  428.    }  // for
  429.  
  430.    if (hDC)
  431.       {
  432.       // turn on horiz. scrollbar if necessary...
  433.       LBSetHorzExtent (hWndInstances, xTextExtent) ;
  434.       ReleaseDC (hWndInstances, hDC) ;
  435.       }
  436.  
  437.  
  438.    if (!bEditLine || szInstCompositeName[0] == TEXT('\0'))
  439.       {
  440.       MLBSetSelection (hWndInstances, 0, TRUE) ;
  441.       }
  442.    else
  443.       {
  444.       BOOL bSetSelection = TRUE ;
  445.  
  446.       iIndex = LBFind (hWndInstances, szInstCompositeName) ;
  447.       if (iIndex == LB_ERR)
  448.          {
  449.          if (bEditLine)
  450.             {
  451.             bSetSelection = FALSE ;
  452.             }
  453.          iIndex = 0 ;
  454.          }
  455.  
  456.       if (bSetSelection)
  457.          {
  458.          MLBSetSelection (hWndInstances, iIndex, TRUE) ;
  459.          }
  460.  
  461.       LBSetVisible (hWndInstances, iIndex) ;
  462.       }
  463.  
  464.    // turn on Listbox redraw
  465.    LBSetRedraw (hWndInstances, TRUE) ;  
  466.  
  467.    }  // LoadInstances
  468.  
  469.  
  470. BOOL OnCounterChanged (HDLG hDlg)
  471. /*
  472.    Effect:        Perform any actions necessary when the counter has changed.
  473.                   In particular, display the explanation for the counter
  474.                   that has the focus rectangle.
  475. */
  476.    {
  477.    LPTSTR         lpszText ;
  478.    PPERFCOUNTERDEF pCounter ;
  479.    int            iStatus ;
  480.    int            iFocusIndex ;
  481.    HWND           hWndCounters = DialogControl (hDlg, IDD_ADDLINECOUNTER);
  482.    HWND           hWndScales = DialogControl (hDlg, IDD_ADDLINESCALE) ;
  483.  
  484.    iFocusIndex = LBFocus (hWndCounters) ;
  485.    if  (iFocusIndex == LB_ERR)
  486.       return (FALSE) ;
  487.  
  488.    if (PlayingBackLog())
  489.       {
  490.       DialogEnable (hDlg, IDD_ADDLINEEXPANDEXPLAIN, FALSE) ;   
  491.       return (TRUE) ;
  492.       }
  493.  
  494.    pCounter = (PPERFCOUNTERDEF) LBData (hWndCounters, iFocusIndex) ;
  495.    if ((!pCounter) || (pCounter == (PPERFCOUNTERDEF)LB_ERR))
  496.       return (FALSE) ;
  497.    
  498.    // no need to get help text before the button is clicked
  499.    if (!bExplainTextButtonHit)
  500.       return (FALSE) ;
  501.  
  502.    // Create initial string
  503.    lpszText = MemoryAllocate (iInitialExplainLen * sizeof (TCHAR)) ;
  504.  
  505.    if (!lpszText)
  506.       return (FALSE) ;
  507.  
  508.    while (TRUE)
  509.       {
  510.       lpszText[0] = TEXT('\0') ;
  511.  
  512.       #ifdef UNICODE
  513.       iStatus = QueryPerformanceName  (pSystem,
  514.                                        pCounter->CounterHelpTitleIndex,
  515.                                        iLanguage,
  516.                                        MemorySize (lpszText) / sizeof(TCHAR),
  517.                                        lpszText,
  518.                                        TRUE) ;
  519.       #else
  520.       iStatus = QueryPerformanceNameW (pSystem,
  521.                                        pCounter->CounterHelpTitleIndex,
  522.                                        iLanguage,
  523.                                        MemorySize (lpszText),
  524.                                        lpszText,
  525.                                        TRUE) ;
  526.       #endif
  527.  
  528.       if (iStatus == ERROR_SUCCESS)
  529.          break ;
  530.  
  531.       if (iStatus == ERROR_MORE_DATA)
  532.          lpszText = 
  533.             MemoryResize (lpszText, 
  534.                           MemorySize (lpszText) + iInitialExplainLen) ;
  535.       else
  536.          break ;
  537.       }  // while
  538.  
  539.    // Don't use my DialogSetString, it won't handle such large strings.
  540.    SetDlgItemText (hDlg, IDD_ADDLINEEXPLAIN, lpszText) ;
  541.    MemoryFree (lpszText) ;
  542.  
  543.    return (TRUE) ;
  544.    }  // OnCounterChanged
  545.  
  546.  
  547.  
  548. BOOL LoadCounters (HDLG hDlg, 
  549.                    UINT iSelectCounterDefn)
  550.    {  // LoadCounters
  551.    PPERFOBJECT       pObject ;
  552.  
  553.    TCHAR             szCounterName [256] ;
  554.    TCHAR             szDefaultCounterName [256] ;
  555.    PPERFCOUNTERDEF   pCounter ;
  556.    UINT              i ;
  557.    int               iIndex ;
  558.    int               xTextExtent = 0 ;
  559.    int               currentTextExtent ;
  560.    HFONT             hFont ;
  561.    HDC               hDC = 0 ;
  562.    BOOL              bSetSelection = TRUE ;
  563.    HWND              hWndObjects = DialogControl (hDlg, IDD_ADDLINEOBJECT);
  564.    HWND              hWndCounters = DialogControl (hDlg, IDD_ADDLINECOUNTER);
  565.  
  566.  
  567.    strclr (szDefaultCounterName) ;
  568.  
  569.    // turn off horiz. scrollbar
  570.    LBSetHorzExtent (hWndCounters, 0) ;
  571.    LBReset (hWndCounters) ;
  572.  
  573.    pObject = SelectedObject (hWndObjects, NULL) ;
  574.    if (!pObject)
  575.       return (FALSE) ;
  576.  
  577.    if (!bEditLine && (hDC = GetDC (hWndCounters)))
  578.       {
  579.       hFont = (HFONT)SendMessage(hWndCounters, WM_GETFONT, 0, 0L);
  580.       if (hFont)
  581.          SelectObject(hDC, hFont);
  582.       }
  583.  
  584.    // turn off Listbox redraw
  585.    LBSetRedraw (hWndCounters, FALSE) ;  
  586.  
  587.    for (i = 0, pCounter = FirstCounter (pObject) ;
  588.         i < pObject->NumCounters ;
  589.         i++, pCounter = NextCounter (pCounter))
  590.       {  // for
  591.       if (pCounter->CounterType != PERF_SAMPLE_BASE &&
  592.           pCounter->CounterType != PERF_COUNTER_NODATA &&
  593.           pCounter->CounterType != PERF_AVERAGE_BASE &&
  594.           pCounter->CounterType != PERF_COUNTER_QUEUELEN_TYPE &&
  595.           pCounter->CounterType != PERF_COUNTER_MULTI_BASE &&
  596.           pCounter->CounterType != PERF_RAW_BASE &&
  597.           pCounter->DetailLevel <= ADDLINEDETAILLEVEL)
  598.          {   // if
  599.          szCounterName[0] = TEXT('\0') ;
  600.          QueryPerformanceName (pSystem, 
  601.                                  pCounter->CounterNameTitleIndex, 
  602.                                  0, sizeof (szCounterName) / sizeof(TCHAR),
  603.                                  szCounterName,
  604.                                  FALSE) ;
  605.          
  606.          // if szCounterName is not empty, add it to the listbox
  607.          if (!strsame(szCounterName, NULL_NAME))
  608.             {
  609.             iIndex = LBAdd (hWndCounters, szCounterName) ;
  610.             LBSetData (hWndCounters, iIndex, (DWORD) pCounter) ;
  611.  
  612.             // get the biggest text width
  613.             if (hDC)
  614.                {
  615.                currentTextExtent = TextWidth (hDC, szCounterName) + xScrollWidth / 2 ;
  616.                if (currentTextExtent > xTextExtent)
  617.                   {
  618.                   xTextExtent = currentTextExtent ;
  619.                   }
  620.                }
  621.        
  622.             if (iSelectCounterDefn == i)
  623.                lstrcpy (szDefaultCounterName, szCounterName) ;
  624.             } // if szCounterName is not empty
  625.          }   // if
  626.       }  // for
  627.  
  628.    if (bEditLine)
  629.       lstrcpy (szDefaultCounterName, pLineEdit->lnCounterName) ;
  630.  
  631.    iIndex = LBFind (hWndCounters, szDefaultCounterName) ;
  632.    if (iIndex == LB_ERR)
  633.       {
  634.       if (bEditLine)
  635.          {
  636.          bSetSelection = FALSE ;
  637.          }
  638.       iIndex = 0 ;
  639.       }
  640.  
  641.    if (bSetSelection)
  642.       {
  643.       MLBSetSelection (hWndCounters, iIndex, TRUE) ;
  644.       }
  645.    LBSetVisible (hWndCounters, iIndex) ;
  646.    
  647.    if (hDC)
  648.       {
  649.       // turn on horiz. scrollbar if necessary...
  650.       LBSetHorzExtent (hWndCounters, xTextExtent) ;
  651.       ReleaseDC (hWndCounters, hDC) ;
  652.       }
  653.  
  654.    // turn on Listbox redraw
  655.    LBSetRedraw (hWndCounters, TRUE) ;  
  656.  
  657.    OnCounterChanged (hDlg) ;
  658.    }  // LoadCounters
  659.  
  660.  
  661.  
  662.  
  663. void LoadObjects (HDLG hDlg,
  664.                   PPERFDATA pPerfData)
  665. /*
  666.    Effect:        Load into the object CB the objects for the current
  667.                   pPerfData.
  668. */
  669.    {
  670.    LPTSTR         lpszObject ;
  671.    HWND           hWndObjects = DialogControl (hDlg, IDD_ADDLINEOBJECT);
  672.  
  673.  
  674.    lpszObject = bEditLine ? pLineEdit->lnObjectName : NULL ;
  675.  
  676.    CBLoadObjects (hWndObjects, 
  677.                   pPerfData,
  678.                   pSystem,
  679.                   ADDLINEDETAILLEVEL,
  680.                   lpszObject,
  681.                   FALSE) ;
  682.    OnObjectChanged (hDlg) ;
  683. //   UpdateWindow (hDlg) ;
  684.    }  // LoadObjects
  685.  
  686.  
  687.  
  688. void OnComputerChanged (HDLG hDlg)
  689.    {
  690.  
  691.    PPERFSYSTEM pLocalSystem;
  692.    PPERFDATA   pLocalPerfData;
  693.  
  694.    pLocalPerfData = pPerfData;
  695.    pLocalSystem = GetComputer (hDlg,
  696.                           IDD_ADDLINECOMPUTER,
  697.                           TRUE,
  698.                           &pLocalPerfData,
  699.                           ppSystemFirst) ;
  700.    if (pLocalSystem && pLocalPerfData)
  701.       {
  702.       pSystem = pLocalSystem;
  703.       pPerfData = pLocalPerfData;
  704.       LoadObjects (hDlg, pPerfData) ;
  705.       ComputerChange = FALSE ;
  706.       }
  707.  
  708.    }  // OnComputerChanged
  709.  
  710.  
  711.    
  712.  
  713. BOOL AddOneChartLine (HWND hDlg,
  714.                       PPERFCOUNTERDEF pCounter,
  715.                       LPTSTR lpszCounter,
  716.                       PPERFINSTANCEDEF pInstance)                     
  717.    {
  718.    TCHAR             szComputer [MAX_SYSTEM_NAME_LENGTH] ;
  719.  
  720. //   PPERFOBJECT       pObject ;
  721.    PERF_OBJECT_TYPE       UNALIGNED *pObject ;
  722.    TCHAR             szObject [PerfObjectLen] ;
  723.  
  724.    TCHAR             szInstance [256] ;
  725.  
  726.    PLINE             pLine ;
  727. //   int               i ;
  728.    int               iCounterIndex ;
  729.    int               j ;
  730.  
  731.    PPERFINSTANCEDEF  pInstanceParent ;
  732.    PERF_COUNTER_BLOCK *pCounterBlock ;
  733.    TCHAR          szInstanceParent [256] ;
  734.    TCHAR          szObjectParent [256] ;
  735.    HWND           hWndColors = DialogControl (hDlg, IDD_ADDLINECOLOR) ;
  736.    HWND           hWndWidths = DialogControl (hDlg, IDD_ADDLINEWIDTH) ;
  737.    HWND           hWndStyles = DialogControl (hDlg, IDD_ADDLINESTYLE) ;
  738.    HWND           hWndScales = DialogControl (hDlg, IDD_ADDLINESCALE) ;
  739.    HWND           hWndObjects = DialogControl (hDlg, IDD_ADDLINEOBJECT);
  740.  
  741.  
  742.    //=============================//
  743.    // Get selected data values    //
  744.    //=============================//
  745.  
  746.  
  747.  
  748.    DialogText (hDlg, IDD_ADDLINECOMPUTER, szComputer) ;
  749.  
  750.    pObject = (PERF_OBJECT_TYPE UNALIGNED *)SelectedObject (hWndObjects, szObject) ;
  751.    if (!pObject)
  752.       return (FALSE) ;
  753.  
  754.    if (pInstance)
  755.       GetInstanceNameStr (pInstance, szInstance) ;
  756.  
  757.    //=============================//
  758.    // Allocate the line           //
  759.    //=============================//
  760.  
  761.    pLine = LineAllocate () ;
  762.    if (!pLine)
  763.       {
  764.       DlgErrorBox (hDlg, ERR_NO_MEMORY);
  765.       return (FALSE) ;
  766.       }
  767.  
  768.  
  769.    //=============================//
  770.    // Set line's data values      //
  771.    //=============================//
  772.  
  773.    pLine->iLineType = iLineType ;
  774.    pLine->lnSystemName = StringAllocate (szComputer) ;
  775.  
  776.    pLine->lnObject = *pObject ;
  777.    pLine->lnObjectName = StringAllocate (szObject) ;
  778.  
  779.    pLine->lnCounterDef = *pCounter ;
  780.    pLine->lnCounterName = StringAllocate (lpszCounter) ;
  781.  
  782.  
  783.    if (pObject->NumInstances > 0 && pInstance)
  784.       {
  785.       pLine->lnInstanceDef = *pInstance ;          
  786.       pLine->lnInstanceName = StringAllocate (szInstance) ;
  787.  
  788.       pLine->lnUniqueID = pInstance->UniqueID ;
  789.  
  790.       if (pInstance->ParentObjectTitleIndex)
  791.          {
  792.          szObjectParent[0] = (TCHAR)'\0';
  793.          QueryPerformanceName (pSystem,
  794.                                pInstance->ParentObjectTitleIndex,
  795.                                0,  PerfObjectLen, szObjectParent, FALSE) ;
  796.          pLine->lnParentObjName = StringAllocate (szObjectParent) ;
  797.          }
  798.  
  799.       pInstanceParent = ParentInstance (pInstance) ;
  800.       if (pInstanceParent)
  801.          {
  802.          GetInstanceNameStr (pInstanceParent, szInstanceParent) ;
  803.          if (pInstance->ParentObjectTitleIndex)
  804.             {
  805.             pLine->lnPINName = StringAllocate (szInstanceParent) ;
  806.             }
  807.          }
  808.       }  // if
  809.  
  810.    pLine->lnCounterType = pCounter->CounterType;
  811.    pLine->lnCounterLength = pCounter->CounterSize;
  812.  
  813.    pLine->lnOldTime = pPerfData->PerfTime.HighPart << 32 +
  814.       pPerfData->PerfTime.LowPart ;
  815.    pLine->lnNewTime = pLine->lnOldTime ;
  816.  
  817.    for (j = 0 ; j < 2 ; j++)
  818.       {
  819.       pLine->lnaCounterValue[j] = (LONGLONG) 0 ;
  820.       }
  821.  
  822.  
  823.    //=============================//
  824.    // Chart-related Values        //
  825.    //=============================//
  826.  
  827.    pLine->iScaleIndex = CBSelection (hWndScales) ;
  828.    if (pLine->iScaleIndex == 0)
  829.       {
  830.       // use the default scale
  831.       pLine->eScale = (FLOAT) pow ((double)10.0,
  832.           (double)pCounter->DefaultScale) ;
  833.       }
  834.    else
  835.       {
  836.       pLine->eScale = DialogFloat (hDlg, IDD_ADDLINESCALE, NULL) ;
  837.       }
  838.  
  839.    if (pObject->NumInstances > 0 && pInstance)
  840.       {
  841.       pCounterBlock = (PERF_COUNTER_BLOCK *) ( (PBYTE) pInstance +
  842.                        pInstance->ByteLength);
  843.       }
  844.    else
  845.       {
  846.       pCounterBlock = (PERF_COUNTER_BLOCK *) ( (PBYTE) pObject +
  847.                        pObject->DefinitionLength);
  848.       }
  849.  
  850.    if (pLine->lnCounterLength <= 4)
  851.       {
  852.       pLine->lnaOldCounterValue[0] =
  853.                * ( (DWORD FAR *) ( (PBYTE)pCounterBlock +
  854.                pCounter[0].CounterOffset));
  855.       pLine->lnaOldCounterValue[0] &= (LONGLONG) (0x0ffffffff);
  856.       }
  857.    else
  858.       {
  859.       pLine->lnaOldCounterValue[0] =
  860.               * ( (LONGLONG UNALIGNED *) ( (PBYTE)pCounterBlock +
  861.               pCounter[0].CounterOffset));
  862.       }
  863.  
  864.    // Get second counter, only if we are not at
  865.    // the end of the counters; some computations
  866.    // require a second counter
  867.  
  868.    iCounterIndex = CounterIndex (pCounter, (PPERFOBJECT) pObject) ;
  869.    if ((UINT) iCounterIndex < pObject->NumCounters - 1 &&
  870.        iCounterIndex != -1)
  871.       {
  872.       if (pLine->lnCounterLength <= 4)
  873.          {
  874.          pLine->lnaOldCounterValue[1] =
  875.                   * ( (DWORD FAR *) ( (PBYTE)pCounterBlock +
  876.                   pCounter[1].CounterOffset));
  877.          pLine->lnaOldCounterValue[1] &= (LONGLONG) (0x0ffffffff);
  878.          }
  879.       else
  880.          pLine->lnaOldCounterValue[1] =
  881.                  * ( (LONGLONG UNALIGNED *) ( (PBYTE)pCounterBlock +
  882.                  pCounter[1].CounterOffset));
  883.       }
  884.  
  885.  
  886.    pLine->lnaOldCounterValue[0] = pLine->lnaCounterValue[0];
  887.    pLine->lnaOldCounterValue[1] = pLine->lnaCounterValue[1];
  888.  
  889.    //=============================//
  890.    // Visual Values               //
  891.    //=============================//
  892.  
  893.    pLine->Visual.iColorIndex = CBSelection (hWndColors) ;
  894.    pLine->Visual.crColor = LineColor (pLine->Visual.iColorIndex) ;
  895.  
  896.    pLine->Visual.iWidthIndex = CBSelection (hWndWidths) ;
  897.    pLine->Visual.iWidth = LineWidth (pLine->Visual.iWidthIndex) ;
  898.  
  899.    pLine->Visual.iStyleIndex = CBSelection (hWndStyles) ;
  900.    pLine->Visual.iStyle = LineStyle (pLine->Visual.iStyleIndex) ;
  901.  
  902.    *pVisual = pLine->Visual ;
  903.    if (!bEditLine)
  904.       VisualIncrement (pVisual) ;
  905.  
  906.    CBSetSelection (hWndColors, pVisual->iColorIndex) ;
  907.    CBSetSelection (hWndWidths, pVisual->iWidthIndex) ;
  908.    CBSetSelection (hWndStyles, pVisual->iStyleIndex) ;
  909.  
  910.    if (iLineType == LineTypeChart)
  911.       {
  912.       pLine->hPen = LineCreatePen (NULL, &(pLine->Visual), FALSE) ;
  913.       }
  914.  
  915.    //=============================//
  916.    // Alert Related Values        //
  917.    //=============================//
  918.  
  919.    if (iLineType == LineTypeAlert)
  920.       {
  921.       pLine->bAlertOver = bAlertOver ;
  922.       pLine->eAlertValue = eAlertValue ;
  923.       pLine->bEveryTime = 
  924.          IsDlgButtonChecked (hDlg, IDD_ADDLINEPROGRAMEVERYTIME) ;
  925.       pLine->bAlerted = FALSE ;
  926.       pLine->hBrush = CreateSolidBrush (pLine->Visual.crColor) ;
  927.       if (!PlayingBackLog ())
  928.          {
  929.          pLine->lpszAlertProgram = StringAllocate (pszAlertProgram) ;
  930.          }
  931.       else
  932.          {
  933.          pLine->lpszAlertProgram = NULL ;
  934.          }
  935.       }
  936.    //=============================//
  937.    // Insert the line!            //
  938.    //=============================//
  939.  
  940.    if (InsertLine (pLine) == FALSE)
  941.       {
  942.       // no inert occurred due to either line already existed
  943.       // or error detected.
  944.       LineFree (pLine) ;
  945.       }
  946.    else
  947.       {
  948.       if (pSystem->lpszValue && pSystem->FailureTime == 0)
  949.          {
  950.          if (strsame(pSystem->lpszValue, TEXT("Global")))
  951.             {
  952.             // take out the "Global" string
  953.             *(pSystem->lpszValue) = 0 ;
  954.             }
  955.          AppendObjectToValueList (
  956.             pLine->lnObject.ObjectNameTitleIndex,
  957.             pSystem->lpszValue) ;
  958.          }
  959.       }
  960.    }  // AddOneChartLine
  961.  
  962.  
  963. BOOL AddCounter (HWND hDlg,
  964.                       PPERFCOUNTERDEF pCounter,
  965.                       LPTSTR lpszCounter)
  966.    {  // AddCounter
  967.    int               iInstanceIndex ;
  968.    int               iInstanceNum ;
  969.    PPERFINSTANCEDEF  pInstance ;
  970.    HWND              hWndInstances = DialogControl (hDlg, IDD_ADDLINEINSTANCE);
  971.  
  972.    // NOTE: for now, we don't check for duplicate lines
  973.    if (!IsCounterSupported (pCounter->CounterType))
  974.       {
  975.       DlgErrorBox (hDlg, ERR_COUNTER_NOT_IMP);
  976.       return (FALSE) ;
  977.       }
  978.  
  979.  
  980.    if ((iInstanceNum = LBNumItems (hWndInstances)) && iInstanceNum != LB_ERR)
  981.       {
  982.  
  983.       if (iInstanceNum > 1)
  984.          {
  985.          // delay some of the insert actions for performacne improvement
  986.          bDelayAddAction = TRUE ;
  987.  
  988.          if (InChartAdd())
  989.             {
  990.             LegendSetRedraw (hWndGraphLegend, FALSE) ;
  991.             }
  992.          else if (InAlertAdd())
  993.             {
  994.             LegendSetRedraw (hWndAlertLegend, FALSE) ;
  995.             }
  996.          }
  997.  
  998.       for (iInstanceIndex = 0 ;
  999.            iInstanceIndex < iInstanceNum ;
  1000.            iInstanceIndex++)
  1001.          {  // for
  1002.          if (LBSelected (hWndInstances, iInstanceIndex))
  1003.             {  // if
  1004.             pInstance = (PPERFINSTANCEDEF) LBData (hWndInstances, iInstanceIndex) ;
  1005.             if (pInstance == (PPERFINSTANCEDEF) LB_ERR)
  1006.                {
  1007.                pInstance = NULL;
  1008.                }
  1009.             AddOneChartLine (hDlg, pCounter, lpszCounter, pInstance) ;
  1010.             }  // if
  1011.          }  // for
  1012.       
  1013.       if (bDelayAddAction)
  1014.          {
  1015.          // now do the post add-line actions
  1016.          bDelayAddAction = FALSE ;
  1017.          if (InReportAdd())
  1018.             {
  1019.             PREPORT pReport ;
  1020.       
  1021.             pReport = ReportData (hWndReport) ;
  1022.             ReportAddAction (pReport) ;
  1023.             }
  1024.          else if (InChartAdd())
  1025.             {
  1026.             GraphAddAction () ;
  1027.             LegendSetRedraw (hWndGraphLegend, TRUE) ;
  1028.             }
  1029.          else if (InAlertAdd())
  1030.             {
  1031.             AlertAddAction () ;
  1032.             LegendSetRedraw (hWndAlertLegend, TRUE) ;
  1033.             }
  1034.          }
  1035.       }
  1036.    else
  1037.       {
  1038.       pInstance = NULL;
  1039.       AddOneChartLine (hDlg, pCounter, lpszCounter, pInstance) ;
  1040.       }
  1041.  
  1042.    return (TRUE) ;
  1043.    }  // AddCounter
  1044.  
  1045.  
  1046. //==========================================================================//
  1047. //                              Message Handlers                            //
  1048. //==========================================================================//
  1049.  
  1050.  
  1051. BOOL /*static*/ OnInitDialog (HWND hDlg)
  1052.    {
  1053.    int            i ;
  1054.    FLOAT          ScaleFactor ;
  1055.    TCHAR          tempBuff[ShortTextLen] ;
  1056.    TCHAR          szCaption [WindowCaptionLen] ;
  1057.    TCHAR          szRemoteComputerName[MAX_COMPUTERNAME_LENGTH + 3] ;
  1058.    HWND           hWndComputer = DialogControl (hDlg, IDD_ADDLINECOMPUTER);
  1059.    HWND           hWndObjects = DialogControl (hDlg, IDD_ADDLINEOBJECT);
  1060.    HWND           hWndInstances = DialogControl (hDlg, IDD_ADDLINEINSTANCE);
  1061.    HWND           hWndCounters = DialogControl (hDlg, IDD_ADDLINECOUNTER);
  1062.    HWND           hWndColors = DialogControl (hDlg, IDD_ADDLINECOLOR) ;
  1063.    HWND           hWndWidths = DialogControl (hDlg, IDD_ADDLINEWIDTH) ;
  1064.    HWND           hWndStyles = DialogControl (hDlg, IDD_ADDLINESTYLE) ;
  1065.    HWND           hWndScales = DialogControl (hDlg, IDD_ADDLINESCALE) ;
  1066.  
  1067.    // this is used to tell UPdateLines not to mark any
  1068.    // system as not used
  1069.    bAddLineInProgress = TRUE ;
  1070.    
  1071.    // turn this off until the Explain text button is clicked
  1072.    bExplainTextButtonHit = FALSE ;
  1073.  
  1074.    if (InAlertAdd())
  1075.       {
  1076.       pszAlertProgram = (LPTSTR) MemoryAllocate (FilePathLen * sizeof (TCHAR)) ;
  1077.       }
  1078.  
  1079.    if (!PlayingBackLog ())
  1080.       pPerfData = MemoryAllocate (STARTING_SYSINFO_SIZE) ;
  1081.  
  1082.    pSystem = NULL ;
  1083.  
  1084.    if (!bEditLine && PlayingBackLog())
  1085.       {
  1086.       pPerfData = DataFromIndexPosition (&(PlaybackLog.StartIndexPos), NULL) ;
  1087.       GetPerfComputerName(pPerfData, szRemoteComputerName);
  1088.       DialogSetString (hDlg, IDD_ADDLINECOMPUTER, szRemoteComputerName);
  1089.       }
  1090.    else
  1091.       {
  1092.       if (bEditLine)
  1093.          {
  1094.          DialogSetString (hDlg, IDD_ADDLINECOMPUTER,
  1095.             pLineEdit->lnSystemName) ;
  1096.          }
  1097.       else
  1098.          {
  1099.             //Try to use current system (if any), otherwise computer specified on commandline (if any),
  1100.             //otherwise local computer
  1101.          DialogSetString (hDlg, IDD_ADDLINECOMPUTER,
  1102.             pCurrentSystem ?
  1103.                 pCurrentSystem :
  1104.                 (( CmdLineComputerName[0] ) ?
  1105.                    CmdLineComputerName :
  1106.                    LocalComputerName )) ;
  1107.          }
  1108.       }
  1109.  
  1110.    OnComputerChanged (hDlg) ;
  1111.  
  1112.    //=============================//
  1113.    // Set default line values     //
  1114.    //=============================//
  1115.  
  1116.    bAlertOver = bEditLine ? pLineEdit->bAlertOver : TRUE ;
  1117.    bEveryTime = bEditLine ? pLineEdit->bEveryTime : TRUE ;
  1118.  
  1119.    //=============================//
  1120.    // Fill line attribute CBs     //
  1121.    //=============================//
  1122.  
  1123.    // Load the colors combobox, select the default color.
  1124.    for (i = 0 ; i < NumColorIndexes () ; i++)
  1125.        CBAdd (hWndColors, i) ;
  1126.    CBSetSelection (hWndColors, pVisual->iColorIndex) ;
  1127.  
  1128.    // Load the widths combobox, select the default width.
  1129.    for (i = 0 ; i < NumWidthIndexes () ; i++)
  1130.       CBAdd (hWndWidths, i) ;
  1131.    CBSetSelection (hWndWidths, pVisual->iWidthIndex) ;
  1132.  
  1133.    // Load the styles combobox, select the default style.
  1134.    for (i = 0 ; i < NumStyleIndexes () ; i++)
  1135.       CBAdd (hWndStyles, i) ;
  1136.    CBSetSelection (hWndStyles, pVisual->iStyleIndex) ;
  1137.  
  1138. #if (!WIDESTYLES)
  1139.    DialogEnable (hDlg, IDD_ADDLINESTYLE, pVisual->iWidthIndex == 0) ;
  1140.    DialogEnable (hDlg, IDD_ADDLINESTYLETEXT, pVisual->iWidthIndex == 0) ;
  1141.  
  1142.    if (pVisual->iWidthIndex == 0 && pVisual->iStyleIndex > 0)
  1143.       {
  1144.       DialogEnable (hDlg, IDD_ADDLINEWIDTHTEXT, FALSE) ;
  1145.       DialogEnable (hDlg, IDD_ADDLINEWIDTH, FALSE) ;
  1146.       }
  1147. #endif
  1148.  
  1149.    // Init the scale combo box.
  1150.  
  1151.    StringLoad (IDS_DEFAULT, tempBuff) ;
  1152.    CBAdd (hWndScales, tempBuff) ;
  1153.  
  1154.    // we are formatting the scale factors during run-time so
  1155.    // the c-runtime library will pick up the default locale
  1156.    // decimal "charatcer".
  1157.    ScaleFactor = (FLOAT)0.000001 ;
  1158.    for (i = 0 ; i < NUMBER_OF_SCALE ; i++)
  1159.       {
  1160.       TSPRINTF(tempBuff, apszScaleFmt[i], ScaleFactor) ;
  1161.       ConvertDecimalPoint (tempBuff) ;
  1162.       ScaleFactor *= (FLOAT) 10.0 ;
  1163.       CBAdd (hWndScales, tempBuff) ;
  1164.       }
  1165.  
  1166.    CBSetSelection (hWndScales, bEditLine ? pLineEdit->iScaleIndex : DEFAULT_SCALE) ;
  1167.  
  1168.    
  1169.    CheckRadioButton (hDlg, IDD_ADDLINEIFOVER, IDD_ADDLINEIFUNDER, 
  1170.                      bAlertOver ? IDD_ADDLINEIFOVER: IDD_ADDLINEIFUNDER) ;
  1171.    CheckRadioButton (hDlg, IDD_ADDLINEPROGRAMFIRSTTIME, IDD_ADDLINEPROGRAMEVERYTIME, 
  1172.                      bEveryTime ? IDD_ADDLINEPROGRAMEVERYTIME: IDD_ADDLINEPROGRAMFIRSTTIME) ;
  1173.  
  1174.    if (bEditLine)
  1175.       {
  1176.       DialogSetText (hDlg, IDD_ADDLINEADD, IDS_OK) ;
  1177.       DialogSetFloat (hDlg, IDD_ADDLINEIFVALUE, pLineEdit->eAlertValue) ;
  1178.       if (pLineEdit->lpszAlertProgram)
  1179.          DialogSetString (hDlg, IDD_ADDLINEPROGRAM, 
  1180.                           pLineEdit->lpszAlertProgram) ;
  1181.  
  1182.       DialogEnable (hDlg, IDD_ADDLINECOMPUTERTEXT, FALSE) ;
  1183.       DialogEnable (hDlg, IDD_ADDLINECOMPUTER, FALSE) ;
  1184.       DialogEnable (hDlg, IDD_ADDLINEELLIPSES, FALSE) ;   
  1185.       DialogEnable (hDlg, IDD_ADDLINEOBJECTTEXT, FALSE) ;   
  1186.       DialogEnable (hDlg, IDD_ADDLINEOBJECT, FALSE) ;   
  1187.       DialogEnable (hDlg, IDD_ADDLINECOUNTERTEXT, FALSE) ;   
  1188.       DialogEnable (hDlg, IDD_ADDLINECOUNTER, FALSE) ;   
  1189.       DialogEnable (hDlg, IDD_ADDLINEINSTANCE, FALSE) ;   
  1190.       DialogEnable (hDlg, IDD_ADDLINEINSTANCETEXT, FALSE) ;   
  1191.       }
  1192.    else
  1193.       {
  1194.       // set the scroll limit on the edit box
  1195.       EditSetLimit (GetDlgItem(hDlg, IDD_CHOOSECOMPUTERNAME),
  1196.          MAX_SYSTEM_NAME_LENGTH-1) ;
  1197.  
  1198.       }
  1199.  
  1200.    if (PlayingBackLog())
  1201.       {
  1202.       DialogEnable (hDlg, IDD_ADDLINEEXPANDEXPLAIN, FALSE) ;   
  1203.       }
  1204.  
  1205.    //=============================//
  1206.    // LineType specific init      //
  1207.    //=============================//
  1208.  
  1209.    switch (iLineType)
  1210.       {
  1211.       case LineTypeChart:
  1212.          dwCurrentDlgID = bEditLine ?
  1213.                   HC_PM_idDlgEditChartLine : HC_PM_idDlgEditAddToChart ;
  1214.  
  1215.          StringLoad (bEditLine ? 
  1216.                      IDS_EDITCHART : IDS_ADDTOCHART, szCaption) ;
  1217.  
  1218.          DialogShow (hDlg, IDD_ADDLINEIFGROUP, FALSE) ;
  1219.          DialogShow (hDlg, IDD_ADDLINEIFVALUE, FALSE) ;
  1220.          DialogShow (hDlg, IDD_ADDLINEIFUNDER, FALSE) ;
  1221.          DialogShow (hDlg, IDD_ADDLINEIFOVER, FALSE) ;
  1222.  
  1223.          DialogShow (hDlg, IDD_ADDLINEPROGRAMGROUP, FALSE) ;
  1224.          DialogShow (hDlg, IDD_ADDLINEPROGRAM, FALSE) ;
  1225.          DialogShow (hDlg, IDD_ADDLINEPROGRAMFIRSTTIME, FALSE) ;
  1226.          DialogShow (hDlg, IDD_ADDLINEPROGRAMEVERYTIME, FALSE) ;
  1227.          break ;
  1228.  
  1229.       case LineTypeAlert:
  1230.          dwCurrentDlgID = bEditLine ?
  1231.                   HC_PM_idDlgEditAlertEntry : HC_PM_idDlgEditAddToAlert ;
  1232.  
  1233.          StringLoad (bEditLine ? 
  1234.                      IDS_EDITALERT : IDS_ADDTOALERT, szCaption) ;
  1235.  
  1236.          DialogShow (hDlg, IDD_ADDLINESCALE, FALSE) ;
  1237.          DialogShow (hDlg, IDD_ADDLINESCALETEXT, FALSE) ;
  1238.  
  1239.          DialogShow (hDlg, IDD_ADDLINEWIDTH, FALSE) ;
  1240.          DialogShow (hDlg, IDD_ADDLINEWIDTHTEXT, FALSE) ;
  1241.  
  1242.          DialogShow (hDlg, IDD_ADDLINESTYLE, FALSE) ;
  1243.          DialogShow (hDlg, IDD_ADDLINESTYLETEXT, FALSE) ;
  1244.  
  1245.          if (PlayingBackLog ())
  1246.             {
  1247.             DialogEnable (hDlg, IDD_ADDLINEPROGRAM, FALSE) ;
  1248.             DialogEnable (hDlg, IDD_ADDLINEPROGRAMGROUP, FALSE) ;
  1249.             DialogEnable (hDlg, IDD_ADDLINEPROGRAMEVERYTIME, FALSE) ;
  1250.             DialogEnable (hDlg, IDD_ADDLINEPROGRAMFIRSTTIME, FALSE) ;
  1251.             }
  1252.  
  1253.          // set the scroll limit on the edit boxes
  1254.  
  1255.          EditSetLimit (GetDlgItem(hDlg, IDD_ADDLINEIFVALUE), ShortTextLen) ;
  1256.          EditSetLimit (GetDlgItem(hDlg, IDD_ADDLINEPROGRAM), FilePathLen-1) ;
  1257.  
  1258.          break ;
  1259.  
  1260.       case LineTypeReport:
  1261.  
  1262.          dwCurrentDlgID = HC_PM_idDlgEditAddToReport ;
  1263.  
  1264.          StringLoad (bEditLine ? 
  1265.                      IDS_EDITREPORT : IDS_ADDTOREPORT, szCaption) ;
  1266.  
  1267.          DialogShow (hDlg, IDD_ADDLINEIFGROUP, FALSE) ;
  1268.          DialogShow (hDlg, IDD_ADDLINEIFVALUE, FALSE) ;
  1269.          DialogShow (hDlg, IDD_ADDLINEIFUNDER, FALSE) ;
  1270.          DialogShow (hDlg, IDD_ADDLINEIFOVER, FALSE) ;
  1271.  
  1272.          DialogShow (hDlg, IDD_ADDLINEPROGRAMGROUP, FALSE) ;
  1273.          DialogShow (hDlg, IDD_ADDLINEPROGRAM, FALSE) ;
  1274.          DialogShow (hDlg, IDD_ADDLINEPROGRAMFIRSTTIME, FALSE) ;
  1275.          DialogShow (hDlg, IDD_ADDLINEPROGRAMEVERYTIME, FALSE) ;
  1276.  
  1277.          DialogShow (hDlg, IDD_ADDLINECOLOR, FALSE) ;
  1278.          DialogShow (hDlg, IDD_ADDLINECOLORTEXT, FALSE) ;
  1279.          DialogShow (hDlg, IDD_ADDLINESCALE, FALSE) ;
  1280.          DialogShow (hDlg, IDD_ADDLINESCALETEXT, FALSE) ;
  1281.          DialogShow (hDlg, IDD_ADDLINEWIDTH, FALSE) ;
  1282.          DialogShow (hDlg, IDD_ADDLINEWIDTHTEXT, FALSE) ;
  1283.          DialogShow (hDlg, IDD_ADDLINESTYLE, FALSE) ;
  1284.          DialogShow (hDlg, IDD_ADDLINESTYLETEXT, FALSE) ;
  1285.          break ;
  1286.       }  // switch
  1287.  
  1288.    SetWindowText (hDlg, szCaption) ;
  1289.    SendDlgItemMessage (hDlg, 
  1290.                        IDD_ADDLINEEXPLAIN, WM_SETFONT, 
  1291.                        (WPARAM) hFontScales, (LPARAM) FALSE) ;
  1292.    WindowCenter (hDlg) ;
  1293.    return (TRUE) ;
  1294.    }  // OnInitDialog
  1295.  
  1296.  
  1297. BOOL /*static*/ OnObjectChanged (HDLG hDlg)
  1298. /*
  1299.    Effect:        Perform any actions necessary when the user has selected
  1300.                   a new object category from the object CB, or when a default
  1301.                   object is first selected into the dialog. In particular,
  1302.                   find and load the counters, instances, etc., for this
  1303.                   object.
  1304.  
  1305.    Called by:     OnInitDialog, AddLineDlgProc (in response to an 
  1306.                   IDM_ADDLINEOBJECT notification).
  1307. */
  1308.    {  // OnObjectChanged
  1309.    PPERFOBJECT    pObject ;
  1310.    HWND           hWndInstances = DialogControl (hDlg, IDD_ADDLINEINSTANCE);
  1311.    HWND           hWndCounters = DialogControl (hDlg, IDD_ADDLINECOUNTER);
  1312.    HWND           hWndObjects = DialogControl (hDlg, IDD_ADDLINEOBJECT);
  1313.  
  1314.    LBReset (hWndInstances) ;
  1315.    LBReset (hWndCounters) ;
  1316.  
  1317.    pObject = SelectedObject (hWndObjects, NULL) ;
  1318.    if (!pObject)
  1319.       return (FALSE) ;
  1320.  
  1321.    LoadCounters (hDlg, (UINT)pObject->DefaultCounter) ;
  1322.    LoadInstances (hDlg) ;  
  1323.  
  1324.    }  // OnObjectChanged
  1325.  
  1326.  
  1327.  
  1328. void /*static*/ OnEllipses (HWND hDlg)
  1329.    {
  1330.    TCHAR          szComputer [256] ;
  1331.  
  1332.    DialogText (hDlg, IDD_ADDLINECOMPUTER, szComputer) ;
  1333.    if (ChooseComputer (hDlg, szComputer)) 
  1334.       {  // if
  1335.       SetHourglassCursor() ;
  1336.       DialogSetString (hDlg, IDD_ADDLINECOMPUTER, szComputer) ;
  1337.       OnComputerChanged (hDlg) ;
  1338.       }  // if
  1339.    }
  1340.  
  1341. BOOL LineModifyAttributes (HWND hDlg, PLINE pLineToModify)
  1342. {
  1343.    LINEVISUAL  LineVisual ;
  1344.    HPEN        hLinePen ;
  1345.    int         iScaleIndex ;        // chart attribute
  1346.    FLOAT          eScale ;             // chart attribute
  1347.  
  1348.    BOOL        bLocalAlertOver ;         // alert attribute - over or under?
  1349.    FLOAT       eLocalAlertValue ;        // alert attribute - value to compare
  1350.    LPTSTR      lpLocalszAlertProgram ;   // alert attribute - program to run
  1351.    BOOL        bLocalEveryTime ;         // alert attribute - run every time or once?
  1352.    BOOL        bLocalAlerted ;           // alert attribute - alert happened on line?
  1353.  
  1354.    HPEN        hTempPen ;
  1355.    LPTSTR      lpTempAlertProgram ;
  1356.    HWND        hWndColors = DialogControl (hDlg, IDD_ADDLINECOLOR) ;
  1357.    HWND        hWndWidths = DialogControl (hDlg, IDD_ADDLINEWIDTH) ;
  1358.    HWND        hWndStyles = DialogControl (hDlg, IDD_ADDLINESTYLE) ;
  1359.    HWND        hWndScales = DialogControl (hDlg, IDD_ADDLINESCALE) ;
  1360.    
  1361.    //=============================//
  1362.    // Visual Values               //
  1363.    //=============================//
  1364.  
  1365.    LineVisual.iColorIndex = CBSelection (hWndColors) ;
  1366.    LineVisual.crColor = LineColor (LineVisual.iColorIndex) ;
  1367.  
  1368.    LineVisual.iWidthIndex = CBSelection (hWndWidths) ;
  1369.    LineVisual.iWidth = LineWidth (LineVisual.iWidthIndex) ;
  1370.  
  1371.    LineVisual.iStyleIndex = CBSelection (hWndStyles) ;
  1372.    LineVisual.iStyle = LineStyle (LineVisual.iStyleIndex) ;
  1373.  
  1374.    hLinePen = LineCreatePen (NULL, &(LineVisual), FALSE) ;
  1375.  
  1376.    //=============================//
  1377.    // Chart-related Values        //
  1378.    //=============================//
  1379.    
  1380.    if (InChartAdd())
  1381.       {
  1382.       iScaleIndex = CBSelection (hWndScales) ;
  1383.       if (iScaleIndex == 0)
  1384.           {
  1385.           // use the default scale
  1386.           eScale = (FLOAT) pow ((double)10.0,
  1387.               (double)pLineToModify->lnCounterDef.DefaultScale) ;
  1388.           }
  1389.       else
  1390.           {
  1391.           eScale = DialogFloat (hDlg, IDD_ADDLINESCALE, NULL) ;
  1392.           }
  1393.       }
  1394.  
  1395.    //=============================//
  1396.    // Alert Related Values        //
  1397.    //=============================//
  1398.    
  1399.    if (InAlertAdd())
  1400.       {
  1401.       bLocalAlertOver = bAlertOver ;
  1402.       eLocalAlertValue = eAlertValue ;
  1403.       bLocalEveryTime =
  1404.          IsDlgButtonChecked (hDlg, IDD_ADDLINEPROGRAMEVERYTIME) ;
  1405.       bLocalAlerted = FALSE ;
  1406.       lpLocalszAlertProgram = StringAllocate (pszAlertProgram) ;
  1407.       }
  1408.  
  1409.    // Just do it..
  1410.    pLineToModify->Visual = LineVisual ;
  1411.    if (pLineToModify->hPen)
  1412.       {
  1413.       hTempPen = pLineToModify->hPen ;
  1414.       pLineToModify->hPen = hLinePen ;
  1415.       DeletePen (hTempPen) ;
  1416.       }
  1417.  
  1418.    if (InChartAdd())
  1419.       {
  1420.       pLineToModify->iScaleIndex = iScaleIndex ;
  1421.       pLineToModify->eScale = eScale ;
  1422.  
  1423.       }
  1424.  
  1425.    if (InAlertAdd())
  1426.       {
  1427.       HBRUSH   hOldBrush;
  1428.       pLineToModify->bAlertOver = bLocalAlertOver ;
  1429.       pLineToModify->eAlertValue = eLocalAlertValue ;
  1430.       pLineToModify->bEveryTime = bLocalEveryTime ;
  1431.       pLineToModify->bAlerted = FALSE ;
  1432.  
  1433.       hOldBrush = pLineToModify->hBrush ;
  1434.       pLineToModify->hBrush = CreateSolidBrush (pLineToModify->Visual.crColor) ;
  1435.       DeleteBrush (hOldBrush);
  1436.  
  1437.       lpTempAlertProgram = pLineToModify->lpszAlertProgram ;
  1438.       pLineToModify->lpszAlertProgram = lpLocalszAlertProgram ;
  1439.  
  1440.       if (lpTempAlertProgram)
  1441.          {
  1442.          MemoryFree (lpTempAlertProgram) ;
  1443.          }
  1444.       }
  1445.  
  1446.    return (TRUE) ;
  1447.  
  1448. } // LineModifyAttributes
  1449.  
  1450. BOOL OnAddLines (HWND hDlg)
  1451.    {  
  1452.    PPERFCOUNTERDEF   pCounter ;
  1453.    TCHAR             szCounter [256] ;
  1454.    BOOL              bOK ;
  1455.    int               iCounter ;
  1456.    int               iCounterNum ;
  1457.    HWND              hWndCounters = DialogControl (hDlg, IDD_ADDLINECOUNTER);
  1458.  
  1459.    if (ComputerChange)
  1460.       {
  1461.       // if computer has changed, don't want to continue
  1462.       // because the perfdata may have changed
  1463.       OnComputerChanged (hDlg) ;
  1464.       return (TRUE) ;
  1465.       }
  1466.  
  1467.    //=============================//
  1468.    // Dialog Values Acceptable?   //
  1469.    //=============================//
  1470.  
  1471.    if (InAlertAdd ())
  1472.       {
  1473.       eAlertValue = DialogFloat (hDlg, IDD_ADDLINEIFVALUE, &bOK) ;
  1474.       if (!bOK)
  1475.          {
  1476.          DlgErrorBox (hDlg, ERR_NEEDALERTVALUE);
  1477.          SetFocus (DialogControl (hDlg, IDD_ADDLINEIFVALUE)) ;
  1478.          return (FALSE) ;
  1479.          }  // if
  1480.       }  // if
  1481.  
  1482.    if (bEditLine)
  1483.       {
  1484.       LineModifyAttributes (hDlg, pLineEdit) ;
  1485.       EndDialog (hDlg, TRUE) ;
  1486.       }
  1487.  
  1488.       // If the user changed the textbox for computer name and pressed enter,
  1489.       // the OnAddLines function would be called without a check of the 
  1490.       // computer name. This solves that problem.
  1491.    else
  1492.       {
  1493.  
  1494.       iCounterNum = LBNumItems (hWndCounters) ;
  1495.       for (iCounter = 0 ;
  1496.            iCounter < iCounterNum ;
  1497.            iCounter++)
  1498.          {  // for
  1499.          // NOTE: for now, we don't check for duplicate lines
  1500.          if (LBSelected (hWndCounters, iCounter))
  1501.             {  // if
  1502.             pCounter = (PPERFCOUNTERDEF) LBData (hWndCounters, iCounter) ;
  1503.             LBString (hWndCounters, iCounter, szCounter) ;
  1504.  
  1505.             if (!IsCounterSupported (pCounter->CounterType))
  1506.                {
  1507.                DlgErrorBox (hDlg, ERR_COUNTER_NOT_IMP);
  1508.                }
  1509.             else
  1510.                {
  1511.                AddCounter (hDlg, pCounter, szCounter) ;
  1512.                }
  1513.             }  // if
  1514.          }  // for
  1515.       DialogSetText (hDlg, IDCANCEL, IDS_DONE) ;
  1516.       } // else (not bEditLine)
  1517.  
  1518.    if (InChartAdd ())
  1519.       SizeGraphComponents (hWndGraph) ;
  1520.    if (InAlertAdd ())
  1521.       SizeAlertComponents (hWndAlert) ;
  1522.  
  1523.    WindowInvalidate (PerfmonViewWindow ()) ;
  1524.  
  1525.    }  // OnAddLines
  1526.  
  1527.  
  1528. void OnExpandExplain (HWND hDlg)
  1529. /*
  1530.    Effect:        Perform actions needed when user clicks on the Explain...
  1531.                   button. In particular, expand the dialog size to 
  1532.                   uncover the explain edit box, and gray out the button.
  1533. */
  1534.    {  // OnExpandExplain
  1535.    RECT           rectWindow ;
  1536.  
  1537.    // Disable button first
  1538.    DialogEnable (hDlg, IDD_ADDLINEEXPANDEXPLAIN, FALSE) ;
  1539.  
  1540.    // go get the help text
  1541.    bExplainTextButtonHit = TRUE ;
  1542.    OnCounterChanged (hDlg) ;
  1543.  
  1544.    GetWindowRect (hDlg, &rectWindow) ;
  1545.    MoveWindow (hDlg,
  1546.                rectWindow.left,
  1547.                rectWindow.top,
  1548.                rectWindow.right - rectWindow.left,
  1549.                rectWindow.bottom - rectWindow.top + 
  1550.                DialogHeight (hDlg, IDD_ADDLINEEXPLAINGROUP) + 
  1551.                yScrollHeight,
  1552.                TRUE) ;
  1553.  
  1554.    WindowCenter (hDlg) ;
  1555.  
  1556.    }  // OnExpandExplain
  1557.  
  1558.  
  1559.  
  1560. BOOL /*static*/ OnCommand (HWND hDlg, 
  1561.                        WPARAM wParam, 
  1562.                        LPARAM lParam)
  1563.    {
  1564.    int            iWidthIndex ;
  1565.    int            iStyleIndex ;
  1566.    HWND           hWndWidths = DialogControl (hDlg, IDD_ADDLINEWIDTH) ;
  1567.    HWND           hWndStyles = DialogControl (hDlg, IDD_ADDLINESTYLE) ;
  1568.  
  1569.    switch (LOWORD (wParam))
  1570.       {
  1571.       case IDD_ADDLINEIFVALUE:
  1572.          // We don't get the value when the user types it. We get it when
  1573.          // the user attempts to add the line.
  1574.          break ;
  1575.  
  1576.       case IDD_ADDLINEPROGRAM:
  1577.          GetDlgItemText (hDlg,
  1578.             IDD_ADDLINEPROGRAM,
  1579.             pszAlertProgram,
  1580.             FilePathLen - 1) ;
  1581.          break ;
  1582.  
  1583.       case IDD_ADDLINEIFOVER:
  1584.       case IDD_ADDLINEIFUNDER:
  1585.          bAlertOver = (LOWORD (wParam) == IDD_ADDLINEIFOVER) ;
  1586.          CheckRadioButton (hDlg, IDD_ADDLINEIFOVER, IDD_ADDLINEIFUNDER, 
  1587.                            bAlertOver ? IDD_ADDLINEIFOVER: IDD_ADDLINEIFUNDER) ;
  1588.          break ;
  1589.  
  1590.       case IDD_ADDLINEPROGRAMFIRSTTIME:
  1591.       case IDD_ADDLINEPROGRAMEVERYTIME:
  1592.          bEveryTime = (LOWORD (wParam) == IDD_ADDLINEPROGRAMEVERYTIME) ;
  1593.          CheckRadioButton (hDlg, IDD_ADDLINEPROGRAMFIRSTTIME, IDD_ADDLINEPROGRAMEVERYTIME, 
  1594.                            bEveryTime ? IDD_ADDLINEPROGRAMEVERYTIME: IDD_ADDLINEPROGRAMFIRSTTIME) ;
  1595.          break ;
  1596.  
  1597.       case IDD_ADDLINEWIDTH:
  1598.          iWidthIndex = CBSelection (hWndWidths) ;
  1599. #if (!WIDESTYLES)
  1600.          DialogEnable (hDlg, IDD_ADDLINESTYLETEXT, 
  1601.                        iWidthIndex == 0  || iWidthIndex == CB_ERR) ;
  1602.          DialogEnable (hDlg, IDD_ADDLINESTYLE, 
  1603.                        iWidthIndex == 0  || iWidthIndex == CB_ERR) ;
  1604. #endif
  1605.          break ;
  1606.  
  1607.       case IDD_ADDLINESTYLE:
  1608.          iStyleIndex = CBSelection (hWndStyles) ;
  1609. #if (!WIDESTYLES)
  1610.          DialogEnable (hDlg, IDD_ADDLINEWIDTHTEXT, 
  1611.                        iStyleIndex == 0  || iStyleIndex == CB_ERR) ;
  1612.          DialogEnable (hDlg, IDD_ADDLINEWIDTH, 
  1613.                        iStyleIndex == 0  || iStyleIndex == CB_ERR) ;
  1614. #endif
  1615.          break ;
  1616.  
  1617.       case IDCANCEL:
  1618.          EndDialog (hDlg, 0);
  1619.          return (TRUE);
  1620.          break ;
  1621.  
  1622.       case IDD_ADDLINEADD :
  1623.  
  1624.          if (ComputerChange)
  1625.             {
  1626.             SetHourglassCursor() ;
  1627.             OnComputerChanged (hDlg) ;
  1628.             }
  1629.          else
  1630.             {
  1631.             SetHourglassCursor() ;
  1632.             OnAddLines (hDlg) ;
  1633.             SetArrowCursor() ;
  1634.             }
  1635.          break;
  1636.  
  1637.       case IDD_ADDLINEEXPANDEXPLAIN :
  1638.          if (ComputerChange)
  1639.             {
  1640.             SetHourglassCursor() ;
  1641.             OnComputerChanged (hDlg) ;
  1642.             }
  1643.          else
  1644.             {
  1645.             OnExpandExplain (hDlg) ;
  1646.             }
  1647.          break;
  1648.  
  1649.       case IDD_ADDLINEELLIPSES:
  1650.          SetHourglassCursor() ;
  1651.          OnEllipses (hDlg) ;
  1652.          SetArrowCursor() ;
  1653.          break ;
  1654.  
  1655.  
  1656.       case IDD_ADDLINECOUNTER:
  1657.          if (ComputerChange)
  1658.             {
  1659.             SetHourglassCursor() ;
  1660.             OnComputerChanged (hDlg) ;
  1661.             }
  1662.          else if (HIWORD (wParam) == LBN_SELCHANGE)
  1663.             OnCounterChanged (hDlg) ;
  1664.          break ;
  1665.            
  1666.       
  1667.       case IDD_ADDLINEOBJECT:
  1668.          if (ComputerChange)
  1669.             {
  1670.             SetHourglassCursor() ;
  1671.             OnComputerChanged (hDlg) ;
  1672.             }
  1673.          else if (HIWORD (wParam) == CBN_SELCHANGE)
  1674.             OnObjectChanged (hDlg) ;
  1675.          break ;
  1676.  
  1677.       case IDD_ADDLINEINSTANCE:
  1678.          if (ComputerChange)
  1679.             {
  1680.             SetHourglassCursor() ;
  1681.             OnComputerChanged (hDlg) ;
  1682.             }
  1683.          break ;
  1684.  
  1685.       case IDD_ADDLINECOMPUTER:
  1686.          if (HIWORD (wParam) == EN_UPDATE)
  1687.             {
  1688.             ComputerChange = TRUE ;
  1689.             }
  1690.          break ;
  1691.  
  1692.       case IDD_ADDLINEHELP:
  1693.          CallWinHelp (dwCurrentDlgID) ;
  1694.          break ;
  1695.  
  1696.         default:
  1697.             break;
  1698.         } // switch
  1699.  
  1700.    return (FALSE) ;
  1701.    } // OnCommand
  1702.  
  1703.  
  1704. void /*static*/ OnMeasureItem (HWND hDlg, 
  1705.                            PMEASUREITEMSTRUCT pMI)
  1706.    {
  1707.    pMI->CtlType    = ODT_COMBOBOX ;
  1708.    pMI->CtlID      = IDD_ADDLINECOLOR ;
  1709.    pMI->itemData   = 0 ;
  1710.    pMI->itemWidth  = 0 ;
  1711.  
  1712.    // need 14 in order to draw the thickest line width
  1713.    pMI->itemHeight = 14 ;
  1714. //   pMI->itemHeight = 12 ;
  1715.    }
  1716.  
  1717. //***************************************************************************
  1718. //                                                                          *
  1719. //  FUNCTION   : HandleSelectionState(LPDRAWITEMSTRUCT)                     *
  1720. //                                                                          *
  1721. //  PURPOSE    : Handles a change in an item selection state. If an item is *
  1722. //               selected, a black rectangular frame is drawn around that   *
  1723. //               item; if an item is de-selected, the frame is removed.     *
  1724. //                                                                          *
  1725. //  COMMENT    : The black selection frame is slightly larger than the gray *
  1726. //               focus frame so they won't paint over each other.           *
  1727. //                                                                          *
  1728. //***************************************************************************
  1729. void static HandleSelectionState (LPDRAWITEMSTRUCT    lpdis)
  1730. {
  1731.     HBRUSH    hbr ;
  1732.  
  1733.     if (lpdis->itemState & ODS_SELECTED)
  1734.     {
  1735.         // selecting item -- paint a black frame
  1736.         hbr = GetStockObject(BLACK_BRUSH) ;
  1737.     }
  1738.     else
  1739.     {
  1740.         // de-selecting item -- remove frame 
  1741.         hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW)) ;
  1742.     }
  1743.     FrameRect(lpdis->hDC, (LPRECT)&lpdis->rcItem, hbr) ;
  1744.     DeleteObject (hbr) ;
  1745.    }  // HandleSelectionState
  1746.  
  1747. //***************************************************************************
  1748. //                                                                          *
  1749. //  FUNCTION   : HandleFocusState(LPDRAWITEMSTRUCT)                         *
  1750. //                                                                          *
  1751. //  PURPOSE    : Handle a change in item focus state. If an item gains the  *
  1752. //               input focus, a gray rectangular frame is drawn around that *
  1753. //               item; if an item loses the input focus, the gray frame is  *
  1754. //               removed.                                                   *
  1755. //                                                                          *
  1756. //  COMMENT    : The gray focus frame is slightly smaller than the black    *
  1757. //               selection frame so they won't paint over each other.       *
  1758. //                                                                          *
  1759. //***************************************************************************
  1760. void static HandleFocusState (LPDRAWITEMSTRUCT    lpdis)
  1761.    {
  1762.     RECT       rc ;
  1763.     HBRUSH    hbr ;
  1764.  
  1765.     // Resize rectangle to place focus frame between the selection
  1766.     // frame and the item.
  1767.     CopyRect ((LPRECT)&rc, (LPRECT)&lpdis->rcItem) ;
  1768.     InflateRect ((LPRECT)&rc, -OWNER_DRAW_FOCUS, -OWNER_DRAW_FOCUS) ;
  1769.  
  1770.     if (lpdis->itemState & ODS_FOCUS)
  1771.     {
  1772.         // gaining input focus -- paint a gray frame
  1773.         hbr = GetStockObject(GRAY_BRUSH) ;
  1774.     }
  1775.     else
  1776.     {
  1777.         // losing input focus -- remove (paint over) frame
  1778.         hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW)) ;
  1779.     }
  1780.     FrameRect(lpdis->hDC, (LPRECT)&rc, hbr) ;
  1781.     DeleteObject (hbr) ;
  1782.    }  // HandleFocusState
  1783.  
  1784. void /*static*/ OnDrawItem (HWND hDlg, PDRAWITEMSTRUCT pDI)
  1785.    {  // OnDrawItem
  1786.    HDC            hDC ;
  1787.    PRECT          prect ;
  1788.    INT            itemData, 
  1789.                   itemID, 
  1790.                   CtlID, 
  1791.                   itemAction ;
  1792.    LOGBRUSH       logBrush ;
  1793.    HANDLE         hBrush, 
  1794.                   hOldBrush, 
  1795.                   hPen, 
  1796.                   hOldPen ;
  1797.    INT            x1, y1, x2, y2, cy ;
  1798.    POINT          point ;
  1799.    INT            iPenWidth ;
  1800.    COLORREF       BackgroundColor ;
  1801.  
  1802.    hDC        = pDI-> hDC ;
  1803.    CtlID      = pDI->CtlID ;
  1804.    prect      = &pDI->rcItem ;
  1805.    itemData   = pDI->itemData ;
  1806.    itemID     = pDI->itemID ;
  1807.    itemAction = pDI->itemAction ;
  1808.  
  1809.  
  1810.    if (itemID == -1)
  1811.       {
  1812.       // invalid ID, can't go on
  1813.       HandleFocusState (pDI) ;
  1814.       }
  1815.    else if (itemAction == ODA_SELECT)
  1816.       {
  1817.       HandleSelectionState(pDI);
  1818.       }
  1819.    else if (itemAction == ODA_FOCUS)
  1820.       {
  1821.       HandleFocusState (pDI) ;
  1822.       }
  1823.    else
  1824.       {
  1825.       
  1826.       // draw the entire item
  1827.       
  1828.       InflateRect (prect, -OWNER_DRAWN_ITEM, -OWNER_DRAWN_ITEM) ;
  1829.  
  1830.       switch (CtlID)
  1831.          {  // switch
  1832.          case IDD_ADDLINECOLOR:
  1833.  
  1834.             // Draw a color rectangle into the control area
  1835.  
  1836.             logBrush.lbStyle = BS_SOLID ;
  1837.             logBrush.lbColor = (COLORREF) argbColors[itemID] ;
  1838.             logBrush.lbHatch = 0 ;
  1839.  
  1840.             hBrush = CreateBrushIndirect (&logBrush) ;
  1841.             hOldBrush = SelectObject (hDC, hBrush) ;
  1842.  
  1843.             hPen = GetStockObject (NULL_PEN) ;
  1844.             hOldPen = SelectObject (hDC, hPen) ;
  1845.  
  1846.             x1 = prect->left ;
  1847.             y1 = prect->top ;
  1848.             x2 = prect->right ;
  1849.             y2 = prect->bottom ;
  1850.  
  1851.             Rectangle (hDC, x1, y1, x2, y2) ;
  1852.  
  1853.             SelectObject (hDC, hOldBrush) ;
  1854.             DeleteObject (hBrush) ;
  1855.  
  1856.             InflateRect (prect, OWNER_DRAWN_ITEM, OWNER_DRAWN_ITEM) ;
  1857.  
  1858.             HandleSelectionState (pDI) ;
  1859.             HandleFocusState (pDI) ;
  1860.  
  1861.             break ;
  1862.  
  1863.          case IDD_ADDLINEWIDTH:
  1864.          case IDD_ADDLINESTYLE:
  1865.  
  1866.             // First draw a rectangle, white interior, null border
  1867.             hBrush = GetStockObject (WHITE_BRUSH) ;
  1868.             hOldBrush = SelectObject (hDC, hBrush) ;
  1869.  
  1870.             // we need to set the bk color in order to draw
  1871.             // the dash lines coorectly during focus.  Otherwise,
  1872.             // the COLOR_WINDOW background will make all dash lines
  1873.             // look like solid line...
  1874.             BackgroundColor = SetBkColor (hDC, crWhite) ;
  1875.  
  1876.             hPen = GetStockObject (NULL_PEN) ;
  1877.             hOldPen = SelectObject (hDC, hPen) ;
  1878.  
  1879.             x1 = prect->left ;
  1880.             y1 = prect->top ;
  1881.             x2 = prect->right ;
  1882.             y2 = prect->bottom ;
  1883.  
  1884.             Rectangle (hDC, x1, y1, x2, y2) ;
  1885.  
  1886.             SelectObject (hDC, hOldPen) ;
  1887.  
  1888.             // Draw a line of the itemID width in the middle
  1889.             // of the control area.
  1890.  
  1891.             if (CtlID == IDD_ADDLINEWIDTH)
  1892.                {
  1893.                iPenWidth = LineWidth (itemID) ;
  1894.                hPen = CreatePen (PS_SOLID, iPenWidth, RGB (0, 0, 0)) ;
  1895.                }
  1896.             else
  1897.                {
  1898.                hPen = CreatePen (itemID, 1, RGB (0, 0, 0)) ;
  1899.                }
  1900.  
  1901.             hOldPen = SelectObject (hDC, hPen) ;
  1902.  
  1903.             x1 = prect->left + 8 ;
  1904.             cy = prect->bottom - prect->top ;
  1905.             y1 = prect->top + (cy / 2) - 1 ;
  1906.             x2 = prect->right - 8 ;
  1907.             MoveToEx (hDC, x1, y1, &point) ;
  1908.             LineTo (hDC, x2, y1) ;
  1909.  
  1910.             SelectObject (hDC, hOldPen) ;
  1911.             DeleteObject (hPen) ;
  1912.             SelectObject (hDC, hOldBrush) ;
  1913.             BackgroundColor = SetBkColor (hDC, BackgroundColor) ;
  1914.  
  1915.             InflateRect (prect, OWNER_DRAWN_ITEM, OWNER_DRAWN_ITEM) ;
  1916.  
  1917.             HandleSelectionState (pDI) ;
  1918.             HandleFocusState (pDI) ;
  1919.  
  1920.             break ;
  1921.          }   // switch
  1922.       }  // draw entire item   
  1923.    }  // OnDrawItem
  1924.                         
  1925.  
  1926. void /*static*/ OnDestroy (HDLG hDlg)
  1927.    {  // OnDestroy
  1928.    if (!PlayingBackLog ())
  1929.       MemoryFree (pPerfData) ;
  1930.  
  1931.    if (pszAlertProgram)
  1932.       {
  1933.       MemoryFree (pszAlertProgram) ;
  1934.       pszAlertProgram = NULL ;
  1935.       }
  1936.  
  1937.    pLineEdit = NULL ;
  1938.    bAddLineInProgress = FALSE ;
  1939.    dwCurrentDlgID = 0 ;
  1940.    bExplainTextButtonHit = FALSE ;
  1941.    }  // OnDestroy
  1942.    
  1943.  
  1944.  
  1945. //==========================================================================//
  1946. //                             Exported Functions                           //
  1947. //==========================================================================//
  1948.  
  1949.  
  1950.  
  1951. BOOL FAR PASCAL AddLineDlgProc (HWND hDlg, 
  1952.                                 WORD msg, 
  1953.                                 DWORD wParam, 
  1954.                                 LONG lParam)
  1955.    {  // AddLineDlgProc
  1956.  
  1957.    BOOL Status;
  1958.  
  1959.    switch (msg)
  1960.       {  // switch
  1961.       case WM_COMMAND:
  1962.          OnCommand (hDlg, wParam, lParam) ;
  1963.          return (FALSE) ;
  1964.          break ;
  1965.  
  1966.        case WM_INITDIALOG:
  1967.          SetHourglassCursor() ;
  1968.          Status = OnInitDialog (hDlg) ;
  1969.          SetArrowCursor() ;
  1970.  
  1971.          // set focus on the "Add" button instead of the "Computer"
  1972.          SetFocus (DialogControl (hDlg, IDD_ADDLINEADD)) ;
  1973.          return FALSE ;
  1974.          break ;
  1975.  
  1976.       case WM_MEASUREITEM:
  1977.          OnMeasureItem (hDlg, (PMEASUREITEMSTRUCT) lParam) ;
  1978.          return (TRUE) ;
  1979.          break ;
  1980.  
  1981.       case WM_DRAWITEM:
  1982.          OnDrawItem (hDlg, (PDRAWITEMSTRUCT) lParam) ;
  1983.          return (TRUE) ;
  1984.          break ;
  1985.  
  1986.       case WM_DESTROY:
  1987.          OnDestroy (hDlg) ;
  1988.          break ;
  1989.            
  1990.        default:
  1991.           break;
  1992.       }  // switch
  1993.  
  1994.    return (FALSE) ;
  1995.    }  // AddLineDlgProc
  1996.  
  1997.  
  1998.  
  1999.  
  2000. BOOL AddLine (HWND hWndParent, 
  2001.               PPERFSYSTEM *ppSystemFirstView,
  2002.               PLINEVISUAL pLineVisual,
  2003.               LPTSTR pInCurrentSystem,
  2004.               int iLineTypeToAdd)
  2005. /*
  2006.    Effect:        Display the add line dialog box, allowing the user
  2007.                   to specify the computer, object, counter, instance,
  2008.                   and scale for a line.  The user can also select the
  2009.                   visual aspects of color, width and line style.
  2010.  
  2011. */                  
  2012.    {  // AddLine
  2013.    pLineEdit = NULL ;
  2014.  
  2015.    ppSystemFirst = ppSystemFirstView ;   
  2016.    iLineType = iLineTypeToAdd ;
  2017.    pVisual = pLineVisual ;
  2018.    pCurrentSystem = pInCurrentSystem ;
  2019.    
  2020.    return (DialogBox (hInstance, idDlgAddLine, 
  2021.                       hWndParent, (DLGPROC) AddLineDlgProc)) ;
  2022.    }  // AddLine
  2023.  
  2024.  
  2025.  
  2026. BOOL EditLine (HWND hWndParent,
  2027.                PPERFSYSTEM *ppSystemFirstView,
  2028.                PLINE pLineToEdit,
  2029.                int iLineTypeToEdit)
  2030.    {  // EditLine
  2031.    if (!pLineToEdit)
  2032.       {
  2033.       return (FALSE) ;
  2034.       }
  2035.  
  2036.    pLineEdit = pLineToEdit ;
  2037.  
  2038.    ppSystemFirst = ppSystemFirstView ;   
  2039.    iLineType = iLineTypeToEdit ;
  2040.    pVisual = &(pLineToEdit->Visual) ;
  2041.    
  2042.    return (DialogBox (hInstance, idDlgAddLine, 
  2043.                       hWndParent, (DLGPROC) AddLineDlgProc)) ;
  2044.    }  // EditLine
  2045. 
  2046.