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