Annotation of mstools/samples/sdktools/perfmon/report.c, revision 1.1.1.1

1.1       root        1: #include "perfmon.h"
                      2: #include <stdio.h>      // for sprintf
                      3: #include <string.h>     // for strncpy
                      4: #include "report.h"     // Exported declarations for this file
                      5: 
                      6: #include "addline.h"    // for AddLine, EditLine
                      7: #include "perferr.h"    // for PostError
                      8: #include "fileutil.h"   // for FileHandleCreate
                      9: #include "line.h"       // for LineAppend
                     10: #include "pmemory.h"    // for MemoryXXX (mallloc-type) routines
                     11: #include "perfdata.h"   // for UpdateLines
                     12: #include "perfmops.h"   // for DoWindowDrag
                     13: #include "playback.h"   // for PlaybackLines, PlayingBackLog
                     14: #include "print.h"      // for PrintDC
                     15: #include "system.h"     // for SystemGet
                     16: #include "utils.h"
                     17: #include "menuids.h"    // for IDM_VIEWREPORT
                     18: #include "fileopen.h"   // for FileGetName
                     19: 
                     20: 
                     21: //==========================================================================//
                     22: //                                Local Data                                //
                     23: //==========================================================================//
                     24: 
                     25: TCHAR          szSystemFormat [ResourceStringLen] ;
                     26: TCHAR          szObjectFormat [ResourceStringLen] ;
                     27: 
                     28: 
                     29: 
                     30: 
                     31: 
                     32: //==========================================================================//
                     33: //                                  Constants                               //
                     34: //==========================================================================//
                     35: 
                     36: 
                     37: #define xSystemMargin               (xScrollWidth)
                     38: #define xObjectMargin               (2 * xScrollWidth)
                     39: #define xCounterMargin              (3 * xScrollWidth)
                     40: #define xColumnMargin               (xScrollWidth)
                     41: 
                     42: #define RightHandMargin             xObjectMargin
                     43: #define ValueMargin(pReport)       \
                     44:    (4 * xScrollWidth + pReport->xMaxCounterWidth)
                     45: 
                     46: 
                     47: //=============================//
                     48: // Report Class                //
                     49: //=============================//
                     50: 
                     51: 
                     52: TCHAR   szReportWindowClass[] = TEXT("PerfmonReportClass") ;
                     53: #define dwReportClassStyle           (CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS)
                     54: #define iReportClassExtra            (0)
                     55: #define iReportWindowExtra           (0)
                     56: #define dwReportWindowStyle          (WS_CHILD | WS_VSCROLL | WS_HSCROLL)
                     57: 
                     58: 
                     59: #define szValuePlaceholder          TEXT("-999999999.999")
                     60: #define szLargeValueFormat          TEXT("%12.0f")
                     61: #define eStatusLargeValueMax        ((FLOAT) 999999999.0)
                     62: #define szValueFormat               TEXT("%12.3f")
                     63: 
                     64: 
                     65: //==========================================================================//
                     66: //                              Local Functions                             //
                     67: //==========================================================================//
                     68: 
                     69: 
                     70: PREPORT AllocateReportData (HWND hWndReport)
                     71:    {
                     72:    PREPORT        pReport ;
                     73: 
                     74:    pReport = ReportData (hWndReport) ;
                     75: 
                     76:    pReport->hWnd = hWndReport ;
                     77:    pReport->iStatus = iPMStatusClosed ;
                     78:    pReport->bManualRefresh = FALSE ;
                     79:    pReport->bModified = FALSE ;
                     80: 
                     81:    pReport->Visual.iColorIndex = 0 ;
                     82:    pReport->Visual.iWidthIndex = -1 ;
                     83:    pReport->Visual.iStyleIndex = -1 ;
                     84: 
                     85:    pReport->iIntervalMSecs = iDefaultReportIntervalSecs * 1000 ;
                     86:    pReport->pSystemFirst = NULL ;
                     87:    pReport->pLineFirst = NULL ;
                     88: 
                     89:    pReport->pLineCurrent = NULL ;
                     90: 
                     91:    return (pReport) ;
                     92:    }  // AllocateReportData
                     93: 
                     94: 
                     95: void FreeReportData (PREPORT pReport)
                     96:    {  // FreeReportData
                     97:    }  // FreeReportData
                     98: 
                     99: 
                    100: 
                    101: BOOL LineCounterRemove (PPLINE ppLineFirst,
                    102:                         PLINE pLineRemove)
                    103:    {
                    104:    PLINE          pLine ;
                    105: 
                    106:    if (*ppLineFirst == pLineRemove)
                    107:       {
                    108:       *ppLineFirst = (*ppLineFirst)->pLineCounterNext ;
                    109:       return (TRUE) ;
                    110:       }
                    111: 
                    112:    for (pLine = *ppLineFirst ;
                    113:         pLine->pLineCounterNext ;
                    114:         pLine = pLine->pLineCounterNext)
                    115:       {   // for
                    116:       if (pLine->pLineCounterNext == pLineRemove)
                    117:          {
                    118:          pLine->pLineCounterNext = pLineRemove->pLineCounterNext ;
                    119:          return (TRUE) ;
                    120:          }  // if
                    121:       }  // for
                    122: 
                    123:    return (FALSE) ;
                    124:    }  // LineCounterRemove
                    125: 
                    126: 
                    127: //======================================//
                    128: // Column Group routines                //
                    129: //======================================//
                    130: 
                    131: 
                    132: BOOL ColumnSame (PCOLUMNGROUP pColumnGroup,
                    133:                  LPTSTR lpszParentName,
                    134:                  LPTSTR lpszInstanceName)
                    135:    {  // ColumnSame
                    136:    BOOL           bParentSame ;
                    137:    BOOL           bInstanceSame ;
                    138: 
                    139:    bParentSame = (!lpszParentName && !pColumnGroup->lpszParentName) ||
                    140:                  strsame (lpszParentName, pColumnGroup->lpszParentName) ;
                    141:    bInstanceSame = (!lpszInstanceName && !pColumnGroup->lpszInstanceName) ||
                    142:                  strsame (lpszInstanceName, pColumnGroup->lpszInstanceName) ;
                    143: 
                    144:    return (bParentSame && bInstanceSame) ;                 
                    145:    }  // ColumnSame
                    146: 
                    147: 
                    148: PCOLUMNGROUP ColumnGroupCreate (PREPORT pReport,
                    149:                                 int xPos,
                    150:                                 LPTSTR lpszParentName,
                    151:                                 LPTSTR lpszInstanceName,
                    152:                                 int PreviousColumnNumber)
                    153:    {  // ColumnGroupCreate
                    154:    PCOLUMNGROUP   pColumnGroup ;
                    155:    HDC            hDC ;
                    156: 
                    157:    hDC = GetDC (pReport->hWnd) ;
                    158:    pColumnGroup = MemoryAllocate (sizeof (COLUMNGROUP)) ;
                    159: 
                    160:    if (pColumnGroup)
                    161:       {
                    162:       pColumnGroup->pColumnGroupNext = NULL ;
                    163:       pColumnGroup->lpszParentName = StringAllocate (lpszParentName) ;
                    164:       pColumnGroup->lpszInstanceName = StringAllocate (lpszInstanceName) ;
                    165:       pColumnGroup->ParentNameTextWidth = TextWidth (hDC, lpszParentName) ;
                    166:       pColumnGroup->InstanceNameTextWidth = TextWidth (hDC, lpszInstanceName) ;
                    167:       pColumnGroup->xPos = xPos ;
                    168:       pColumnGroup->ColumnNumber = PreviousColumnNumber + 1 ;
                    169:       pColumnGroup->xWidth = max (max (pColumnGroup->ParentNameTextWidth,
                    170:                                        pColumnGroup->InstanceNameTextWidth),
                    171:                                   pReport->xValueWidth) ;
                    172: 
                    173:       pReport->xWidth = max (pReport->xWidth,
                    174:                              RightHandMargin +
                    175:                              ValueMargin (pReport) + 
                    176:                              pColumnGroup->xPos + pColumnGroup->xWidth + 
                    177:                              xColumnMargin) ;
                    178:       }  // if
                    179: 
                    180:    ReleaseDC (pReport->hWnd, hDC) ;
                    181:    return (pColumnGroup) ;
                    182:    }  // ColumnGroupCreate
                    183: 
                    184: 
                    185: 
                    186: PCOLUMNGROUP ColumnGroup (PREPORT pReport,
                    187:                           POBJECTGROUP pObjectGroup,
                    188:                           PLINE pLine)
                    189: /*
                    190:    Effect:        Return a pointer to the appropriate column group from
                    191:                   within the groups of pObject. If the line is a counter
                    192:                   without instances, return NULL. Otherwise, determine
                    193:                   if the counter's parent/instance pair is already found
                    194:                   in an existing column and return a pointer to that column.
                    195: 
                    196:                   If a column with the appropriate parent/instance isn't
                    197:                   found, add a new column *at the end*, and return that
                    198:                   column.
                    199: 
                    200:    Note:          This function has multiple return points.
                    201: */
                    202:    {  // ColumnGroup
                    203:    PCOLUMNGROUP   pColumnGroup ;
                    204:    LPTSTR         lpszParentName ;
                    205:    LPTSTR         lpszInstanceName ;
                    206: 
                    207: 
                    208:    if (!LineInstanceName (pLine))
                    209:       return (NULL) ;
                    210: 
                    211: 
                    212:    lpszParentName = LineParentName (pLine) ;
                    213:    lpszInstanceName = LineInstanceName (pLine) ;
                    214:       
                    215:    if (!pObjectGroup->pColumnGroupFirst)
                    216:       {
                    217:       pObjectGroup->pColumnGroupFirst = 
                    218:          ColumnGroupCreate (pReport, 0, lpszParentName, lpszInstanceName, -1) ;
                    219:       return (pObjectGroup->pColumnGroupFirst) ;
                    220:       }
                    221: 
                    222:    for (pColumnGroup = pObjectGroup->pColumnGroupFirst ;
                    223:         pColumnGroup ;
                    224:         pColumnGroup = pColumnGroup->pColumnGroupNext)
                    225:       {  // for
                    226:       if (ColumnSame (pColumnGroup, lpszParentName, lpszInstanceName))
                    227:          return (pColumnGroup) ;
                    228: 
                    229:       else if (!pColumnGroup->pColumnGroupNext)
                    230:          {  // if
                    231:          pColumnGroup->pColumnGroupNext = 
                    232:             ColumnGroupCreate (pReport,
                    233:                                pColumnGroup->xPos + pColumnGroup->xWidth +
                    234:                                xColumnMargin,
                    235:                                lpszParentName,
                    236:                                lpszInstanceName,
                    237:                                pColumnGroup->ColumnNumber) ;
                    238:          return (pColumnGroup->pColumnGroupNext) ;
                    239:          }  // if
                    240:       }  // for
                    241: 
                    242:    return (NULL) ;
                    243:    }  // ColumnGroup
                    244: 
                    245: 
                    246: 
                    247: //======================================//
                    248: // Counter Group routines               //
                    249: //======================================//
                    250: 
                    251: 
                    252: PCOUNTERGROUP CounterGroupCreate (DWORD dwCounterIndex)
                    253:    {  // CounterGroupCreate
                    254:    PCOUNTERGROUP   pCounterGroup ;
                    255: 
                    256:    pCounterGroup = MemoryAllocate (sizeof (COUNTERGROUP)) ;
                    257: 
                    258:    if (pCounterGroup)
                    259:       {
                    260:       pCounterGroup->pCounterGroupNext = NULL ;
                    261:       pCounterGroup->pLineFirst = NULL ;
                    262:       pCounterGroup->dwCounterIndex = dwCounterIndex ;
                    263:       }  // if
                    264: 
                    265:    return (pCounterGroup) ;
                    266:    }  // CounterGroupCreate
                    267: 
                    268: 
                    269: PCOUNTERGROUP CounterGroup (POBJECTGROUP pObjectGroup,
                    270:                             DWORD dwCounterIndex,
                    271:                             BOOL *pbCounterGroupCreated) 
                    272:    {  // CounterGroup
                    273:    PCOUNTERGROUP   pCounterGroup ;
                    274: 
                    275:    *pbCounterGroupCreated = FALSE ;
                    276:    if (!pObjectGroup)
                    277:       return (FALSE) ;
                    278: 
                    279:    if (!pObjectGroup->pCounterGroupFirst)
                    280:       {
                    281:       pObjectGroup->pCounterGroupFirst = CounterGroupCreate (dwCounterIndex) ;
                    282:       *pbCounterGroupCreated = TRUE ;
                    283:       return (pObjectGroup->pCounterGroupFirst) ;
                    284:       }
                    285: 
                    286:    for (pCounterGroup = pObjectGroup->pCounterGroupFirst ;
                    287:         pCounterGroup ;
                    288:         pCounterGroup = pCounterGroup->pCounterGroupNext)
                    289:       {  // for
                    290:       if (pCounterGroup->dwCounterIndex == dwCounterIndex)
                    291:          return (pCounterGroup) ;
                    292:       else if (!pCounterGroup->pCounterGroupNext)
                    293:          {  // if
                    294:          pCounterGroup->pCounterGroupNext = 
                    295:             CounterGroupCreate (dwCounterIndex) ;
                    296:          *pbCounterGroupCreated = TRUE ;
                    297:          return (pCounterGroup->pCounterGroupNext) ;
                    298:          }  // if
                    299:       }  // for
                    300: 
                    301:    return (NULL) ;
                    302:    }  // CounterGroup
                    303: 
                    304: 
                    305: //======================================//
                    306: // Object Group routines                //
                    307: //======================================//
                    308: 
                    309: 
                    310: POBJECTGROUP ObjectGroupCreate (LPTSTR lpszObjectName)
                    311:    {  // ObjectGroupCreate
                    312:    POBJECTGROUP   pObjectGroup ;
                    313:    HDC            hDC ;
                    314:    PREPORT        pReport ;
                    315:    int            OldCounterWidth ;
                    316: 
                    317:    pObjectGroup = MemoryAllocate (sizeof (OBJECTGROUP)) ;
                    318: 
                    319:    if (pObjectGroup)
                    320:       {
                    321:       pObjectGroup->pObjectGroupNext = NULL ;
                    322:       pObjectGroup->pCounterGroupFirst = NULL ;
                    323:       pObjectGroup->pColumnGroupFirst = NULL ;
                    324:       pObjectGroup->lpszObjectName = StringAllocate (lpszObjectName) ;
                    325: 
                    326:       hDC = GetDC (hWndReport) ;
                    327:       pReport = ReportData (hWndReport) ;
                    328:       SelectFont (hDC, pReport->hFontHeaders) ;
                    329: 
                    330:       // re-calc. the max. counter group width
                    331:       OldCounterWidth = pReport->xMaxCounterWidth ;
                    332:       pReport->xMaxCounterWidth =
                    333:             max (pReport->xMaxCounterWidth,
                    334:                  TextWidth (hDC, lpszObjectName) + xObjectMargin) ;
                    335: 
                    336:       if (OldCounterWidth < pReport->xMaxCounterWidth)
                    337:           {
                    338:           // adjust the report width with the new counter width
                    339:           pReport->xWidth +=
                    340:                (pReport->xMaxCounterWidth - OldCounterWidth);
                    341:           }
                    342: 
                    343:       ReleaseDC (hWndReport, hDC) ;
                    344:       }  // if
                    345:    return (pObjectGroup) ;
                    346:    }  // ObjectGroupCreate
                    347: 
                    348: 
                    349: POBJECTGROUP ObjectGroup (PSYSTEMGROUP pSystemGroup,
                    350:                           LPTSTR lpszObjectName)
                    351:    {
                    352:    POBJECTGROUP   pObjectGroup ;
                    353: 
                    354:    if (!pSystemGroup)
                    355:       return (FALSE) ;
                    356: 
                    357:    if (!pSystemGroup->pObjectGroupFirst)
                    358:       {
                    359:       pSystemGroup->pObjectGroupFirst = ObjectGroupCreate (lpszObjectName) ;
                    360:       return (pSystemGroup->pObjectGroupFirst) ;
                    361:       }
                    362: 
                    363:    for (pObjectGroup = pSystemGroup->pObjectGroupFirst ;
                    364:         pObjectGroup ;
                    365:         pObjectGroup = pObjectGroup->pObjectGroupNext)
                    366:       {  // for
                    367:       if (strsame (pObjectGroup->lpszObjectName, lpszObjectName))
                    368:          {
                    369:          return (pObjectGroup) ;
                    370:          }
                    371:       else if (!pObjectGroup->pObjectGroupNext)
                    372:          {  // if
                    373:          pObjectGroup->pObjectGroupNext = 
                    374:             ObjectGroupCreate (lpszObjectName) ;
                    375:          return (pObjectGroup->pObjectGroupNext) ;
                    376:          }  // if
                    377:       }  // for
                    378: 
                    379:    }  // ObjectGroup
                    380: 
                    381:  
                    382: //======================================//
                    383: // System Group routines                //
                    384: //======================================//
                    385: 
                    386: 
                    387: PSYSTEMGROUP SystemGroupCreate (LPTSTR lpszSystemName)
                    388:    {  // SystemGroupCreate
                    389:    PSYSTEMGROUP   pSystemGroup ;
                    390: 
                    391:    pSystemGroup = MemoryAllocate (sizeof (SYSTEMGROUP)) ;
                    392: 
                    393:    if (pSystemGroup)
                    394:       {
                    395:       pSystemGroup->pSystemGroupNext = NULL ;
                    396:       pSystemGroup->pObjectGroupFirst = NULL ;
                    397:       pSystemGroup->lpszSystemName = StringAllocate (lpszSystemName) ;
                    398:       }  // if
                    399: 
                    400:    return (pSystemGroup) ;
                    401:    }  // SystemGroupCreate
                    402: 
                    403: 
                    404: PSYSTEMGROUP SystemGroup (PREPORT pReport,
                    405:                           LPTSTR lpszSystemName)
                    406: /*
                    407:    Effect;        Return a pointer to the system group of pReport with
                    408:                   a system name of lpszSystemName. If no system group
                    409:                   has that name, add a new system group.
                    410: */
                    411:    {  // SystemGroup
                    412:    PSYSTEMGROUP   pSystemGroup ;
                    413: 
                    414:    if (!pReport->pSystemGroupFirst)
                    415:       {
                    416:       pReport->pSystemGroupFirst = SystemGroupCreate (lpszSystemName) ;
                    417:       return (pReport->pSystemGroupFirst) ;
                    418:       }
                    419: 
                    420:    for (pSystemGroup = pReport->pSystemGroupFirst ;
                    421:         pSystemGroup ;
                    422:         pSystemGroup = pSystemGroup->pSystemGroupNext)
                    423:       {  // for
                    424:       if (strsamei (pSystemGroup->lpszSystemName, lpszSystemName))
                    425:          return (pSystemGroup) ;
                    426:       else if (!pSystemGroup->pSystemGroupNext)
                    427:          {  // if
                    428:          pSystemGroup->pSystemGroupNext = 
                    429:             SystemGroupCreate (lpszSystemName) ;
                    430:          return (pSystemGroup->pSystemGroupNext) ;
                    431:          }  // if
                    432:       }  // for
                    433:    }  // SystemGroup
                    434: 
                    435: 
                    436: 
                    437: void DrawCounter (HDC hDC, PREPORT pReport,
                    438:                   PCOUNTERGROUP pCounterGroup)
                    439:    {  // DrawCounter
                    440: 
                    441: 
                    442:    if (!pCounterGroup->pLineFirst)
                    443:       return ;
                    444: 
                    445:    SelectFont (hDC, pReport->hFont) ;
                    446:    TextOut (hDC, xCounterMargin, pCounterGroup->yLine,
                    447:             pCounterGroup->pLineFirst->lnCounterName,
                    448:             lstrlen (pCounterGroup->pLineFirst->lnCounterName)) ;
                    449:    }  // DrawCounter
                    450: 
                    451: 
                    452: void DrawObject (HDC hDC, PREPORT pReport,
                    453:                  POBJECTGROUP pObjectGroup)
                    454:    {  // DrawObject
                    455:    TCHAR          szLine [LongTextLen] ;
                    456:    PCOUNTERGROUP  pCounterGroup ;
                    457:    PCOLUMNGROUP   pColumnGroup ;
                    458: 
                    459:    if (!pObjectGroup->pCounterGroupFirst)
                    460:       {
                    461:       return ;
                    462:       }
                    463: 
                    464:    SelectFont (hDC, pReport->hFontHeaders) ;
                    465: 
                    466:    SetTextAlign (hDC, TA_RIGHT) ;
                    467: 
                    468:    for (pColumnGroup = pObjectGroup->pColumnGroupFirst ;
                    469:         pColumnGroup ;
                    470:         pColumnGroup = pColumnGroup->pColumnGroupNext)
                    471:       {  // for
                    472:       // Draw Parent
                    473:       if (pColumnGroup->lpszParentName)
                    474:          TextOut (hDC, 
                    475:                   ValueMargin (pReport) + 
                    476:                   pColumnGroup->xPos + pColumnGroup->xWidth,
                    477:                   pObjectGroup->yFirstLine - pReport->yLineHeight,
                    478:                   pColumnGroup->lpszParentName,
                    479:                   lstrlen (pColumnGroup->lpszParentName)) ;
                    480: 
                    481:       // Draw Instance
                    482:       if (pColumnGroup->lpszInstanceName)
                    483:          TextOut (hDC, 
                    484:                   ValueMargin (pReport) + 
                    485:                   pColumnGroup->xPos + pColumnGroup->xWidth,
                    486:                   pObjectGroup->yFirstLine,
                    487:                   pColumnGroup->lpszInstanceName,
                    488:                   lstrlen (pColumnGroup->lpszInstanceName)) ;
                    489:       }  // for
                    490:    SetTextAlign (hDC, TA_LEFT) ;
                    491: 
                    492:    TSPRINTF (szLine, szObjectFormat, pObjectGroup->lpszObjectName) ;
                    493:    TextOut (hDC, 
                    494:             xObjectMargin, pObjectGroup->yFirstLine,
                    495:             szLine, lstrlen (szLine)) ;
                    496: 
                    497:    SelectFont (hDC, pReport->hFont) ;
                    498: 
                    499:    for (pCounterGroup = pObjectGroup->pCounterGroupFirst ;
                    500:         pCounterGroup ;
                    501:         pCounterGroup = pCounterGroup->pCounterGroupNext)
                    502:       {  // for
                    503:       DrawCounter (hDC, pReport, pCounterGroup) ;
                    504:       }  // for
                    505: 
                    506:    }  // DrawObject
                    507: 
                    508: 
                    509: void DrawSystem (HDC hDC, PREPORT pReport, PSYSTEMGROUP pSystemGroup)
                    510:    {  // DrawSystem
                    511:    TCHAR          szLine [LongTextLen] ;
                    512:    POBJECTGROUP   pObjectGroup ;
                    513: 
                    514:    SelectFont (hDC, pReport->hFontHeaders) ;
                    515: 
                    516:    if (!pSystemGroup->pObjectGroupFirst)
                    517:       return ;
                    518: 
                    519:    SetTextAlign (hDC, TA_LEFT) ;
                    520:    TSPRINTF (szLine, szSystemFormat, pSystemGroup->lpszSystemName) ;
                    521:    TextOut (hDC, 
                    522:             xSystemMargin, pSystemGroup->yFirstLine,
                    523:             szLine, lstrlen (szLine)) ;
                    524: 
                    525:    for (pObjectGroup = pSystemGroup->pObjectGroupFirst ;
                    526:         pObjectGroup ;
                    527:         pObjectGroup = pObjectGroup->pObjectGroupNext)
                    528:       {  // for
                    529:       DrawObject (hDC, pReport, pObjectGroup) ;
                    530:       }  // for
                    531:    }  // DrawSystem
                    532: 
                    533: 
                    534: void ReportValueRect (PREPORT pReport,
                    535:                       PLINE pLine,
                    536:                       LPRECT lpRect)
                    537:    {  // ReportValueRect
                    538:    lpRect->left = ValueMargin (pReport) + pLine->xReportPos ;
                    539:    lpRect->top = pLine->yReportPos ;
                    540:    lpRect->right = lpRect->left + pReport->xValueWidth ;
                    541:    lpRect->bottom = lpRect->top + pReport->yLineHeight ;
                    542:    }  // ReportValueRect
                    543: 
                    544: 
                    545: void DrawReportValue (HDC hDC, PREPORT pReport, PLINE pLine)
                    546:    {  // DrawReportValue
                    547:    TCHAR          szValue [20] ;
                    548:    FLOAT          eValue ;
                    549:    RECT           rectValue ;
                    550: 
                    551:    // skip until we have collect enough samples for the first data
                    552:    if (pLine->bFirstTime == 0)
                    553:       {
                    554:       eValue = (*(pLine->valNext)) (pLine) ;
                    555:       TSPRINTF (szValue,
                    556:                 (eValue > eStatusLargeValueMax) ?
                    557:                     szLargeValueFormat : szValueFormat,
                    558:                 eValue) ;
                    559:       }
                    560:    else
                    561:       {
                    562:       // draw "- - - -"
                    563:       lstrcpy(szValue, TEXT("- - - -"));
                    564:       }
                    565: 
                    566:    ReportValueRect (pReport, pLine, &rectValue) ;
                    567:    
                    568:    ExtTextOut (hDC, 
                    569:                rectValue.right - 2, rectValue.top,
                    570:                ETO_CLIPPED | ETO_OPAQUE,
                    571:                &rectValue,
                    572:                szValue, lstrlen (szValue), NULL) ;
                    573: 
                    574:    if (pLine == pReport->pLineCurrent)
                    575:       {
                    576:       DrawFocusRect (hDC, &rectValue) ;
                    577:       }
                    578:    }  // DrawReportValue
                    579: 
                    580: 
                    581: void DrawReportValues (HDC hDC, PREPORT pReport)
                    582:    {
                    583:    PSYSTEMGROUP   pSystemGroup ;
                    584:    POBJECTGROUP   pObjectGroup ;
                    585:    PCOUNTERGROUP  pCounterGroup ;
                    586:    PLINE          pLine ;
                    587: 
                    588:    SelectFont (hDC, pReport->hFont) ;
                    589:    SetTextAlign (hDC, TA_RIGHT) ;
                    590: 
                    591:    for (pSystemGroup = pReport->pSystemGroupFirst ;
                    592:         pSystemGroup ;
                    593:         pSystemGroup = pSystemGroup->pSystemGroupNext)
                    594:       {  // for System...
                    595:       for (pObjectGroup = pSystemGroup->pObjectGroupFirst ;
                    596:            pObjectGroup ;
                    597:            pObjectGroup = pObjectGroup->pObjectGroupNext)
                    598:          {  // for Object...
                    599:          for (pCounterGroup = pObjectGroup->pCounterGroupFirst ;
                    600:               pCounterGroup ;
                    601:               pCounterGroup = pCounterGroup->pCounterGroupNext)
                    602:             {  // for Counter...
                    603:             for (pLine = pCounterGroup->pLineFirst ;
                    604:                  pLine ;
                    605:                  pLine = pLine->pLineCounterNext)
                    606:                {  // for Line...
                    607:                DrawReportValue (hDC, pReport, pLine) ;
                    608:                }  // for Line...
                    609:             }  // for Counter...
                    610:          }  // for Object      
                    611:       }  // for System...
                    612: 
                    613:    }
                    614: 
                    615: 
                    616: void DrawReportHeaders (HDC hDC, PREPORT pReport)
                    617:    {  // DrawReportHeaders
                    618:    PSYSTEMGROUP   pSystemGroup ;
                    619: 
                    620:    for (pSystemGroup = pReport->pSystemGroupFirst ;
                    621:         pSystemGroup ;
                    622:         pSystemGroup = pSystemGroup->pSystemGroupNext)
                    623:       {  // for
                    624:       DrawSystem (hDC, pReport, pSystemGroup) ;
                    625:       }  // for         
                    626:    }  // DrawReportHeaders
                    627: 
                    628: 
                    629: void DrawReport (HDC hDC, PREPORT pReport)
                    630:    {
                    631:    SetBkColor (hDC, GetSysColor(COLOR_WINDOW)) ;
                    632:    DrawReportHeaders (hDC, pReport) ;
                    633:    //UpdateLines (&(pReport->pSystemFirst), pReport->pLineFirst) ;
                    634:    DrawReportValues (hDC, pReport) ;
                    635:    }
                    636: 
                    637: 
                    638: 
                    639: void SetLinePosition (HDC hDC,
                    640:                       PREPORT pReport, 
                    641:                       POBJECTGROUP pObjectGroup,
                    642:                       PLINE pLine)
                    643:    {  // SetLinePositions
                    644:    PCOLUMNGROUP   pColumnGroup ;
                    645: 
                    646: 
                    647:    pColumnGroup = ColumnGroup (pReport, pObjectGroup, pLine) ;
                    648:    if (!pColumnGroup)
                    649:       {
                    650:       pLine->xReportPos = 0 ;
                    651:       pLine->iScaleIndex = -1 ;
                    652:       }
                    653:    else
                    654:       {
                    655:       pLine->xReportPos = pColumnGroup->xPos ;
                    656:       pLine->iScaleIndex = pColumnGroup->ColumnNumber ;
                    657:       }
                    658:    }  // SetLinePosition
                    659: 
                    660: 
                    661: void SetCounterPositions (HDC hDC,
                    662:                           PREPORT pReport,
                    663:                           POBJECTGROUP pObjectGroup,
                    664:                           PCOUNTERGROUP pCounterGroup,
                    665:                           int yLine)
                    666:    {  // SetCounterPositions
                    667:    PLINE          pLine ;
                    668:    int            yPos ;
                    669: 
                    670: 
                    671:    if (!pCounterGroup->pLineFirst)
                    672:       return ;
                    673: 
                    674:    yPos = pCounterGroup->yLine ;
                    675: 
                    676:    SelectFont (hDC, pReport->hFontHeaders) ;
                    677: 
                    678:    for (pLine = pCounterGroup->pLineFirst ;
                    679:         pLine ;
                    680:         pLine = pLine->pLineCounterNext)
                    681:       {  // for
                    682:       SetLinePosition (hDC, pReport, pObjectGroup, pLine) ;
                    683:       pLine->yReportPos = yPos ;
                    684:       }  // for
                    685:    }  // SetCounterPositions
                    686: 
                    687: 
                    688: void SetColumnPositions (HDC hDC,
                    689:                          PREPORT pReport,
                    690:                          POBJECTGROUP pObjectGroup)
                    691:    {  // SetColumnPositions
                    692:    int            xPos ;
                    693:    PCOLUMNGROUP   pColumnGroup ;
                    694: 
                    695:    xPos = 0 ;
                    696:    for (pColumnGroup = pObjectGroup->pColumnGroupFirst ;
                    697:         pColumnGroup ;
                    698:         pColumnGroup = pColumnGroup->pColumnGroupNext)
                    699:       {  // for
                    700:       pColumnGroup->xWidth = max (max (pColumnGroup->ParentNameTextWidth,
                    701:                                        pColumnGroup->InstanceNameTextWidth),
                    702:                                   pReport->xValueWidth) ;
                    703:       pColumnGroup->xPos = xPos ;
                    704:       xPos += (pColumnGroup->xWidth + xColumnMargin) ;
                    705:       }  // for
                    706:    }  // SetColumnPositions
                    707: 
                    708: 
                    709: void SetObjectPositions (HDC hDC,
                    710:                          PREPORT pReport,
                    711:                          POBJECTGROUP pObjectGroup,
                    712:                          int yLine)
                    713: /*
                    714:    Effect:        Determine and set the logical coordinates for the
                    715:                   object pObject within the report pReport.
                    716: 
                    717:                   For each instance x counter, determine the appropriate
                    718:                   column, adding a column description to the object if
                    719:                   needed.
                    720: 
                    721:    Called By:     SetSystemPositions only.
                    722: 
                    723:    See Also:      SetSystemPositions, SetCounterPositions, ColumnGroup.
                    724: */
                    725:    {  // SetObjectPositions
                    726:    PCOUNTERGROUP  pCounterGroup ;
                    727:    int            yPos ;
                    728: 
                    729:    yPos = pObjectGroup->yFirstLine + yLine ;
                    730: 
                    731:    SetColumnPositions (hDC, pReport, pObjectGroup) ;
                    732: 
                    733:    for (pCounterGroup = pObjectGroup->pCounterGroupFirst ;
                    734:         pCounterGroup ;
                    735:         pCounterGroup = pCounterGroup->pCounterGroupNext)
                    736:       {  // for
                    737:       pCounterGroup->yLine = yPos + yLine ;
                    738:    
                    739:       SetCounterPositions (hDC, pReport, pObjectGroup, pCounterGroup, yLine) ;
                    740: 
                    741:       yPos = pCounterGroup->yLine ;
                    742:       }  // for
                    743: 
                    744:    pObjectGroup->yLastLine = yPos + yLine ;
                    745:    }  // SetObjectPositions
                    746: 
                    747: 
                    748: void SetSystemPositions (HDC hDC,
                    749:                          PREPORT pReport, 
                    750:                          PSYSTEMGROUP pSystemGroup,
                    751:                          int yLine)
                    752:    {  // SetSystemPositions
                    753:    POBJECTGROUP  pObjectGroup ;
                    754:    int            yPos ;
                    755: 
                    756:    yPos = pSystemGroup->yFirstLine ;
                    757: 
                    758:    for (pObjectGroup = pSystemGroup->pObjectGroupFirst ;
                    759:         pObjectGroup ;
                    760:         pObjectGroup = pObjectGroup->pObjectGroupNext)
                    761:       {  // for
                    762:       pObjectGroup->yFirstLine = yPos + yLine ;
                    763:    
                    764:       SetObjectPositions (hDC, pReport, pObjectGroup, yLine) ;
                    765: 
                    766:       yPos = pObjectGroup->yLastLine ;
                    767:       }  // for
                    768: 
                    769:    pSystemGroup->yLastLine = yPos + yLine ;
                    770:    }  // SetSystemPositions
                    771: 
                    772: 
                    773: void static SetScrollRanges (HWND hWnd)
                    774:    {  // SetScrollRanges
                    775:    PREPORT        pReport ;
                    776:    RECT           rectClient ;
                    777:    int            xWidth, yHeight ;
                    778: 
                    779:    GetClientRect (hWnd, &rectClient) ;
                    780:    xWidth = rectClient.right - rectClient.left ;
                    781:    yHeight = rectClient.bottom - rectClient.top ;
                    782: 
                    783:    pReport = ReportData (hWnd) ;
                    784: 
                    785:    SetScrollRange (hWnd, SB_VERT, 
                    786:                    0, max (0, pReport->yHeight - yHeight), 
                    787:                    TRUE) ;
                    788:    SetScrollRange (hWnd, SB_HORZ,
                    789:                    0, max (0, pReport->xWidth - xWidth),
                    790:                    TRUE) ;
                    791:    }  // SetScrollRanges
                    792: 
                    793: 
                    794: BOOL SystemGroupRemove (PSYSTEMGROUP *ppSystemGroupFirst,
                    795:                         PSYSTEMGROUP pSystemGroupRemove)
                    796:    {
                    797:    PSYSTEMGROUP  pSystemGroup ;
                    798: 
                    799:    if (*ppSystemGroupFirst == pSystemGroupRemove)
                    800:       {
                    801:       *ppSystemGroupFirst = (*ppSystemGroupFirst)->pSystemGroupNext ;
                    802:       MemoryFree (pSystemGroupRemove->lpszSystemName) ;
                    803:       MemoryFree (pSystemGroupRemove) ;
                    804:       return (TRUE) ;
                    805:       }
                    806: 
                    807:    for (pSystemGroup = *ppSystemGroupFirst ;
                    808:         pSystemGroup->pSystemGroupNext ;
                    809:         pSystemGroup = pSystemGroup->pSystemGroupNext)
                    810:       {   // for
                    811:       if (pSystemGroup->pSystemGroupNext == pSystemGroupRemove)
                    812:          {
                    813:          pSystemGroup->pSystemGroupNext = pSystemGroupRemove->pSystemGroupNext ;
                    814:          MemoryFree (pSystemGroupRemove->lpszSystemName) ;
                    815:          MemoryFree (pSystemGroupRemove) ;
                    816:          return (TRUE) ;
                    817:          }  // if
                    818:       }  // for
                    819: 
                    820:    return (FALSE) ;
                    821:    }
                    822: 
                    823: void ColumnGroupRemove (PCOLUMNGROUP pColumnGroupFirst)
                    824:    {
                    825:    PCOLUMNGROUP   pColumnGroup ;
                    826:    PCOLUMNGROUP   pNextColumnGroup ;
                    827: 
                    828:    for (pColumnGroup = pColumnGroupFirst ;
                    829:         pColumnGroup ;
                    830:         pColumnGroup = pNextColumnGroup)
                    831:       {
                    832:       pNextColumnGroup = pColumnGroup->pColumnGroupNext ;
                    833: 
                    834:       // free memory for this column group
                    835:       MemoryFree (pColumnGroup->lpszParentName) ;
                    836:       MemoryFree (pColumnGroup->lpszInstanceName) ;
                    837:       MemoryFree (pColumnGroup) ;
                    838:       }
                    839:    }  // ColumnGroupRemove
                    840: 
                    841: BOOL ObjectGroupRemove (POBJECTGROUP *ppObjectGroupFirst,
                    842:                         POBJECTGROUP pObjectGroupRemove)
                    843:    {
                    844:    POBJECTGROUP  pObjectGroup ;
                    845: 
                    846:    if (*ppObjectGroupFirst == pObjectGroupRemove)
                    847:       {
                    848:       *ppObjectGroupFirst = (*ppObjectGroupFirst)->pObjectGroupNext ;
                    849: 
                    850:       // clean up the allocated memory
                    851:       ColumnGroupRemove (pObjectGroupRemove->pColumnGroupFirst) ;
                    852:       MemoryFree (pObjectGroupRemove->lpszObjectName) ;
                    853:       MemoryFree (pObjectGroupRemove) ;
                    854:       return (TRUE) ;
                    855:       }
                    856: 
                    857:    for (pObjectGroup = *ppObjectGroupFirst ;
                    858:         pObjectGroup->pObjectGroupNext ;
                    859:         pObjectGroup = pObjectGroup->pObjectGroupNext)
                    860:       {   // for
                    861:       if (pObjectGroup->pObjectGroupNext == pObjectGroupRemove)
                    862:          {
                    863:          pObjectGroup->pObjectGroupNext = pObjectGroupRemove->pObjectGroupNext ;
                    864: 
                    865:          // clean up the allocated memory
                    866:          ColumnGroupRemove (pObjectGroupRemove->pColumnGroupFirst) ;
                    867:          MemoryFree (pObjectGroupRemove->lpszObjectName) ;
                    868:          MemoryFree (pObjectGroupRemove) ;
                    869:          return (TRUE) ;
                    870:          }  // if
                    871:       }  // for
                    872: 
                    873:    return (FALSE) ;
                    874:    }
                    875: 
                    876: 
                    877: BOOL CounterGroupRemove (PCOUNTERGROUP *ppCounterGroupFirst,
                    878:                         PCOUNTERGROUP pCounterGroupRemove)
                    879:    {
                    880:    PCOUNTERGROUP  pCounterGroup ;
                    881: 
                    882:    if (*ppCounterGroupFirst == pCounterGroupRemove)
                    883:       {
                    884:       *ppCounterGroupFirst = (*ppCounterGroupFirst)->pCounterGroupNext ;
                    885:       MemoryFree (pCounterGroupRemove) ;
                    886:       return (TRUE) ;
                    887:       }
                    888: 
                    889:    for (pCounterGroup = *ppCounterGroupFirst ;
                    890:         pCounterGroup->pCounterGroupNext ;
                    891:         pCounterGroup = pCounterGroup->pCounterGroupNext)
                    892:       {   // for
                    893:       if (pCounterGroup->pCounterGroupNext == pCounterGroupRemove)
                    894:          {
                    895:          pCounterGroup->pCounterGroupNext = pCounterGroupRemove->pCounterGroupNext ;
                    896:          MemoryFree (pCounterGroupRemove) ;
                    897:          return (TRUE) ;
                    898:          }  // if
                    899:       }  // for
                    900: 
                    901:    return (FALSE) ;
                    902:    }
                    903:                         
                    904: 
                    905: //==========================================================================//
                    906: //                              Message Handlers                            //
                    907: //==========================================================================//
                    908: 
                    909: 
                    910: void static OnCreate (HWND hWnd)
                    911:    {  // OnCreate
                    912:    HDC            hDC ;
                    913:    PREPORT        pReport ;
                    914: 
                    915:    pReport = AllocateReportData (hWnd) ;
                    916:    if (!pReport)
                    917:       return ;
                    918: 
                    919:    pReport->hFont = hFontScales ;
                    920:    pReport->hFontHeaders = hFontScalesBold ;
                    921: 
                    922:    pReport->pLineFirst = NULL ;
                    923:    pReport->pSystemFirst = NULL ;
                    924: 
                    925:    pReport->pSystemGroupFirst = NULL ;
                    926: 
                    927:    hDC = GetDC (hWnd) ;
                    928: 
                    929:    SelectFont (hDC, pReport->hFont) ;
                    930: 
                    931: 
                    932:    pReport->yLineHeight = FontHeight (hDC, TRUE) ;
                    933:    pReport->xValueWidth = TextWidth (hDC, szValuePlaceholder) ;
                    934:    ReleaseDC (hWnd, hDC) ;
                    935: 
                    936:    pReport->xWidth = 0 ;
                    937:    pReport->yHeight = 0 ;
                    938: 
                    939:    StringLoad (IDS_SYSTEMFORMAT, szSystemFormat) ;
                    940:    StringLoad (IDS_OBJECTFORMAT, szObjectFormat) ;
                    941:    }  // OnCreate
                    942: 
                    943: 
                    944: void static OnPaint (HWND hWnd)
                    945:    {
                    946:    HDC            hDC ;
                    947:    PAINTSTRUCT    ps ;
                    948:    PREPORT        pReport ;
                    949: 
                    950: 
                    951: 
                    952:    pReport = ReportData (hWnd) ;
                    953: 
                    954:    hDC = BeginPaint (hWnd, &ps) ;
                    955:    //hDC = hReportDC ;
                    956:    SetWindowOrgEx (hDC, 
                    957:                    GetScrollPos (hWnd, SB_HORZ), 
                    958:                    GetScrollPos (hWnd, SB_VERT),
                    959:                    NULL) ;
                    960: 
                    961:    DrawReport (hDC, pReport) ;
                    962: 
                    963:    EndPaint (hWnd, &ps) ;
                    964:    }
                    965: 
                    966: 
                    967: void static UpdateReportValues (PREPORT pReport)
                    968: /*
                    969:    Effect:        Redraw all the visible report values of pReport.
                    970:                   Since drawing the values completely covers any 
                    971:                   previous values, there is no need to erase (or flicker)
                    972:                   between updating values.
                    973: 
                    974:    Called By:     ReportTimer, OnVScroll, OnHScroll.
                    975: */
                    976:    {  // UpdateReportValues
                    977:    HDC            hDC ;
                    978: 
                    979:    hDC = GetDC (pReport->hWnd) ;
                    980: 
                    981:    SetBkColor (hDC, GetSysColor(COLOR_WINDOW)) ;
                    982:    SetWindowOrgEx (hDC, 
                    983:                    GetScrollPos (pReport->hWnd, SB_HORZ), 
                    984:                    GetScrollPos (pReport->hWnd, SB_VERT),
                    985:                    NULL) ;
                    986: 
                    987:    DrawReportValues (hDC, pReport) ;
                    988:    ReleaseDC (pReport->hWnd, hDC) ;
                    989: 
                    990:    }  // UpdateReportValues
                    991: 
                    992: 
                    993: 
                    994: void static OnHScroll (HWND hWnd,
                    995:                        int iScrollCode,
                    996:                        int iScrollNewPos)
                    997:    {  // OnHScroll
                    998:    PREPORT        pReport ;
                    999:    int            iScrollAmt, iScrollPos, iScrollRange ;
                   1000:    int            iScrollLo ;
                   1001:    RECT           rectClient ;
                   1002: 
                   1003:    pReport = ReportData (hWnd) ;
                   1004: 
                   1005:    iScrollPos = GetScrollPos (hWnd, SB_HORZ) ;
                   1006:    GetScrollRange (hWnd, SB_HORZ, &iScrollLo, &iScrollRange) ;
                   1007: 
                   1008:    GetClientRect (hWnd, &rectClient) ;
                   1009: 
                   1010:    switch (iScrollCode)
                   1011:       {
                   1012:       case SB_LINEUP:
                   1013:            iScrollAmt = - Report.yLineHeight ;
                   1014:            break ;
                   1015: 
                   1016:       case SB_LINEDOWN:
                   1017:            iScrollAmt = Report.yLineHeight ;
                   1018:            break ;
                   1019: 
                   1020:       case SB_PAGEUP:
                   1021:            iScrollAmt = - (rectClient.right - rectClient.left) / 2 ;
                   1022:            break ;
                   1023: 
                   1024:       case SB_PAGEDOWN:
                   1025:            iScrollAmt = (rectClient.right - rectClient.left) / 2 ;
                   1026:            break ;
                   1027: 
                   1028:       case SB_THUMBPOSITION:
                   1029:            iScrollAmt = iScrollNewPos - iScrollPos ;
                   1030:            break ;
                   1031: 
                   1032:       default:
                   1033:            iScrollAmt = 0 ;
                   1034:       }  // switch
                   1035: 
                   1036:      iScrollAmt = PinInclusive (iScrollAmt,
                   1037:                                 -iScrollPos,
                   1038:                                 iScrollRange - iScrollPos) ;
                   1039:      if (iScrollAmt)
                   1040:         {
                   1041:         iScrollPos += iScrollAmt ;
                   1042:         ScrollWindow (hWnd, -iScrollAmt, 0, NULL, NULL) ;
                   1043:         SetScrollPos (hWnd, SB_HORZ, iScrollPos, TRUE) ;
                   1044:         UpdateWindow (hWnd) ;
                   1045: 
                   1046:         UpdateReportValues (pReport) ;        
                   1047:         }
                   1048:    }  // OnHScroll
                   1049: 
                   1050: 
                   1051: 
                   1052: void static OnVScroll (HWND hWnd,
                   1053:                        int iScrollCode,
                   1054:                        int iScrollNewPos)
                   1055:    {  // OnVScroll
                   1056:    PREPORT        pReport ;
                   1057:    int            iScrollAmt, iScrollPos, iScrollRange ;
                   1058:    int            iScrollLo ;
                   1059:    RECT           rectClient ;
                   1060: 
                   1061:    pReport = ReportData (hWnd) ;
                   1062: 
                   1063:    iScrollPos = GetScrollPos (hWnd, SB_VERT) ;
                   1064:    GetScrollRange (hWnd, SB_VERT, &iScrollLo, &iScrollRange) ;
                   1065: 
                   1066:    GetClientRect (hWnd, &rectClient) ;
                   1067: 
                   1068:    switch (iScrollCode)
                   1069:       {
                   1070:       case SB_LINEUP:
                   1071:            iScrollAmt = - Report.yLineHeight ;
                   1072:            break ;
                   1073: 
                   1074:       case SB_LINEDOWN:
                   1075:            iScrollAmt = Report.yLineHeight ;
                   1076:            break ;
                   1077: 
                   1078:       case SB_PAGEUP:
                   1079:            iScrollAmt = - (rectClient.bottom - rectClient.top) / 2 ;
                   1080:            break ;
                   1081: 
                   1082:       case SB_PAGEDOWN:
                   1083:            iScrollAmt = (rectClient.bottom - rectClient.top) / 2 ;
                   1084:            break ;
                   1085: 
                   1086:       case SB_THUMBPOSITION:
                   1087:            iScrollAmt = iScrollNewPos - iScrollPos ;
                   1088:            break ;
                   1089: 
                   1090:       default:
                   1091:            iScrollAmt = 0 ;
                   1092:       }  // switch
                   1093: 
                   1094:      iScrollAmt = PinInclusive (iScrollAmt,
                   1095:                                 -iScrollPos,
                   1096:                                 iScrollRange - iScrollPos) ;
                   1097:      if (iScrollAmt)
                   1098:         {
                   1099:         iScrollPos += iScrollAmt ;
                   1100:         ScrollWindow (hWnd, 0, -iScrollAmt, NULL, NULL) ;
                   1101:         SetScrollPos (hWnd, SB_VERT, iScrollPos, TRUE) ;
                   1102:         WindowInvalidate (hWnd) ;
                   1103:         UpdateWindow (hWnd) ;
                   1104: 
                   1105:         UpdateReportValues (pReport) ;        
                   1106:         }
                   1107:    }  // OnVScroll
                   1108: 
                   1109: 
                   1110: BOOL static OnLButtonDown (HWND hWnd, 
                   1111:                            WORD xPos,
                   1112:                            WORD yPos)
                   1113:    {
                   1114:    HDC         hDC ;
                   1115:    PREPORT     pReport ;
                   1116:    PLINE       pLine ;
                   1117:    PLINE       pLinePrevious ;
                   1118:    RECT        rect ;
                   1119:    POINT       pt ;
                   1120:    int         xOffset, yOffset ;
                   1121: 
                   1122: 
                   1123:    pReport = ReportData (hWnd) ;
                   1124:    if (!pReport)
                   1125:       return (FALSE) ;
                   1126: 
                   1127:    xOffset = GetScrollPos (hWnd, SB_HORZ) ;
                   1128:    yOffset = GetScrollPos (hWnd, SB_VERT) ;
                   1129:    pt.x = xPos + xOffset ;
                   1130:    pt.y = yPos + yOffset ;
                   1131: 
                   1132:    pLinePrevious = pReport->pLineCurrent ;
                   1133: 
                   1134:    for (pLine = pReport->pLineFirst ;
                   1135:         pLine ;
                   1136:         pLine = pLine->pLineNext)
                   1137:       {  // for
                   1138:       ReportValueRect (pReport, pLine, &rect) ;
                   1139:       if (PtInRect (&rect, pt))
                   1140:          {
                   1141:          if (pLine != pLinePrevious)
                   1142:             {
                   1143:             pReport->pLineCurrent = pLine ;
                   1144:             hDC = GetDC (hWnd) ;
                   1145:             SetWindowOrgEx (hDC, xOffset, yOffset, NULL) ;
                   1146:             SelectFont (hDC, pReport->hFont) ;
                   1147:             SetTextAlign (hDC, TA_RIGHT) ;
                   1148:             SetBkColor (hDC, GetSysColor(COLOR_WINDOW)) ;
                   1149:             DrawReportValue (hDC, pReport, pLine) ;
                   1150:             if (pLinePrevious)
                   1151:                DrawReportValue (hDC, pReport, pLinePrevious) ;
                   1152:             
                   1153:             ReleaseDC (hWnd, hDC) ;
                   1154:             return (TRUE) ;
                   1155:             }
                   1156:          return (FALSE) ;
                   1157:          }
                   1158:       }  // for
                   1159: 
                   1160:    return (FALSE) ;
                   1161:    }  // OnLButtonDown
                   1162:          
                   1163:          
                   1164: LRESULT APIENTRY ReportWndProc (HWND hWnd,
                   1165:                                WORD wMsg,
                   1166:                                DWORD wParam,
                   1167:                                LONG lParam)
                   1168:    {  // ReportWndProc
                   1169:    BOOL           bCallDefProc ;
                   1170:    LRESULT        lReturnValue ;
                   1171: 
                   1172:    bCallDefProc = FALSE ;
                   1173:    lReturnValue = 0L ;
                   1174: 
                   1175:    switch (wMsg)
                   1176:       {  // switch
                   1177:       case WM_CREATE:
                   1178:          OnCreate (hWnd) ;
                   1179:          break ;
                   1180: 
                   1181:       case WM_LBUTTONDOWN:
                   1182: 
                   1183:          if (!OnLButtonDown (hWnd, LOWORD (lParam), HIWORD (lParam)))
                   1184:             {
                   1185:             // mouse click do not hit on any entries, see if we 
                   1186:             // need to drag Perfmon
                   1187:             if (!(Options.bMenubar))
                   1188:                {
                   1189:                DoWindowDrag (lParam) ;
                   1190:                }
                   1191:             }
                   1192:          break ;
                   1193: 
                   1194:       case WM_LBUTTONDBLCLK:
                   1195:          SendMessage (hWndMain, WM_LBUTTONDBLCLK, wParam, lParam) ;
                   1196:          break ;
                   1197: 
                   1198:       case WM_PAINT:
                   1199:          OnPaint (hWnd) ;
                   1200:          break ;
                   1201: 
                   1202:       case WM_SIZE:
                   1203:          SetScrollRanges (hWnd) ;
                   1204:          break ;
                   1205: 
                   1206:       case WM_HSCROLL:
                   1207:          OnHScroll (hWnd, LOWORD (wParam), HIWORD (wParam)) ;
                   1208:          break ;
                   1209: 
                   1210:       case WM_VSCROLL:
                   1211:          OnVScroll (hWnd, LOWORD (wParam), HIWORD (wParam)) ;
                   1212:          break ;
                   1213: 
                   1214:       case WM_TIMER:
                   1215:          ReportTimer (hWnd, FALSE) ;
                   1216:          break ;
                   1217: 
                   1218:       case WM_DESTROY:
                   1219:          KillTimer (hWnd, ReportTimerID) ;
                   1220:          break ;
                   1221: 
                   1222:       default:
                   1223:          bCallDefProc = TRUE ;
                   1224:       }  // switch
                   1225: 
                   1226: 
                   1227:    if (bCallDefProc)
                   1228:       lReturnValue = DefWindowProc (hWnd, wMsg, wParam, lParam) ;
                   1229: 
                   1230:    return (lReturnValue);
                   1231:    }  // ReportWndProc
                   1232: 
                   1233: 
                   1234: 
                   1235: //==========================================================================//
                   1236: //                             Exported Functions                           //
                   1237: //==========================================================================//
                   1238: 
                   1239: #if 0
                   1240: PREPORT ReportData (HWND hWndReport)
                   1241:    {
                   1242:    return (&Report) ;
                   1243:    }
                   1244: #endif
                   1245: 
                   1246: void SetReportTimer (PREPORT pReport)
                   1247:    {  
                   1248:    if (pReport->iStatus == iPMStatusCollecting)
                   1249:       KillTimer (pReport->hWnd, ReportTimerID) ;
                   1250: 
                   1251:    SetTimer (pReport->hWnd, ReportTimerID, 
                   1252:              pReport->iIntervalMSecs , NULL) ;
                   1253:    pReport->iStatus = iPMStatusCollecting ;
                   1254:    }
                   1255: 
                   1256: 
                   1257: void ClearReportTimer (PREPORT pReport)
                   1258:    {
                   1259:    pReport->iStatus = iPMStatusClosed ;
                   1260:    KillTimer (pReport->hWnd, ReportTimerID) ;
                   1261:    }
                   1262: 
                   1263: 
                   1264: BOOL ReportInitializeApplication (void)
                   1265:    {  // ReportInitializeApplication
                   1266:    BOOL           bSuccess ;
                   1267:    WNDCLASS       wc ;
                   1268: 
                   1269:    //=============================//
                   1270:    // Register ReportWindow class  //
                   1271:    //=============================//
                   1272: 
                   1273: 
                   1274:    wc.style         = dwReportClassStyle ;
                   1275:    wc.lpfnWndProc   = (WNDPROC) ReportWndProc ;
                   1276:    wc.hInstance     = hInstance ;
                   1277:    wc.cbClsExtra    = iReportWindowExtra ;
                   1278:    wc.cbWndExtra    = iReportClassExtra ;
                   1279:    wc.hIcon         = NULL ;
                   1280:    wc.hCursor       = LoadCursor(NULL, IDC_ARROW) ;
                   1281: //   wc.hbrBackground = GetStockObject (WHITE_BRUSH) ;
                   1282:    wc.hbrBackground =   (HBRUSH) (COLOR_WINDOW + 1) ;
                   1283:    wc.lpszMenuName  = NULL ;
                   1284:    wc.lpszClassName = szReportWindowClass ;
                   1285: 
                   1286:    bSuccess = RegisterClass (&wc) ;
                   1287: 
                   1288: 
                   1289:    //=============================//
                   1290:    // Register Child classes      //
                   1291:    //=============================//
                   1292: 
                   1293:    return (bSuccess) ;
                   1294:    }  // ReportInitializeApplication
                   1295: 
                   1296: 
                   1297: 
                   1298: 
                   1299: BOOL ReportDeleteLine (HWND hWnd, PLINE pLine)
                   1300: /*
                   1301:    Effect:        Delete the line pLine into the data structures for the
                   1302:                   Report of window hWnd. The line is added to the list of
                   1303:                   lines, and also added to the report structure in the 
                   1304:                   appropriate System, Object, and Counter.
                   1305: 
                   1306:    Returns:       Whether the function was successful. If this function 
                   1307:                   returns FALSE, the line was not added.
                   1308: */
                   1309:    {  // ReportDeleteLine
                   1310:    HDC            hDC ;
                   1311:    PREPORT        pReport ;
                   1312:    PSYSTEMGROUP   pSystemGroup ;
                   1313:    POBJECTGROUP   pObjectGroup ;
                   1314:    PCOUNTERGROUP  pCounterGroup ;
                   1315:    BOOL           bCreatNewCounterGroup ;
                   1316: 
                   1317: 
                   1318:    pReport = ReportData (hWnd) ;
                   1319:    pReport->bModified = TRUE ;
                   1320: 
                   1321:    //=============================//
                   1322:    // Remove line, line's system  //
                   1323:    //=============================//
                   1324: 
                   1325:    LineRemove (&pReport->pLineFirst, pLine) ;
                   1326: 
                   1327:    // no more line, no more timer...
                   1328:    if (!pReport->pLineFirst)
                   1329:       {
                   1330:       pReport->xWidth = 0 ;
                   1331:       pReport->yHeight = 0 ;
                   1332:       pReport->xMaxCounterWidth = 0 ;
                   1333:       ClearReportTimer (pReport) ;
                   1334:       }
                   1335: 
                   1336: 
                   1337:    //=============================//
                   1338:    // Get correct spot; remove line //
                   1339:    //=============================//
                   1340: 
                   1341:    pSystemGroup = SystemGroup (pReport, pLine->lnSystemName) ;
                   1342:    pObjectGroup = ObjectGroup (pSystemGroup, pLine->lnObjectName) ;
                   1343:    pCounterGroup = CounterGroup (pObjectGroup, 
                   1344:                               pLine->lnCounterDef.CounterNameTitleIndex,
                   1345:                               &bCreatNewCounterGroup) ;
                   1346: 
                   1347:    if (!pCounterGroup)
                   1348:       return (FALSE) ;
                   1349: 
                   1350:    LineCounterRemove (&pCounterGroup->pLineFirst, pLine) ;
                   1351: 
                   1352:    if (!(pCounterGroup->pLineFirst))
                   1353:       CounterGroupRemove (&pObjectGroup->pCounterGroupFirst, pCounterGroup) ;
                   1354: 
                   1355:    if (!(pObjectGroup->pCounterGroupFirst))
                   1356:       ObjectGroupRemove (&pSystemGroup->pObjectGroupFirst, pObjectGroup) ;
                   1357: 
                   1358:    if (!(pSystemGroup->pObjectGroupFirst))
                   1359:       SystemGroupRemove (&pReport->pSystemGroupFirst, pSystemGroup) ;
                   1360: 
                   1361: 
                   1362:    LineFree (pLine) ;
                   1363:    pReport->pLineCurrent = pReport->pLineFirst ;
                   1364: 
                   1365:    if (pReport->pLineFirst)
                   1366:       {
                   1367:       BuildNewValueListForReport () ;
                   1368:       }
                   1369: 
                   1370:    //=============================//
                   1371:    // Calculate report positions  //
                   1372:    //=============================//
                   1373: 
                   1374:    hDC = GetDC (hWnd) ;
                   1375:    SetReportPositions (hDC, pReport) ;
                   1376:    ReleaseDC (hWnd, hDC) ;
                   1377: 
                   1378:    WindowInvalidate (hWnd) ;
                   1379:    }  // ReportDeleteLine
                   1380: 
                   1381: 
                   1382: HWND CreateReportWindow (HWND hWndParent)
                   1383: /*
                   1384:    Effect:        Create the graph window. This window is a child of 
                   1385:                   hWndMain and is a container for the graph data,
                   1386:                   graph label, graph legend, and graph status windows.
                   1387: 
                   1388:    Note:          We dont worry about the size here, as this window
                   1389:                   will be resized whenever the main window is resized.
                   1390: 
                   1391: */
                   1392:    {
                   1393:    return (CreateWindow (szReportWindowClass,       // window class
                   1394:                          NULL,                     // caption
                   1395:                          dwReportWindowStyle,       // style for window
                   1396:                          0, 0,                     // initial position
                   1397:                          0, 0,                     // initial size
                   1398:                          hWndParent,               // parent
                   1399:                          NULL,                     // menu
                   1400:                          hInstance,               // program instance
                   1401:                          NULL)) ;                  // user-supplied data                                              
                   1402:    }  // CreateReportWindow
                   1403: 
                   1404: 
                   1405: 
                   1406: 
                   1407: BOOL ReportInsertLine (HWND hWnd, PLINE pLine)
                   1408: /*
                   1409:    Effect:        Insert the line pLine into the data structures for the
                   1410:                   Report of window hWnd. The line is added to the list of
                   1411:                   lines, and also added to the report structure in the 
                   1412:                   appropriate System, Object, and Counter.
                   1413: 
                   1414:    Returns:       Whether the function was successful. If this function 
                   1415:                   returns FALSE, the line was not added.
                   1416: */
                   1417:    {  // ReportInsertLine
                   1418:    HDC            hDC ;
                   1419:    PREPORT        pReport ;
                   1420:    PSYSTEMGROUP   pSystemGroup ;
                   1421:    POBJECTGROUP   pObjectGroup ;
                   1422:    PCOUNTERGROUP  pCounterGroup ;
                   1423:    PLINE          pLineEquivalent ;
                   1424:    int            OldCounterWidth ;
                   1425:    BOOL           bNewCounterGroup ;
                   1426: 
                   1427:    pReport = ReportData (hWnd) ;
                   1428:    pReport->bModified = TRUE ;
                   1429: 
                   1430:    pLineEquivalent = FindEquivalentLine (pLine, pReport->pLineFirst) ;
                   1431:    if (pLineEquivalent) 
                   1432:       {
                   1433:       return (FALSE) ; 
                   1434:       }
                   1435:    else
                   1436:       {
                   1437:       //=============================//
                   1438:       // Add line, line's system     //
                   1439:       //=============================//
                   1440: 
                   1441:       LineAppend (&pReport->pLineFirst, pLine) ;
                   1442:       SystemAdd (&pReport->pSystemFirst, pLine->lnSystemName) ;
                   1443: 
                   1444: 
                   1445:       //=============================//
                   1446:       // Find correct spot; add line //
                   1447:       //=============================//
                   1448: 
                   1449:       pSystemGroup = SystemGroup (pReport, pLine->lnSystemName) ;
                   1450:       pObjectGroup = ObjectGroup (pSystemGroup, pLine->lnObjectName) ;
                   1451:       pCounterGroup = CounterGroup (pObjectGroup, 
                   1452:                                  pLine->lnCounterDef.CounterNameTitleIndex,
                   1453:                                  &bNewCounterGroup) ;
                   1454: 
                   1455:       if (!pCounterGroup)
                   1456:          return (FALSE) ;
                   1457: 
                   1458:       LineCounterAppend (&pCounterGroup->pLineFirst, pLine) ;
                   1459:    
                   1460:       //=============================//
                   1461:       // Calculate report positions  //
                   1462:       //=============================//
                   1463:       hDC = GetDC (hWnd) ;
                   1464:       SelectFont (hDC, pReport->hFontHeaders) ;
                   1465: 
                   1466:       if (bNewCounterGroup)
                   1467:          {
                   1468:          // re-calc. the max. counter group width 
                   1469:          OldCounterWidth = pReport->xMaxCounterWidth ;
                   1470:          pReport->xMaxCounterWidth = 
                   1471:             max (pReport->xMaxCounterWidth,
                   1472:                  TextWidth (hDC, pLine->lnCounterName)) ;
                   1473:          if (OldCounterWidth < pReport->xMaxCounterWidth)
                   1474:             {
                   1475:             // adjust the report width with the new counter width
                   1476:             pReport->xWidth +=
                   1477:                (pReport->xMaxCounterWidth - OldCounterWidth);
                   1478:             }
                   1479:          }
                   1480: 
                   1481:       if (!bDelayAddAction)
                   1482:          {
                   1483:          SetReportPositions (hDC, pReport) ;
                   1484:          }
                   1485:       ReleaseDC (hWnd, hDC) ;
                   1486: 
                   1487:       pReport->pLineCurrent = pLine ;
                   1488:       
                   1489:       if (!bDelayAddAction)
                   1490:          {
                   1491:          if (PlayingBackLog ())
                   1492:             {
                   1493:             PlaybackReport (hWndReport) ;
                   1494:             }
                   1495:          else if (pReport->iStatus == iPMStatusClosed)
                   1496:             {
                   1497:             SetReportTimer (pReport) ;
                   1498:             }
                   1499:          
                   1500:          WindowInvalidate (hWnd) ;
                   1501:          }
                   1502:       }  // else
                   1503: 
                   1504:       return (TRUE) ;
                   1505:    }  // ReportInsertLine
                   1506: 
                   1507: 
                   1508: 
                   1509: void SetReportPositions (HDC hDC,
                   1510:                          PREPORT pReport)
                   1511:    {
                   1512:    PSYSTEMGROUP   pSystemGroup ;
                   1513:    int            yLine ;
                   1514:    int            yPos ;
                   1515: 
                   1516:   
                   1517: //   pReport->xMaxCounterWidth = 0 ;
                   1518: 
                   1519:    yLine = pReport->yLineHeight ;
                   1520:    yPos = 2 * yLine ;
                   1521: 
                   1522:    for (pSystemGroup = pReport->pSystemGroupFirst ;
                   1523:         pSystemGroup ;
                   1524:         pSystemGroup = pSystemGroup->pSystemGroupNext)
                   1525:       {  // for
                   1526:       pSystemGroup->yFirstLine = yPos + yLine ;
                   1527: 
                   1528:       SetSystemPositions (hDC, pReport, pSystemGroup, yLine) ;
                   1529: 
                   1530:       yPos = pSystemGroup->yLastLine ;
                   1531:       }  // for 
                   1532: 
                   1533:    pReport->yHeight = yPos ;
                   1534: 
                   1535:    SetScrollRanges (pReport->hWnd) ;
                   1536:    }  // SetReportPositions
                   1537: 
                   1538: 
                   1539: 
                   1540: void PlaybackReport (HWND hWndReport)
                   1541:    {  // PlaybackReport
                   1542:    PREPORT        pReport ;
                   1543: 
                   1544:    pReport = ReportData (hWndReport) ;
                   1545: 
                   1546:    PlaybackLines (pReport->pSystemFirst, 
                   1547:                   pReport->pLineFirst, 
                   1548:                   PlaybackLog.StartIndexPos.iPosition) ;
                   1549:    PlaybackLines (pReport->pSystemFirst, 
                   1550:                   pReport->pLineFirst, 
                   1551:                   PlaybackLog.StopIndexPos.iPosition) ;
                   1552:    }  // PlaybackReport
                   1553: 
                   1554: 
                   1555: PLINESTRUCT CurrentReportLine (HWND hWndReport)
                   1556:    {  // CurrentReportLine
                   1557:    PREPORT        pReport ;
                   1558: 
                   1559:    pReport = ReportData (hWndReport) ;
                   1560:    if (!pReport)
                   1561:       return (NULL) ;
                   1562: 
                   1563:    return (pReport->pLineCurrent) ;
                   1564:    }  // CurrentReportLine
                   1565: 
                   1566: 
                   1567: 
                   1568: BOOL AddReport (HWND hWndParent)
                   1569:    {
                   1570:    PREPORT        pReport ;
                   1571: 
                   1572:    pReport = ReportData (hWndReport) ;
                   1573: 
                   1574:    return (AddLine (hWndParent, 
                   1575:                     &(pReport->pSystemFirst), 
                   1576:                     &(pReport->Visual), 
                   1577:                     LineTypeReport)) ;
                   1578:    }
                   1579: 
                   1580: 
                   1581: 
                   1582: BOOL EditReport (HWND hWndParent)
                   1583:    {  // EditReport
                   1584:    PREPORT        pReport ;
                   1585: 
                   1586:    pReport = ReportData (hWndReport) ;
                   1587: 
                   1588:    return (EditLine (hWndParent, 
                   1589:                      &(pReport->pSystemFirst), 
                   1590:                      CurrentReportLine (hWndReport),
                   1591:                      LineTypeReport)) ;
                   1592:    }  // EditReport
                   1593: 
                   1594: 
                   1595: BOOL ToggleReportRefresh (HWND hWnd)
                   1596:    {  // ToggleReportRefresh
                   1597:    PREPORT        pReport ;
                   1598: 
                   1599:    pReport = ReportData (hWnd) ;
                   1600: 
                   1601:    if (pReport->bManualRefresh)
                   1602:       SetReportTimer (pReport) ;
                   1603:    else
                   1604:       ClearReportTimer (pReport) ;
                   1605: 
                   1606:    pReport->bManualRefresh = !pReport->bManualRefresh ;
                   1607:    return (pReport->bManualRefresh) ;
                   1608:    }  // ToggleReportRefresh
                   1609: 
                   1610: BOOL ReportRefresh (HWND hWnd)
                   1611:    {  // ReportRefresh
                   1612:    PREPORT        pReport ;
                   1613: 
                   1614:    pReport = ReportData (hWnd) ;
                   1615: 
                   1616:    return (pReport->bManualRefresh) ;
                   1617:    }  // ReportRefresh
                   1618: 
                   1619: 
                   1620: 
                   1621: void ReportTimer (HWND hWnd, BOOL bForce)
                   1622:    {
                   1623:    PREPORT        pReport ;
                   1624: 
                   1625:    pReport = ReportData (hWnd) ;
                   1626: 
                   1627:    if (PlayingBackLog () || !pReport)
                   1628:       {
                   1629:       return;
                   1630:       }
                   1631: 
                   1632:    if (bForce || !pReport->bManualRefresh)
                   1633:       {  // if
                   1634:       UpdateLines (&(pReport->pSystemFirst), pReport->pLineFirst) ;
                   1635:       if (iPerfmonView == IDM_VIEWREPORT && !bPerfmonIconic)
                   1636:          {
                   1637:          // only need to draw the data when we are viewing it...
                   1638:          UpdateReportValues (pReport) ;
                   1639:          }
                   1640:       }  // if
                   1641:    }  // ReportTimer
                   1642: 
                   1643: 
                   1644: 
                   1645: 
                   1646: 
                   1647: 
                   1648: BOOL SaveReport (HWND hWndReport, HANDLE hInputFile, BOOL bGetFileName)
                   1649:    {
                   1650:    PREPORT        pReport ;
                   1651:    PLINE          pLine ;
                   1652:    HANDLE         hFile ;
                   1653:    DISKREPORT     DiskReport ;
                   1654:    PERFFILEHEADER FileHeader ;
                   1655:    TCHAR          szFileName [256] ;
                   1656:    BOOL           newFileName = FALSE ;
                   1657: 
                   1658:    pReport = ReportData (hWndReport) ;
                   1659:    if (!pReport)
                   1660:       {
                   1661:       return (FALSE) ;
                   1662:       }
                   1663: 
                   1664:    if (hInputFile)
                   1665:       {
                   1666:       // use the input file handle if it is available
                   1667:       // this is the case for saving workspace data
                   1668:       hFile = hInputFile ;
                   1669:       }
                   1670:    else
                   1671:       {
                   1672:       if (pReportFullFileName)
                   1673:          {
                   1674:          lstrcpy (szFileName, pReportFullFileName) ;
                   1675:          }
                   1676:       if (bGetFileName || pReportFullFileName == NULL)
                   1677:          {
                   1678: //         if (pReportFullFileName == NULL)
                   1679: //            {
                   1680: //            StringLoad (IDS_REPORT_FNAME, szFileName) ;
                   1681: //            }
                   1682:          if (!FileGetName (hWndReport, IDS_REPORTFILE, szFileName))
                   1683:             {
                   1684:             return (FALSE) ;
                   1685:             }
                   1686:          newFileName = TRUE ;
                   1687:          }
                   1688: 
                   1689:       hFile = FileHandleCreate (szFileName) ;
                   1690: 
                   1691:       if (hFile && newFileName)
                   1692:          {
                   1693:          ChangeSaveFileName (szFileName, IDM_VIEWREPORT) ;
                   1694:          }
                   1695:       else if (!hFile)
                   1696:          {
                   1697:          DlgErrorBox (hWndReport, ERR_CANT_OPEN, szFileName) ;
                   1698:          }
                   1699:       }
                   1700: 
                   1701: 
                   1702:    if (!hFile)
                   1703:       return (FALSE) ;
                   1704: 
                   1705: 
                   1706:    if (!hInputFile)
                   1707:       {
                   1708:       memset (&FileHeader, 0, sizeof (FileHeader)) ;
                   1709:       lstrcpy (FileHeader.szSignature, szPerfReportSignature) ;
                   1710:       FileHeader.dwMajorVersion = ReportMajorVersion ;
                   1711:       FileHeader.dwMinorVersion = ReportMinorVersion ;
                   1712:    
                   1713:       if (!FileWrite (hFile, &FileHeader, sizeof (PERFFILEHEADER)))
                   1714:          {
                   1715:          goto Exit0 ;
                   1716:          }
                   1717:       }
                   1718: 
                   1719:    DiskReport.Visual = pReport->Visual ;
                   1720:    DiskReport.bManualRefresh = pReport->bManualRefresh ;
                   1721:    DiskReport.dwIntervalSecs = pReport->iIntervalMSecs ;
                   1722:    DiskReport.dwNumLines = NumLines (pReport->pLineFirst) ;
                   1723:    DiskReport.perfmonOptions = Options ;
                   1724: 
                   1725:    if (!FileWrite (hFile, &DiskReport, sizeof (DISKREPORT)))
                   1726:       {
                   1727:       goto Exit0 ;
                   1728:       }
                   1729: 
                   1730:    for (pLine = pReport->pLineFirst ;
                   1731:         pLine ;
                   1732:         pLine = pLine->pLineNext)
                   1733:       {  // for
                   1734:       if (!WriteLine (pLine, hFile))
                   1735:          {
                   1736:          goto Exit0 ;
                   1737:          }
                   1738:       }  // for
                   1739: 
                   1740:    if (!hInputFile)
                   1741:       {
                   1742:       CloseHandle (hFile) ;
                   1743:       }
                   1744: 
                   1745:    return (TRUE) ;
                   1746: 
                   1747: Exit0:
                   1748:    if (!hInputFile)
                   1749:       {
                   1750:       CloseHandle (hFile) ;
                   1751: 
                   1752:       // only need to report error if not workspace 
                   1753:       DlgErrorBox (hWndReport, ERR_SETTING_FILE, szFileName) ;
                   1754:       }
                   1755:    return (FALSE) ;
                   1756:    }  // SaveReport  
                   1757: 
                   1758: 
                   1759: void ReportAddAction (PREPORT pReport)
                   1760:    {
                   1761:    HDC      hDC ;
                   1762: 
                   1763:    //=============================//
                   1764:    // Calculate report positions  //
                   1765:    //=============================//
                   1766: 
                   1767:    hDC = GetDC (hWndReport) ;
                   1768:    SetReportPositions (hDC, pReport) ;
                   1769:    ReleaseDC (hWndReport, hDC) ;
                   1770:    
                   1771:    if (PlayingBackLog ())
                   1772:       {
                   1773:       PlaybackReport (hWndReport) ;
                   1774:       }
                   1775:    else if (pReport->iStatus == iPMStatusClosed)
                   1776:       {
                   1777:       SetReportTimer (pReport) ;
                   1778:       }
                   1779: 
                   1780:    WindowInvalidate (hWndReport) ;
                   1781:    }
                   1782: 
                   1783: 
                   1784: BOOL OpenReportVer1 (HANDLE hFile,
                   1785:                      DISKREPORT *pDiskReport,
                   1786:                      PREPORT pReport,
                   1787:                      DWORD dwMinorVersion)
                   1788:    {
                   1789:    HDC   hDC ;
                   1790: 
                   1791:    pReport->Visual = pDiskReport->Visual ;
                   1792:    pReport->iIntervalMSecs = pDiskReport->dwIntervalSecs ;
                   1793:    if (dwMinorVersion < 3)
                   1794:       {
                   1795:       // convert this to msec
                   1796:       pReport->iIntervalMSecs *= 1000 ;
                   1797:       }
                   1798:    pReport->bManualRefresh = pDiskReport->bManualRefresh ;
                   1799: 
                   1800:    bDelayAddAction = TRUE ;
                   1801:    ReadLines (hFile, pDiskReport->dwNumLines,
                   1802:              &(pReport->pSystemFirst), &(pReport->pLineFirst), IDM_VIEWREPORT) ;
                   1803:    bDelayAddAction = FALSE ;
                   1804: 
                   1805:    //=============================//
                   1806:    // Calculate report positions  //
                   1807:    //=============================//
                   1808: 
                   1809:    hDC = GetDC (hWndReport) ;
                   1810:    SetReportPositions (hDC, pReport) ;
                   1811:    ReleaseDC (hWndReport, hDC) ;
                   1812: 
                   1813:    if (PlayingBackLog ())
                   1814: 
                   1815:       {
                   1816:       PlaybackReport (hWndReport) ;
                   1817:       }
                   1818:    else if (pReport->iStatus == iPMStatusClosed)
                   1819:       {
                   1820:       SetReportTimer (pReport) ;
                   1821:       }
                   1822: 
                   1823:    WindowInvalidate (hWndReport) ;
                   1824: 
                   1825:    return (TRUE) ;
                   1826:    }  // OpenReportVer1
                   1827: 
                   1828: 
                   1829: 
                   1830: BOOL OpenReport (HWND hWndReport, 
                   1831:                  HANDLE hFile, 
                   1832:                  DWORD dwMajorVersion,
                   1833:                  DWORD dwMinorVersion,
                   1834:                  BOOL bReportFile)
                   1835:    {
                   1836:    PREPORT        pReport ;
                   1837:    DISKREPORT     DiskReport ;
                   1838:    BOOL           bSuccess = TRUE ;
                   1839: 
                   1840:    pReport = ReportData (hWndReport) ;
                   1841:    if (!pReport)
                   1842:       {
                   1843:       bSuccess = FALSE ;
                   1844:       goto Exit0 ;
                   1845:       }
                   1846: 
                   1847:    if (!FileRead (hFile, &DiskReport, sizeof (DISKREPORT)))
                   1848:       {
                   1849:       bSuccess = FALSE ;
                   1850:       goto Exit0 ;
                   1851:       }
                   1852: 
                   1853: 
                   1854:    switch (dwMajorVersion)
                   1855:       {
                   1856:       case (1):
                   1857:          
                   1858:          SetHourglassCursor() ;
                   1859:      
                   1860:          ResetReportView (hWndReport) ;
                   1861: 
                   1862:          OpenReportVer1 (hFile, &DiskReport, pReport, dwMinorVersion) ;
                   1863: 
                   1864:          // change to report view if we are opening a 
                   1865:          // report file
                   1866:          if (bReportFile && iPerfmonView != IDM_VIEWREPORT)
                   1867:             {
                   1868:             SendMessage (hWndMain, WM_COMMAND, (LONG)IDM_VIEWREPORT, 0L) ;
                   1869:             }
                   1870: 
                   1871:          if (iPerfmonView == IDM_VIEWREPORT)
                   1872:             {
                   1873:             SetPerfmonOptions (&DiskReport.perfmonOptions) ;
                   1874:             }
                   1875: 
                   1876:          SetArrowCursor() ;
                   1877: 
                   1878:          break ;
                   1879:       }  // switch
                   1880: 
                   1881: Exit0:
                   1882:       
                   1883:    if (bReportFile)
                   1884:       {
                   1885:       CloseHandle (hFile) ;
                   1886:       }
                   1887: 
                   1888:    return (bSuccess) ;
                   1889:    }  // OpenReport
                   1890:    
                   1891: 
                   1892: 
                   1893: BOOL QuerySaveReport (HWND hWndParent, 
                   1894:                       HWND hWndReport)
                   1895:    {  // QuerySaveReport
                   1896: #ifdef KEEP_QUERY
                   1897:    PREPORT        pReport ;
                   1898:    int            iReturn ;
                   1899: 
                   1900:    pReport = ReportData (hWndReport) ;
                   1901:    if (!pReport)
                   1902:       return (TRUE) ;
                   1903: 
                   1904:    if (!pReport->bModified)
                   1905:       return (TRUE) ;
                   1906: 
                   1907:    iReturn = MessageBoxResource (hWndParent, 
                   1908:                                  IDS_SAVEREPORT, IDS_MODIFIEDREPORT,
                   1909:                                  MB_YESNOCANCEL | MB_ICONASTERISK) ;
                   1910: 
                   1911:    if (iReturn == IDCANCEL)
                   1912:       return (FALSE) ;
                   1913: 
                   1914:    if (iReturn == IDYES)
                   1915:       SaveReport (hWndReport) ;
                   1916: #endif
                   1917: 
                   1918:    return (TRUE) ;
                   1919:    }  // QuerySaveReport
                   1920: 
                   1921: void ResetReportView (HWND hWndReport)
                   1922:    {  // ResetReportView
                   1923:    PREPORT        pReport ;
                   1924: 
                   1925:    pReport = ReportData (hWndReport) ;
                   1926:    
                   1927:    if (!pReport)
                   1928:       {
                   1929:       return ;
                   1930:       }
                   1931:    
                   1932:    ChangeSaveFileName (NULL, IDM_VIEWREPORT) ;
                   1933: 
                   1934:    if (pReport->pSystemGroupFirst)
                   1935:       {
                   1936:       ResetReport (hWndReport) ;
                   1937:       }
                   1938:    }  // ResetReportView
                   1939: 
                   1940: 
                   1941: void ResetReport (HWND hWndReport)
                   1942:    {  // ResetReport
                   1943:    PREPORT        pReport ;
                   1944:    PSYSTEMGROUP   pSystemGroup, pSystemGroupDelete ;
                   1945:    POBJECTGROUP   pObjectGroup, pObjectGroupDelete ;
                   1946:    PCOUNTERGROUP  pCounterGroup, pCounterGroupDelete ;
                   1947:    HDC            hDC ;
                   1948: 
                   1949:    pReport = ReportData (hWndReport) ;
                   1950:    if (!pReport)
                   1951:       return ;
                   1952: 
                   1953:    ClearReportTimer (pReport) ;
                   1954: 
                   1955:    pSystemGroup = pReport->pSystemGroupFirst ;
                   1956:    while (pSystemGroup)
                   1957:       { 
                   1958:       pObjectGroup = pSystemGroup->pObjectGroupFirst ;
                   1959:       while (pObjectGroup)
                   1960:          {
                   1961:          pCounterGroup = pObjectGroup->pCounterGroupFirst ;
                   1962:          while (pCounterGroup)
                   1963:             {
                   1964:             pCounterGroupDelete = pCounterGroup ;
                   1965:             pCounterGroup = pCounterGroup->pCounterGroupNext ;
                   1966:             MemoryFree (pCounterGroupDelete) ;
                   1967:             }  // while pCounter...
                   1968:          
                   1969:          pObjectGroupDelete = pObjectGroup ;
                   1970:          pObjectGroup = pObjectGroup->pObjectGroupNext ;
                   1971:          ColumnGroupRemove (pObjectGroupDelete->pColumnGroupFirst) ;
                   1972:          MemoryFree (pObjectGroupDelete->lpszObjectName) ;
                   1973:          MemoryFree (pObjectGroupDelete) ;
                   1974:          }  // while pObject
                   1975: 
                   1976:       pSystemGroupDelete = pSystemGroup ;
                   1977:       pSystemGroup = pSystemGroup->pSystemGroupNext ;
                   1978:       MemoryFree (pSystemGroupDelete->lpszSystemName) ;
                   1979:       MemoryFree (pSystemGroupDelete) ;
                   1980:       }  // while pSystem...
                   1981: 
                   1982:    FreeLines (pReport->pLineFirst) ;
                   1983:    pReport->pLineFirst = NULL ;
                   1984: 
                   1985:    FreeSystems (pReport->pSystemFirst) ;
                   1986:    pReport->pSystemFirst = NULL ;
                   1987: 
                   1988:    pReport->pSystemGroupFirst = NULL ;
                   1989:    pReport->pLineCurrent = NULL ;
                   1990: 
                   1991:    // reset scrolling ranges
                   1992:    pReport->xWidth = 0 ;
                   1993:    pReport->yHeight = 0 ;
                   1994:    pReport->xMaxCounterWidth = 0 ;
                   1995:    hDC = GetDC (hWndReport) ;
                   1996:    SetReportPositions (hDC, pReport) ;
                   1997:    ReleaseDC (hWndReport, hDC) ;
                   1998: 
                   1999:    WindowInvalidate (hWndReport) ;
                   2000:    }  // ResetReport
                   2001:    
                   2002: void ClearReportDisplay (HWND hWndReport)
                   2003:    {  // ResetReport
                   2004:    PREPORT        pReport ;
                   2005:    PLINE          pLine;
                   2006: 
                   2007:    if (PlayingBackLog())
                   2008:       {
                   2009:       return ;
                   2010:       }
                   2011: 
                   2012:    pReport = ReportData (hWndReport) ;
                   2013:    if (!pReport || !pReport->pLineFirst)
                   2014:       return ;
                   2015: 
                   2016:    for (pLine = pReport->pLineFirst ;
                   2017:         pLine ;
                   2018:         pLine = pLine->pLineNext)
                   2019:       {
                   2020:       // reset the new data counts
                   2021:       pLine->bFirstTime = 2 ;
                   2022:       }
                   2023: 
                   2024:    // re-draw the values
                   2025:    UpdateReportValues (pReport) ;
                   2026: 
                   2027:    }  // ClearReportDisplay
                   2028:  
                   2029: //=========================================
                   2030: // we don't print. we just export
                   2031: //
                   2032: // if need printint, define KEEP_PRINT
                   2033: //=========================================
                   2034: #ifdef KEEP_PRINT
                   2035: BOOL PrintReportDisplay (HDC hDC,
                   2036:                          PREPORT pReport)
                   2037:    {
                   2038:    SetReportPositions (hDC, pReport) ;
                   2039:    DrawReport (hDC, pReport) ;
                   2040:    return TRUE ;
                   2041:    }  // PrintReportDisplay
                   2042: 
                   2043: 
                   2044: 
                   2045: BOOL PrintReport (HWND hWndParent,
                   2046:                   HWND hWndReport)
                   2047:    {
                   2048:    PREPORT        pReport ;
                   2049:    HDC            hDC ;
                   2050:    int            xPageWidth ;
                   2051:    int            yPageHeight ;
                   2052:    int            xValueWidth ;
                   2053: 
                   2054:    HFONT          hFont, hFontHeaders ;
                   2055:    int            yLineHeight ;
                   2056: 
                   2057:    pReport = ReportData (hWndReport) ;
                   2058:    if (!pReport)
                   2059:       return (FALSE) ;
                   2060: 
                   2061:    hDC = PrintDC () ;
                   2062:    if (!hDC)
                   2063:       {
                   2064:       PostError () ;
                   2065:       return (FALSE) ;
                   2066:       }
                   2067:       
                   2068:    xPageWidth = GetDeviceCaps (hDC, HORZRES) ;
                   2069:    yPageHeight = GetDeviceCaps (hDC, VERTRES) ;
                   2070: 
                   2071:    
                   2072:    StartJob (hDC, TEXT("Performance Monitor Report")) ;
                   2073:    StartPage (hDC) ;   
                   2074: 
                   2075: 
                   2076:    hFont = pReport->hFont ;
                   2077:    hFontHeaders = pReport->hFontHeaders ;
                   2078:    yLineHeight = pReport->yLineHeight ;
                   2079:    xValueWidth = pReport->xValueWidth ;
                   2080: 
                   2081:    pReport->hFont = hFontPrinterScales ;
                   2082:    pReport->hFontHeaders = hFontPrinterScalesBold ;
                   2083: 
                   2084:    SelectFont (hDC, pReport->hFont) ;
                   2085:    pReport->yLineHeight = FontHeight (hDC, TRUE) ;
                   2086: 
                   2087:    pReport->xValueWidth = TextWidth (hDC, szValuePlaceholder) ;
                   2088: 
                   2089:    PrintReportDisplay (hDC, pReport) ;
                   2090: 
                   2091:    EndPage (hDC) ;
                   2092:    EndJob (hDC) ;
                   2093:    
                   2094:    DeleteDC (hDC) ;
                   2095: 
                   2096: 
                   2097:    pReport->hFont = hFont ;
                   2098:    pReport->hFontHeaders = hFontHeaders ;
                   2099:    pReport->yLineHeight = yLineHeight ;
                   2100: 
                   2101:    pReport->xValueWidth = xValueWidth ;
                   2102: 
                   2103:    hDC = GetDC ()hWndReport) ;
                   2104:    SetReportPositions (hDC, pReport) ;
                   2105:    ReleaseDC (hWndReport, hDC) ;
                   2106: 
                   2107:    return (FALSE) ;
                   2108:    }  // PrintReport
                   2109: 
                   2110: // we don't print. we just export
                   2111: #endif
                   2112: 
                   2113: BOOL ExportComputerName (HANDLE hFile, PSYSTEMGROUP pSystemGroup)
                   2114: {
                   2115:    int            StringLen ;
                   2116:    BOOL           bWriteSuccess = TRUE ;
                   2117:    CHAR           TempBuff [LongTextLen] ;
                   2118:    TCHAR          UnicodeBuff [LongTextLen] ;
                   2119: 
                   2120:    // export computer name
                   2121:    strcpy (TempBuff, LineEndStr) ;
                   2122:    strcat (TempBuff, LineEndStr) ;
                   2123:    StringLen = strlen (TempBuff) ;
                   2124:    TSPRINTF (UnicodeBuff, szSystemFormat, pSystemGroup->lpszSystemName) ;
                   2125:    ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
                   2126:    strcat (TempBuff, LineEndStr) ;
                   2127: 
                   2128:    if (!FileWrite (hFile, TempBuff, strlen(TempBuff)))
                   2129:       {
                   2130:       bWriteSuccess = FALSE ; 
                   2131:       }
                   2132: 
                   2133:    return (bWriteSuccess) ;
                   2134: }  // ExportComputerName
                   2135: 
                   2136: BOOL ExportObjectName (HANDLE hFile, POBJECTGROUP pObjectGroup, int *pColNum)
                   2137: {
                   2138:    int            StringLen ;
                   2139:    BOOL           bNeedToExport ;
                   2140:    BOOL           bWriteSuccess = TRUE ;
                   2141:    CHAR           TempBuff [LongTextLen] ;
                   2142:    TCHAR          UnicodeBuff [LongTextLen] ;
                   2143:    PCOLUMNGROUP   pColumnGroup ;
                   2144:    int            ParentNum, InstanceNum ;
                   2145: 
                   2146: 
                   2147:    ParentNum = InstanceNum = 0 ;
                   2148: 
                   2149:    if (pColNum)
                   2150:       {
                   2151:       *pColNum = 0 ;
                   2152:       }
                   2153: 
                   2154:    // export object name
                   2155:    strcpy (TempBuff, LineEndStr) ;
                   2156:    StringLen = strlen (TempBuff) ;
                   2157:    TSPRINTF (UnicodeBuff, szObjectFormat, pObjectGroup->lpszObjectName) ;
                   2158:    ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
                   2159:    strcat (TempBuff, LineEndStr) ;
                   2160: 
                   2161:    if (!FileWrite (hFile, TempBuff, strlen(TempBuff)))
                   2162:       {
                   2163:       goto Exit0 ;
                   2164:       }
                   2165:    
                   2166: 
                   2167:    // export column group
                   2168:    if (pObjectGroup->pColumnGroupFirst)
                   2169:       {
                   2170:       strcpy (TempBuff, pDelimiter) ;
                   2171:       strcat (TempBuff, pDelimiter) ;
                   2172:       StringLen = strlen (TempBuff) ;
                   2173: 
                   2174:       bNeedToExport = FALSE ;
                   2175: 
                   2176:       // export Parent Names
                   2177:       for (pColumnGroup = pObjectGroup->pColumnGroupFirst ;
                   2178:            pColumnGroup ;
                   2179:            pColumnGroup = pColumnGroup->pColumnGroupNext)
                   2180:          {  // for
                   2181: 
                   2182:          if (pColumnGroup->lpszParentName)
                   2183:             {
                   2184:             ParentNum++ ;
                   2185:             bNeedToExport = TRUE ;
                   2186:             ConvertUnicodeStr (&TempBuff[StringLen],
                   2187:                                pColumnGroup->lpszParentName) ;
                   2188:             StringLen = strlen (TempBuff) ;
                   2189:             }
                   2190:                         
                   2191:          strcat (&TempBuff[StringLen], pDelimiter) ;
                   2192:          StringLen = strlen (TempBuff) ;
                   2193:          }
                   2194:           
                   2195:       if (bNeedToExport)
                   2196:          {
                   2197:          // only need to export when there is Parent Instance
                   2198:          strcat (&TempBuff[StringLen], LineEndStr) ;
                   2199:          if (!FileWrite (hFile, TempBuff, strlen(TempBuff)))
                   2200:             {
                   2201:             goto Exit0 ;
                   2202:             }
                   2203:          }
                   2204:       else
                   2205:          {
                   2206:          ParentNum = 0 ;
                   2207:          }
                   2208: 
                   2209: 
                   2210:       // setup to export Instances
                   2211:       strcpy (TempBuff, pDelimiter) ;
                   2212:       strcat (TempBuff, pDelimiter) ;
                   2213:       StringLen = strlen (TempBuff) ;
                   2214:       bNeedToExport = FALSE ;
                   2215: 
                   2216:       // export Instance Names
                   2217:       for (pColumnGroup = pObjectGroup->pColumnGroupFirst ;
                   2218:            pColumnGroup ;
                   2219:            pColumnGroup = pColumnGroup->pColumnGroupNext)
                   2220:          {  // for
                   2221: 
                   2222:          if (pColumnGroup->lpszInstanceName)
                   2223:             {
                   2224:             InstanceNum++ ;
                   2225:             bNeedToExport = TRUE ;
                   2226:             ConvertUnicodeStr (&TempBuff[StringLen],
                   2227:                                pColumnGroup->lpszInstanceName) ;
                   2228:             StringLen = strlen (TempBuff) ;
                   2229:             }
                   2230:                
                   2231:          strcat (&TempBuff[StringLen], pDelimiter) ;
                   2232:          StringLen = strlen (TempBuff) ;
                   2233:          }
                   2234: 
                   2235:       if (bNeedToExport)
                   2236:          {
                   2237:          strcat (&TempBuff[StringLen], LineEndStr) ;
                   2238:          if (!FileWrite (hFile, TempBuff, strlen(TempBuff)))
                   2239:             {
                   2240:             goto Exit0 ;
                   2241:             }
                   2242:          }
                   2243:       else
                   2244:          {
                   2245:          InstanceNum = 0 ;
                   2246:          }
                   2247:       }
                   2248: 
                   2249:    if (pColNum)
                   2250:       {
                   2251:       *pColNum = max (ParentNum, InstanceNum) ;
                   2252:       }
                   2253: 
                   2254:    return (TRUE) ;
                   2255: 
                   2256: Exit0:
                   2257:    return (FALSE) ;
                   2258: 
                   2259: }  // ExportObjectName
                   2260: 
                   2261: BOOL ExportLineName (HANDLE hFile, PLINE pLine, int *pExportCounterName)
                   2262: {
                   2263:    FLOAT          eValue ;
                   2264:    int            StringLen ;
                   2265:    BOOL           bWriteSuccess = TRUE ;
                   2266:    CHAR           TempBuff [LongTextLen] ;
                   2267:    TCHAR          UnicodeBuff [LongTextLen] ;
                   2268: 
                   2269: 
                   2270:    strcpy (TempBuff, pDelimiter) ;
                   2271:    
                   2272:    if (*pExportCounterName)
                   2273:       {
                   2274:       StringLen = strlen (TempBuff) ;
                   2275:       ConvertUnicodeStr (&TempBuff[StringLen], pLine->lnCounterName) ;
                   2276:       strcat (TempBuff, pDelimiter) ;
                   2277:       *pExportCounterName = FALSE ;
                   2278:       }
                   2279:    StringLen = strlen (TempBuff) ;
                   2280: 
                   2281:    if (pLine->bFirstTime == 0)
                   2282:       {
                   2283:       eValue = (*(pLine->valNext)) (pLine) ;
                   2284:       TSPRINTF (UnicodeBuff,
                   2285:                 (eValue > eStatusLargeValueMax) ?
                   2286:                     szLargeValueFormat : szValueFormat,
                   2287:                 eValue) ;
                   2288:       ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
                   2289:       }
                   2290:    else
                   2291:       {
                   2292:       // export "----" for unstable values
                   2293:       strcat (&TempBuff[StringLen], "----");
                   2294:       }
                   2295: 
                   2296:    // write the line value, it may be inefficient but we
                   2297:    // don't want to overflow TempBuff with line values..
                   2298:    if (!FileWrite (hFile, TempBuff, strlen(TempBuff)))
                   2299:       {
                   2300:       goto Exit0 ;
                   2301:       }
                   2302: 
                   2303:    return (TRUE) ;
                   2304: 
                   2305: 
                   2306: Exit0:
                   2307:    return (FALSE) ;
                   2308: }  // ExportLineName
                   2309: 
                   2310: 
                   2311: // This routine is need to insert the line values into its
                   2312: // column location.  It is needed because not all the instances (columns)
                   2313: // are available for the same line.
                   2314: void SaveColumnLineData (PLINE pLine, LPSTR pColumnLineData)
                   2315: {
                   2316:    FLOAT          eValue ;
                   2317:    LPSTR          pColumnLine ;
                   2318:    CHAR           TempBuff [LongTextLen] ;
                   2319:    TCHAR          UnicodeBuff [LongTextLen] ;
                   2320: 
                   2321:    if (!pColumnLineData)
                   2322:       {
                   2323:       return ;
                   2324:       }
                   2325: 
                   2326:    // find the offset into the pColumnLineData buffer for current line
                   2327:    pColumnLine = pColumnLineData + pLine->iScaleIndex * ShortTextLen ;
                   2328: 
                   2329:    if (pLine->bFirstTime == 0)
                   2330:       {
                   2331:       eValue = (*(pLine->valNext)) (pLine) ;
                   2332:       TSPRINTF (UnicodeBuff,
                   2333:                 (eValue > eStatusLargeValueMax) ?
                   2334:                     szLargeValueFormat : szValueFormat,
                   2335:                 eValue) ;
                   2336: 
                   2337:       ConvertUnicodeStr (TempBuff, UnicodeBuff) ;
                   2338:       strncpy (pColumnLine, TempBuff, ShortTextLen) ;
                   2339:       *(pColumnLine + ShortTextLen - 1) = '\0' ;
                   2340:       }
                   2341:    else
                   2342:       {
                   2343:       // export "----" for unstable values
                   2344:       strcpy (pColumnLine, "----");
                   2345:       }
                   2346: }  // SaveColumnLineData
                   2347: 
                   2348: BOOL ExportColumnLineData (HANDLE hFile,
                   2349:                            int ColumnTotal,
                   2350:                            PCOUNTERGROUP pCounterGroup,
                   2351:                            LPSTR pColumnLineData)
                   2352: {
                   2353:    int            iIndex ;
                   2354:    int            StringLen ;
                   2355:    CHAR           TempBuff [LongTextLen] ;
                   2356:    LPSTR          pCurrentLineData ;
                   2357: 
                   2358:    // export the counter name
                   2359:    strcpy (TempBuff, pDelimiter) ;
                   2360:    StringLen = strlen (TempBuff) ;
                   2361:    ConvertUnicodeStr (&TempBuff[StringLen], pCounterGroup->pLineFirst->lnCounterName) ;
                   2362:    strcat (TempBuff, pDelimiter) ;
                   2363:    if (!FileWrite (hFile, TempBuff, strlen(TempBuff)))
                   2364:       {
                   2365:       goto Exit0 ;
                   2366:       }
                   2367: 
                   2368:    // go thru each column and export the line value if it has been stored   
                   2369:    for (iIndex = 0, pCurrentLineData = pColumnLineData ;
                   2370:       iIndex < ColumnTotal ;
                   2371:       iIndex++, pCurrentLineData += ShortTextLen )
                   2372:       {
                   2373:       if (*pCurrentLineData != 0)
                   2374:          {
                   2375:          // data available for this column
                   2376:          if (!FileWrite (hFile, pCurrentLineData, strlen(pCurrentLineData)))
                   2377:             {
                   2378:             goto Exit0 ;
                   2379:             }
                   2380:          }
                   2381: 
                   2382:       if (!FileWrite (hFile, pDelimiter, strlen(pDelimiter)))
                   2383:          {
                   2384:          goto Exit0 ;
                   2385:          }
                   2386:       }
                   2387: 
                   2388:    if (!FileWrite (hFile, LineEndStr, strlen(LineEndStr)))
                   2389:       {
                   2390:       goto Exit0 ;
                   2391:       }
                   2392: 
                   2393:    return (TRUE) ;
                   2394: 
                   2395: 
                   2396: Exit0:
                   2397:    return (FALSE) ;
                   2398: 
                   2399: }  // ExportColumnLineData
                   2400: 
                   2401: void ExportReport (void)
                   2402: {
                   2403:    HANDLE         hFile = 0 ;
                   2404:    PREPORT        pReport ;
                   2405:    PSYSTEMGROUP   pSystemGroup ;
                   2406:    POBJECTGROUP   pObjectGroup ;
                   2407:    PCOUNTERGROUP  pCounterGroup ;
                   2408:    PLINE          pLine ;
                   2409:    BOOL           bExportComputer ;
                   2410:    BOOL           bExportObject ;
                   2411:    BOOL           bExportCounterName ;
                   2412:    int            ColumnTotal = 0 ;
                   2413:    LPSTR          pColumnLineData = NULL ;
                   2414:    LPTSTR         pFileName = NULL ;
                   2415:    INT            ErrCode = 0 ;
                   2416: 
                   2417:    if (!(pReport = ReportData (hWndReport)))
                   2418:       {
                   2419:       return ;
                   2420:       }
                   2421: 
                   2422:    // see if there is anything to export..
                   2423:    if (!(pReport->pSystemGroupFirst))
                   2424:       {
                   2425:       return ;
                   2426:       }
                   2427: 
                   2428:    SetHourglassCursor() ;
                   2429:    
                   2430:    if (ErrCode = ExportFileOpen (hWndReport, &hFile,
                   2431:        pReport->iIntervalMSecs, &pFileName))
                   2432:       {
                   2433:       goto Exit0 ;
                   2434:       }
                   2435: 
                   2436:    if (!pFileName)
                   2437:       {
                   2438:       // the case when user cancel
                   2439:       goto Exit0 ;
                   2440:       }
                   2441: 
                   2442:    // export each system group
                   2443: 
                   2444:    for (pSystemGroup = pReport->pSystemGroupFirst ;
                   2445:         pSystemGroup ;
                   2446:         pSystemGroup = pSystemGroup->pSystemGroupNext)
                   2447:       {  // for System...
                   2448: 
                   2449:       bExportComputer = TRUE ;
                   2450: 
                   2451:       for (pObjectGroup = pSystemGroup->pObjectGroupFirst ;
                   2452:            pObjectGroup ;
                   2453:            pObjectGroup = pObjectGroup->pObjectGroupNext)
                   2454:          {  // for Object...
                   2455: 
                   2456:          bExportObject = TRUE ;
                   2457: 
                   2458:          for (pCounterGroup = pObjectGroup->pCounterGroupFirst ;
                   2459:               pCounterGroup ;
                   2460:               pCounterGroup = pCounterGroup->pCounterGroupNext)
                   2461:             {  // for Counter...
                   2462: 
                   2463:             bExportCounterName = TRUE ;
                   2464: 
                   2465:             // Column data buffer has been allocated for this object type, 
                   2466:             // zero out the buffer and prepare for next round.
                   2467:          
                   2468:             if (pColumnLineData)
                   2469:                {
                   2470:                memset (pColumnLineData, 0, ColumnTotal * ShortTextLen) ;
                   2471:                }
                   2472: 
                   2473:             for (pLine = pCounterGroup->pLineFirst ;
                   2474:                  pLine ;
                   2475:                  pLine = pLine->pLineCounterNext)
                   2476:                {  // for Line...
                   2477: 
                   2478:                if (bExportComputer)
                   2479:                   {
                   2480:                   // only need to do this for the first object
                   2481:                   bExportComputer = FALSE ;
                   2482:                   if (!ExportComputerName (hFile, pSystemGroup))
                   2483:                      {
                   2484:                      ErrCode = ERR_EXPORT_FILE ;
                   2485:                      goto Exit0 ;
                   2486:                      }
                   2487:                   }
                   2488: 
                   2489:                if (bExportObject)
                   2490:                   {
                   2491:                   // only need to do this for the first counter group
                   2492:                   bExportObject = FALSE ;
                   2493:                   if (!ExportObjectName (hFile, pObjectGroup, &ColumnTotal))
                   2494:                      {
                   2495:                      ErrCode = ERR_EXPORT_FILE ;
                   2496:                      goto Exit0 ;
                   2497:                      }
                   2498: 
                   2499:                   if (ColumnTotal > 1)
                   2500:                      {
                   2501:                      // special case to setup a column array and export
                   2502:                      // the line values later
                   2503:                      pColumnLineData = MemoryAllocate (ColumnTotal * ShortTextLen) ;
                   2504:                      if (!pColumnLineData)
                   2505:                         {
                   2506:                         ErrCode = ERR_EXPORT_FILE ;
                   2507:                         goto Exit0 ;
                   2508:                         }
                   2509:                      }
                   2510:                   }
                   2511: 
                   2512:                if (ColumnTotal > 1)
                   2513:                   {
                   2514:                   // save the line value into its column & export later
                   2515:                   SaveColumnLineData (pLine, pColumnLineData) ;
                   2516:                   }
                   2517:                else
                   2518:                   {
                   2519:                   // simple case, export the line now
                   2520:                   if (!ExportLineName (hFile, pLine, &bExportCounterName))
                   2521:                      {
                   2522:                      ErrCode = ERR_EXPORT_FILE ;
                   2523:                      goto Exit0 ;
                   2524:                      }
                   2525:                   }
                   2526:                }  // for Line...
                   2527: 
                   2528:             if (!bExportCounterName)
                   2529:                {
                   2530:                // export the line end
                   2531:                if (!FileWrite (hFile, LineEndStr, strlen(LineEndStr)))
                   2532:                   {
                   2533:                   ErrCode = ERR_EXPORT_FILE ;
                   2534:                   goto Exit0 ;
                   2535:                   }
                   2536:                }
                   2537: 
                   2538:             if (pColumnLineData)
                   2539:                {
                   2540:                // now, do the actual export
                   2541:                if (!ExportColumnLineData (hFile,
                   2542:                   ColumnTotal,
                   2543:                   pCounterGroup,
                   2544:                   pColumnLineData))
                   2545:                   {
                   2546:                   ErrCode = ERR_EXPORT_FILE ;
                   2547:                   goto Exit0 ;
                   2548:                   }
                   2549:                }
                   2550:             }  // for Counter...
                   2551: 
                   2552:          // done with the object, done with the buffer
                   2553:          if (pColumnLineData)
                   2554:             {
                   2555:             MemoryFree (pColumnLineData) ;
                   2556:             ColumnTotal = 0 ;
                   2557:             pColumnLineData = NULL ;
                   2558:             }
                   2559:          }  // for Object
                   2560: 
                   2561: 
                   2562:       }  // for System...
                   2563: 
                   2564: Exit0:
                   2565: 
                   2566:    SetArrowCursor() ;
                   2567: 
                   2568:    if (pColumnLineData)
                   2569:       {
                   2570:       MemoryFree (pColumnLineData) ;
                   2571:       }
                   2572: 
                   2573:    if (hFile)
                   2574:       {
                   2575:       CloseHandle (hFile) ;
                   2576:       }
                   2577: 
                   2578:    if (pFileName)
                   2579:       {
                   2580:       if (ErrCode)
                   2581:          {
                   2582:          DlgErrorBox (hWndGraph, ErrCode, pFileName) ;
                   2583:          }
                   2584: 
                   2585:       MemoryFree (pFileName) ;
                   2586:       }
                   2587: 
                   2588: }  // ExportReport
                   2589: 
                   2590: 
                   2591: BOOL
                   2592: BuildNewValueListForReport (
                   2593: )
                   2594: {
                   2595:     PREPORT pReport;
                   2596: 
                   2597:     pReport = ReportData (hWndReport);
                   2598:     
                   2599:     return BuildValueListForSystems (
                   2600:         pReport->pSystemFirst,
                   2601:         pReport->pLineFirst);
                   2602: 
                   2603: }
                   2604: 
                   2605: 
                   2606: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.