Annotation of mstools/samples/sdktools/perfmon/report.c, revision 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.