Annotation of mstools/samples/sdktools/perfmon/grafdata.c, revision 1.1

1.1     ! root        1: /*****************************************************************************
        !             2:  *
        !             3:  *  Grafdata.c - This module handles the non-drawing functions of the graph,
        !             4:  *      such as allocating linked structures and their memory, freeing it,
        !             5:  *      unlinking, starting and stopping the timer,
        !             6:  *      setting up the first graph (CPU), and all the numeric functions for
        !             7:  *      the different counter types.
        !             8:  *
        !             9:  *  Microsoft Confidential
        !            10:  *  Copyright (c) 1992-1993 Microsoft Corporation
        !            11:  *
        !            12:  *
        !            13:  ****************************************************************************/
        !            14: 
        !            15: 
        !            16: //==========================================================================//
        !            17: //                                  Includes                                //
        !            18: //==========================================================================//
        !            19: 
        !            20: #include <stdio.h>      // for sprintf
        !            21: 
        !            22: #include "perfmon.h"       // main perfmon declarations
        !            23: #include "grafdata.h"      // external declarations for this file
        !            24: #include <float.h>         // for FLT_MAX constant
        !            25: 
        !            26: #include "addline.h"       // for AddLine, EditLine
        !            27: #include "counters.h"      // for Counter_Counter, et al.
        !            28: #include "graph.h"         // for SizeGraphComponents
        !            29: #include "pmemory.h"       // for MemoryXXX (mallloc-type) routines
        !            30: #include "perfdata.h"      // for UpdateLines
        !            31: #include "playback.h"      // for PlayingBackLog, PlaybackLines
        !            32: #include "legend.h"
        !            33: #include "system.h"        // for SystemGet
        !            34: #include "utils.h"
        !            35: #include "line.h"          // for LineFree
        !            36: #include "valuebar.h"      // for StatusTimer
        !            37: 
        !            38: #include "fileopen.h"      // for FileGetName
        !            39: #include "fileutil.h"      // for FileRead...
        !            40: #include "menuids.h"       // for IDM_VIEWCHART
        !            41: #include "perfmops.h"      // for ExportFileHeader
        !            42: #include "status.h"        // for StatusLineReady
        !            43: 
        !            44: extern BOOL SaveFileHandler(HWND hWnd,DWORD type) ;
        !            45: 
        !            46: // this macro is used in doing a simple DDA (Digital Differential Analyzer)
        !            47: // * 10 + 5 is to make the result round up with .5
        !            48: #define DDA_DISTRIBUTE(TotalTics, numOfData) \
        !            49:    ((TotalTics * 10 / numOfData) + 5) / 10
        !            50: 
        !            51: #define szSmallValueFormat         TEXT("%10.3f")
        !            52: #define szLargeValueFormat         TEXT("%10.0f")
        !            53: 
        !            54: //==========================================================================//
        !            55: //                                Local Data                                //
        !            56: //==========================================================================//
        !            57: 
        !            58: 
        !            59: 
        !            60: 
        !            61: //==========================================================================//
        !            62: //                              Local Functions                             //
        !            63: //==========================================================================//
        !            64: 
        !            65: 
        !            66: /****************************************************************************
        !            67:  * eUpdateMinMaxAve -
        !            68:  ****************************************************************************/
        !            69: void eUpdateMinMaxAve (FLOAT eValue, PLINESTRUCT pLineStruct, INT iValidValues,
        !            70:    INT iTotalValidPoints, INT iDataPoint, INT gMaxPoints)
        !            71: {
        !            72: INT     i ;
        !            73: INT     iDataNum = iTotalValidPoints ;
        !            74: FLOAT   eMin,
        !            75:         eMax,
        !            76:         eSum,
        !            77:         eNewValue ;
        !            78: 
        !            79: 
        !            80:    eMax = eMin = eValue ;
        !            81: 
        !            82:    if (PlayingBackLog())
        !            83:       {
        !            84:       eSum = (FLOAT) 0.0 ;
        !            85:       }
        !            86:    else
        !            87:       {
        !            88:       eSum = eValue ;
        !            89:       }
        !            90: 
        !            91:    if (iValidValues == iTotalValidPoints)
        !            92:       {
        !            93:       for (i=0 ; i < iValidValues ; i++)
        !            94:          {
        !            95:          if (i == iDataPoint)
        !            96:             {
        !            97:             // skip the data point we are going to replace
        !            98:             continue ;
        !            99:             }
        !           100: 
        !           101:          eNewValue = pLineStruct->lnValues[i] ;
        !           102:          
        !           103:          eSum += eNewValue ;
        !           104: 
        !           105:          if (eNewValue > eMax)
        !           106:             {
        !           107:             eMax = eNewValue ;
        !           108:             }
        !           109: 
        !           110:          if (eNewValue < eMin)
        !           111:             {
        !           112:             eMin = eNewValue ;
        !           113:             }
        !           114:          }
        !           115:       }
        !           116:    else
        !           117:       {
        !           118:       // special case when we start the new line in the middle of the chart
        !           119:       for (i = iDataPoint, iTotalValidPoints-- ;
        !           120:           iTotalValidPoints > 0 ;
        !           121:           iTotalValidPoints-- )
        !           122:          {
        !           123:          i-- ;
        !           124:          if (i < 0)
        !           125:             {
        !           126:             // for the wrap-around case..
        !           127:             i = gMaxPoints - 1 ;
        !           128:             }
        !           129: 
        !           130:          if (i == iDataPoint)
        !           131:             {
        !           132:             // skip the data point we are going to replace
        !           133:             continue ;
        !           134:             }
        !           135:          eNewValue = pLineStruct->lnValues[i] ;
        !           136: 
        !           137:          eSum += eNewValue ;
        !           138: 
        !           139:          if (eNewValue > eMax)
        !           140:             {
        !           141:             eMax = eNewValue ;
        !           142:             }
        !           143: 
        !           144:          if (eNewValue < eMin)
        !           145:             {
        !           146:             eMin = eNewValue ;
        !           147:             }
        !           148:          }
        !           149:       }
        !           150: 
        !           151:    pLineStruct->lnMinValue = eMin ;
        !           152:    pLineStruct->lnMaxValue = eMax ;
        !           153: 
        !           154:    if (iDataNum)
        !           155:       {
        !           156:       pLineStruct->lnAveValue = eSum / (FLOAT) iDataNum ;
        !           157:       }
        !           158:    else
        !           159:       {
        !           160:       pLineStruct->lnAveValue = (FLOAT) 0.0 ;
        !           161:       }
        !           162: }
        !           163: 
        !           164: 
        !           165: // UpdateValueBarData is used to update the value bar data
        !           166: // It is called when the user switches to a diff. line from
        !           167: // the legned window.
        !           168: VOID UpdateValueBarData (PGRAPHSTRUCT pGraph)
        !           169:    {
        !           170:    PLINESTRUCT    pCurrentGraphLine ;   
        !           171:    INT            KnownValue,
        !           172:                   MaxValues,
        !           173:                   iValidValues,
        !           174:                   iDataPoint ;
        !           175:    FLOAT          eValue ;
        !           176:    pCurrentGraphLine = CurrentGraphLine (hWndGraph) ;
        !           177: 
        !           178:    if (!pCurrentGraphLine || pCurrentGraphLine->bFirstTime)
        !           179:       {
        !           180:       // we have not collect enough samples
        !           181:       return ;
        !           182:       }
        !           183: 
        !           184:    KnownValue = pGraph->gKnownValue ;
        !           185:    MaxValues = pGraph->gMaxValues ;
        !           186: 
        !           187:    // The valid values is the number of valid entries in the
        !           188:    // data buffer.  After we wrap the buffer, all the values are
        !           189:    // valid.
        !           190:    iValidValues = pGraph->gTimeLine.iValidValues ;
        !           191: 
        !           192:    // Get the index to the data point we are updating.
        !           193: 
        !           194:    iDataPoint = KnownValue % MaxValues ;
        !           195:    eValue = pCurrentGraphLine->lnValues[iDataPoint] ;
        !           196: 
        !           197:    // get the statistical data for this line
        !           198:    eUpdateMinMaxAve(eValue, pCurrentGraphLine,
        !           199:       iValidValues, pCurrentGraphLine->lnValidValues,
        !           200:       iDataPoint, MaxValues) ;
        !           201:    }  // UpdateValueBarData
        !           202: 
        !           203: 
        !           204: VOID UpdateLGData (PGRAPHSTRUCT pGraph)
        !           205:    {
        !           206:    PLINESTRUCT    pLine ;               
        !           207:    PLINESTRUCT    pCurrentGraphLine ;   
        !           208:    INT            KnownValue,
        !           209:                   MaxValues,
        !           210:                   iValidValues,
        !           211:                   iDataPoint ;
        !           212:    FLOAT          eValue ;
        !           213:    // Known Value is the where data is placed in the buffer.
        !           214:    pGraph->gKnownValue++;
        !           215: 
        !           216:    KnownValue = pGraph->gKnownValue ;
        !           217: 
        !           218:    // Update the high water mark for valid data in the lnValues
        !           219:    // (aka DataPoint) buffer.
        !           220: 
        !           221: 
        !           222:    MaxValues = pGraph->gMaxValues ;
        !           223: 
        !           224:    // The valid values is the number of valid entries in the
        !           225:    // data buffer.  After we wrap the buffer, all the values are
        !           226:    // valid.
        !           227:    iValidValues = pGraph->gTimeLine.iValidValues ;
        !           228: 
        !           229:    if (iValidValues < MaxValues)
        !           230:        iValidValues = (KnownValue % MaxValues) + 1 ;
        !           231: 
        !           232:    pGraph->gTimeLine.iValidValues = iValidValues ;
        !           233: 
        !           234:    // Get the index to the data point we are updating.
        !           235: 
        !           236:    iDataPoint = KnownValue % MaxValues ;
        !           237: 
        !           238:    // loop through lines,
        !           239:    // If one of the lines is highlighted then do the calculations
        !           240:    // for average, min, & max on that line.
        !           241: 
        !           242:    pCurrentGraphLine = CurrentGraphLine (hWndGraph) ;
        !           243: 
        !           244:    for (pLine=pGraph->pLineFirst; pLine; pLine=pLine->pLineNext)
        !           245:      { // for
        !           246: 
        !           247:      if (pLine->bFirstTime)
        !           248:          {
        !           249:          // skip until we have collect enough samples to plot the first data
        !           250:          continue ;
        !           251:          }
        !           252: 
        !           253:      if (pLine->lnValidValues < MaxValues)
        !           254:          {   
        !           255:          (pLine->lnValidValues)++ ;
        !           256:          }
        !           257:    
        !           258:      // Get the new value for this line.
        !           259:      eValue = (*(pLine->valNext))(pLine) ;
        !           260: 
        !           261:      if (pLine == pCurrentGraphLine)
        !           262:         {  // if
        !           263:         // get the statistical data for this line
        !           264:         eUpdateMinMaxAve (eValue, pLine, 
        !           265:                                  iValidValues, pLine->lnValidValues,
        !           266:                                  iDataPoint, MaxValues) ;
        !           267:         }  // if
        !           268:       
        !           269:      // Now put the new value into the data array
        !           270:      pLine->lnValues[iDataPoint] = eValue ;
        !           271:      }
        !           272:    
        !           273:    GetLocalTime (&(pGraph->pDataTime[iDataPoint])) ; 
        !           274:    }  // UpdateLGData
        !           275: 
        !           276: 
        !           277: 
        !           278: BOOL HandleGraphTimer (void)
        !           279:    {
        !           280:    PGRAPHSTRUCT pGraph;
        !           281: 
        !           282:    //NOTE: get a strategy for these "no-go" states
        !           283:    if (!(pGraph = pGraphs) || !pGraphs->pSystemFirst)
        !           284:        return(FALSE);
        !           285: 
        !           286: 
        !           287:    if (!UpdateLines(&(pGraphs->pSystemFirst), pGraphs->pLineFirst))
        !           288:         return (TRUE) ;
        !           289: 
        !           290:    UpdateLGData(pGraph);
        !           291: 
        !           292:    return(TRUE);
        !           293:    }
        !           294: 
        !           295: 
        !           296: VOID ClearGraphTimer(PGRAPHSTRUCT pGraph)
        !           297:    {
        !           298:    KillTimer(pGraph->hWnd, GRAPH_TIMER_ID);
        !           299:    }
        !           300: 
        !           301: 
        !           302: VOID SetGraphTimer(PGRAPHSTRUCT pGraph)
        !           303:    {
        !           304:    SetTimer(pGraph->hWnd, GRAPH_TIMER_ID, pGraph->gInterval, NULL) ;
        !           305:    }
        !           306: 
        !           307: VOID ResetGraphTimer(PGRAPHSTRUCT pGraph)
        !           308: {
        !           309:     KillTimer(pGraph->hWnd, GRAPH_TIMER_ID);
        !           310:     SetGraphTimer(pGraph);
        !           311: }
        !           312: 
        !           313: 
        !           314: VOID GetGraphConfig(PGRAPHSTRUCT pGraph)
        !           315: {
        !           316: 
        !           317:     LoadRefreshSettings(pGraph);
        !           318:     LoadLineGraphSettings(pGraph);
        !           319: 
        !           320: 
        !           321:     // Init the structure
        !           322:     pGraph->pLineFirst = NULL;
        !           323: 
        !           324:     //NOTE: put the rest of this in Config
        !           325: 
        !           326:     pGraph->gOptions.bLegendChecked    = TRUE;
        !           327:     pGraph->gOptions.bMenuChecked      = TRUE;
        !           328:     pGraph->gOptions.bLabelsChecked    = TRUE;
        !           329:     pGraph->gOptions.bVertGridChecked  = FALSE;
        !           330:     pGraph->gOptions.bHorzGridChecked  = FALSE;
        !           331:     pGraph->gOptions.bStatusBarChecked = TRUE;
        !           332:     pGraph->gOptions.GraphVGrid        = TRUE;
        !           333:     pGraph->gOptions.GraphHGrid        = TRUE;
        !           334:     pGraph->gOptions.HistVGrid         = TRUE;
        !           335:     pGraph->gOptions.HistHGrid         = TRUE;
        !           336: 
        !           337:     pGraph->gOptions.iGraphOrHistogram = LINE_GRAPH;       // vs. BAR_GRAPH
        !           338:     pGraph->gOptions.iVertMax = DEF_GRAPH_VMAX;
        !           339: 
        !           340:     return;
        !           341: }
        !           342: 
        !           343: 
        !           344: BOOL InsertGraph (HWND hWnd)
        !           345:    {
        !           346:    PGRAPHSTRUCT    pGraph;
        !           347: 
        !           348:    pGraph = MemoryAllocate (sizeof (GRAPHSTRUCT)) ;
        !           349:    if (!pGraph)
        !           350:       return (FALSE) ;
        !           351: 
        !           352: 
        !           353:    pGraphs = pGraph;
        !           354: 
        !           355:    
        !           356:    GetGraphConfig(pGraph);
        !           357:    pGraph->bManualRefresh = FALSE ;
        !           358: 
        !           359:    pGraph->gMaxValues = DEFAULT_MAX_VALUES;
        !           360:    pGraph->pptDataPoints = 
        !           361:       (PPOINT) MemoryAllocate (sizeof (POINT) * pGraph->gMaxValues) ;
        !           362: 
        !           363:    pGraph->pDataTime =
        !           364:       (SYSTEMTIME *) MemoryAllocate (sizeof(SYSTEMTIME) * pGraph->gMaxValues) ;
        !           365: 
        !           366:    pGraph->hWnd = hWnd ;
        !           367:    pGraph->bModified = FALSE ;
        !           368: 
        !           369:    pGraph->Visual.iColorIndex = 0 ;
        !           370:    pGraph->Visual.iWidthIndex = 0 ;
        !           371:    pGraph->Visual.iStyleIndex = 0 ;
        !           372: 
        !           373:    return(TRUE) ;
        !           374:    }
        !           375: 
        !           376: 
        !           377: 
        !           378: void PlaybackSetGraphLines (HWND hWndChart, 
        !           379:                             PLINE pLineFirst, 
        !           380:                             int iDisplayTic,
        !           381:                             int iLogTic,
        !           382:                             BOOL CalcData)
        !           383:    {
        !           384:    PLINE          pLine ;
        !           385:    FLOAT          eValue ;
        !           386: 
        !           387:    for (pLine = pLineFirst ;
        !           388:         pLine ;
        !           389:         pLine = pLine->pLineNext)
        !           390:       {  // for
        !           391:       eValue = (*(pLine->valNext))(pLine) ;
        !           392:       pLine->lnValues[iDisplayTic] = eValue ;
        !           393:       pLine->aiLogIndexes[iDisplayTic] = iLogTic ;
        !           394: 
        !           395:       // only need to do this on request.
        !           396:       if (CalcData)
        !           397:          {
        !           398:          eUpdateMinMaxAve (eValue, pLine, iDisplayTic, iDisplayTic,
        !           399:             iDisplayTic, iDisplayTic) ;
        !           400:          }  // if
        !           401:       }  // for
        !           402:    }  // PlaybackSetGraphLines
        !           403: 
        !           404: 
        !           405: 
        !           406: BOOL ChartInsertLine (PGRAPHSTRUCT pGraph, 
        !           407:                       PLINE pLine)
        !           408: /*
        !           409:    Effect:        Insert the line pLine into the graph pGraph and 
        !           410:                   allocate space for the graph's number of values.
        !           411: 
        !           412:    Returns:       Whether the line could be added and space allocated.
        !           413: 
        !           414:    See Also:      LineAllocate (line.c), ChartDeleteLine.
        !           415: */
        !           416:    {  // ChartInsertLine
        !           417:    PLINE          pLineEquivalent ;
        !           418:    INT            i ;
        !           419:    FLOAT          *pTempPts;
        !           420:    HPEN           tempPen ;
        !           421: 
        !           422:    pGraph->bModified = TRUE ;
        !           423: 
        !           424:    pLineEquivalent = FindEquivalentLine (pLine, pGraph->pLineFirst) ;
        !           425:    if (pLineEquivalent)
        !           426:       {
        !           427:       pLineEquivalent->Visual = pLine->Visual ;
        !           428:       pLineEquivalent->iScaleIndex = pLine->iScaleIndex ;
        !           429:       pLineEquivalent->eScale = pLine->eScale ;
        !           430: 
        !           431:       tempPen = pLineEquivalent->hPen ;
        !           432:       pLineEquivalent->hPen =  pLine->hPen ;
        !           433:       pLine->hPen = tempPen ;
        !           434:       return FALSE ;
        !           435:       }
        !           436:    else
        !           437:       {
        !           438:       if (!pGraph->pLineFirst && !PlayingBackLog())
        !           439:          {
        !           440:          SetGraphTimer (pGraph) ;
        !           441:          }
        !           442: 
        !           443:       if (!SystemAdd (&pGraph->pSystemFirst, pLine->lnSystemName))
        !           444:         return FALSE;
        !           445: 
        !           446:       LineAppend (&pGraph->pLineFirst, pLine) ;
        !           447: 
        !           448:       pLine->lnMinValue = FLT_MAX ;
        !           449:       pLine->lnMaxValue = - FLT_MAX ;
        !           450:       pLine->lnAveValue = 0.0F ;
        !           451:       pLine->lnValidValues = 0 ;
        !           452: 
        !           453:       pLine->lnValues = 
        !           454:          (FLOAT *) MemoryAllocate (sizeof (FLOAT) * pGraph->gMaxValues) ;
        !           455:       
        !           456:       for (i = pGraph->gMaxValues, pTempPts = pLine->lnValues ;
        !           457:            i > 0 ;
        !           458:            i-- )
        !           459:          {
        !           460:          *pTempPts++ = (FLOAT) 0.0 ;
        !           461:          }
        !           462: 
        !           463:       if (PlayingBackLog ())
        !           464:          {
        !           465:          pLine->aiLogIndexes =
        !           466:             (int *) MemoryAllocate (sizeof (LONG) * pGraph->gMaxValues) ;
        !           467:          }
        !           468: 
        !           469:       // Add the line to the legend, resize the legend window, and then
        !           470:       // select the new line as the current legend item. Do it in this 
        !           471:       // sequence to avoid the legend scroll bar momentarily appearing and
        !           472:       // then disappearing, since the resize will obviate the scroll bar.
        !           473: 
        !           474:       LegendAddItem (hWndGraphLegend, pLine) ;
        !           475: 
        !           476:       if (!bDelayAddAction)
        !           477:          {
        !           478:          SizeGraphComponents (hWndGraph) ;
        !           479:          LegendSetSelection (hWndGraphLegend, 
        !           480:                           LegendNumItems (hWndGraphLegend) - 1) ;
        !           481: 
        !           482:          if (PlayingBackLog ())
        !           483:             PlaybackChart (pGraph->hWnd) ;
        !           484:          }
        !           485:       }
        !           486: 
        !           487:    return (TRUE) ;
        !           488:    }  // ChartInsertLine
        !           489: 
        !           490: 
        !           491: VOID ChartDeleteLine (PGRAPHSTRUCT pGraph, 
        !           492:                       PLINESTRUCT pLine)
        !           493:    {
        !           494:    PLINESTRUCT npLine;
        !           495: 
        !           496: 
        !           497:    pGraph->bModified = TRUE ;
        !           498: 
        !           499:    if (pGraph->pLineFirst == pLine)
        !           500:        pGraph->pLineFirst = pLine->pLineNext;
        !           501:    else
        !           502:    {
        !           503:        for (npLine = pGraph->pLineFirst; npLine; npLine = npLine->pLineNext)
        !           504:        {
        !           505:            if (npLine->pLineNext == pLine)
        !           506:                npLine->pLineNext = pLine->pLineNext;
        !           507:        }
        !           508:    }
        !           509: 
        !           510:    if (!pGraph->pLineFirst)
        !           511:       {
        !           512:       ResetGraph (pGraph) ;
        !           513:       }
        !           514:    else
        !           515:       {
        !           516:       BuildNewValueListForGraph () ;
        !           517:       }
        !           518: 
        !           519:    // Delete the legend entry for this line.
        !           520:    // If the line was highlighted then this will undo the highlight.
        !           521: 
        !           522:    LegendDeleteItem (hWndGraphLegend, pLine) ;
        !           523: 
        !           524:    LineFree (pLine) ;
        !           525: 
        !           526:    SizeGraphComponents (hWndGraph) ;
        !           527: 
        !           528: 
        !           529:    }
        !           530: 
        !           531: 
        !           532: FLOAT Counter_Queuelen(PLINESTRUCT pLine)
        !           533: {
        !           534: 
        !           535:     return((FLOAT)0.0);
        !           536: //    pLine;
        !           537: }
        !           538: 
        !           539: 
        !           540: void ClearGraphDisplay (PGRAPHSTRUCT pGraph)
        !           541:    {
        !           542:    PLINESTRUCT    pLine;
        !           543: 
        !           544:    // reset the timeline data
        !           545:    pGraph->gKnownValue = -1 ;
        !           546:    pGraph->gTimeLine.iValidValues = 0 ;
        !           547:    pGraph->gTimeLine.xLastTime = 0 ;
        !           548:    memset (pGraph->pDataTime, 0, sizeof(SYSTEMTIME) * pGraph->gMaxValues) ;
        !           549: 
        !           550:    // loop through lines,
        !           551:    // If one of the lines is highlighted then do the calculations
        !           552:    // for average, min, & max on that line.
        !           553: 
        !           554:    for (pLine=pGraph->pLineFirst; pLine; pLine=pLine->pLineNext)
        !           555:       { // for
        !           556: 
        !           557:       pLine->bFirstTime = 2 ;
        !           558:       pLine->lnMinValue = FLT_MAX ;
        !           559:       pLine->lnMaxValue = - FLT_MAX ;
        !           560:       pLine->lnAveValue = 0.0F ;
        !           561:       pLine->lnValidValues = 0 ;
        !           562:       memset (pLine->lnValues, 0, sizeof(FLOAT) * pGraph->gMaxValues) ;
        !           563:       }
        !           564: 
        !           565:    StatusTimer (hWndGraphStatus, TRUE) ;
        !           566:    WindowInvalidate (hWndGraphDisplay) ;
        !           567:    }
        !           568: 
        !           569: void ResetGraphView (HWND hWndGraph)
        !           570:    {
        !           571:    PGRAPHSTRUCT      pGraph ;
        !           572: 
        !           573:    pGraph = GraphData (hWndGraph) ;
        !           574: 
        !           575: 
        !           576:    if (!pGraph)
        !           577:       {
        !           578:       return ;
        !           579:       }
        !           580: 
        !           581:    ChangeSaveFileName (NULL, IDM_VIEWCHART) ;
        !           582: 
        !           583:    if (pGraph->pSystemFirst)
        !           584:       {
        !           585:       ResetGraph (pGraph) ;
        !           586:       }
        !           587:    }  // ResetGraphView
        !           588: 
        !           589: void ResetGraph (PGRAPHSTRUCT pGraph)
        !           590:    {
        !           591:    ClearGraphTimer (pGraph) ;
        !           592:    ClearLegend (hWndGraphLegend) ;
        !           593:    if (pGraph->pLineFirst)
        !           594:       {
        !           595:       FreeLines (pGraph->pLineFirst) ;
        !           596:       pGraph->pLineFirst = NULL ;
        !           597:       }
        !           598: 
        !           599:    if (pGraph->pSystemFirst)
        !           600:       {
        !           601:       FreeSystems (pGraph->pSystemFirst) ;
        !           602:       pGraph->pSystemFirst = NULL ;
        !           603:       }
        !           604: 
        !           605:    pGraph->gKnownValue = -1 ;
        !           606:    pGraph->gTimeLine.iValidValues = 0 ;
        !           607:    pGraph->gTimeLine.xLastTime = 0 ;
        !           608: 
        !           609:    // reset visual data
        !           610:    pGraph->Visual.iColorIndex = 0 ;
        !           611:    pGraph->Visual.iWidthIndex = 0 ;
        !           612:    pGraph->Visual.iStyleIndex = 0 ;
        !           613: 
        !           614:    memset (pGraph->pDataTime, 0, sizeof(SYSTEMTIME) * pGraph->gMaxValues) ;
        !           615: 
        !           616:    SizeGraphComponents (hWndGraph) ;
        !           617:    InvalidateRect(hWndGraph, NULL, TRUE) ;
        !           618:    }
        !           619: 
        !           620: 
        !           621: 
        !           622: void PlaybackChart (HWND hWndChart)
        !           623:    {  // PlaybackChart
        !           624:    int            iDisplayTics ;       // num visual points to display
        !           625:    int            iDisplayTic ;
        !           626:    int            iLogTic ;
        !           627:    int            iLogTicsMove ;
        !           628:    BOOL           bFirstTime = TRUE;
        !           629:    int            iLogTicsRemaining ;
        !           630: 
        !           631:    if (!pGraphs->pLineFirst)
        !           632:       {
        !           633:       // no line to playback
        !           634:       return ;
        !           635:       }
        !           636: 
        !           637:    iLogTicsRemaining = PlaybackLog.iSelectedTics ;
        !           638: 
        !           639: 
        !           640:    // we only have iDisplayTics-1 points since
        !           641:    // we have to use the first two sample points to
        !           642:    // get the first data points.
        !           643:    if (iLogTicsRemaining <= pGraphs->gMaxValues)
        !           644:       {
        !           645:       iDisplayTics = iLogTicsRemaining ;
        !           646:       pGraphs->gTimeLine.iValidValues = iDisplayTics - 1 ;
        !           647:       }
        !           648:    else
        !           649:       {
        !           650:       iDisplayTics = pGraphs->gMaxValues ;
        !           651:       pGraphs->gTimeLine.iValidValues = iDisplayTics ;
        !           652:       }
        !           653: 
        !           654:    iDisplayTic = -1 ;
        !           655:    iLogTic = PlaybackLog.StartIndexPos.iPosition ;
        !           656: 
        !           657:    while (iDisplayTics)
        !           658:       {
        !           659: 
        !           660:       PlaybackLines (pGraphs->pSystemFirst, 
        !           661:                      pGraphs->pLineFirst, 
        !           662:                      iLogTic) ;
        !           663: 
        !           664:       if (bFirstTime)
        !           665:          {
        !           666:          bFirstTime = FALSE ;
        !           667: 
        !           668:          // get the second sample data to form the first data point
        !           669:          iLogTic++ ;
        !           670:          iLogTicsRemaining-- ;
        !           671:          PlaybackLines (pGraphs->pSystemFirst, 
        !           672:                         pGraphs->pLineFirst, 
        !           673:                         iLogTic) ;
        !           674:          }
        !           675:       iDisplayTic++ ;
        !           676:       PlaybackSetGraphLines (hWndChart, pGraphs->pLineFirst, 
        !           677:          iDisplayTic, iLogTic, (iDisplayTics == 1)) ;
        !           678: 
        !           679:       // setup DDA to get the index of the next sample point
        !           680:       iLogTicsMove = DDA_DISTRIBUTE (iLogTicsRemaining, iDisplayTics) ;
        !           681:       iLogTicsRemaining -= iLogTicsMove ;
        !           682:       iLogTic += iLogTicsMove ;
        !           683: 
        !           684:       iDisplayTics-- ;
        !           685: 
        !           686:       }  // while
        !           687: 
        !           688:    // point to the last value for valuebar display
        !           689:    pGraphs->gKnownValue = iDisplayTic ;
        !           690: 
        !           691:    }  // PlaybackChart
        !           692: 
        !           693: 
        !           694: 
        !           695: #if 0
        !           696: PLINESTRUCT CurrentGraphLine (HWND hWndGraph)
        !           697:    {  // CurrentGraphLine
        !           698:    UNREFERENCED_PARAMETER (hWndGraph) ;
        !           699: 
        !           700:    return (LegendCurrentLine (hWndGraphLegend)) ;
        !           701:    }
        !           702: #endif
        !           703: 
        !           704: 
        !           705: BOOL AddChart (HWND hWndParent)
        !           706:    {
        !           707:    return (AddLine (hWndParent, 
        !           708:                     &(pGraphs->pSystemFirst), 
        !           709:                     &(pGraphs->Visual), 
        !           710:                     LineTypeChart)) ;
        !           711:    }
        !           712: 
        !           713: 
        !           714: BOOL EditChart (HWND hWndParent)
        !           715:    {  // EditChart
        !           716:    return (EditLine (hWndParent, 
        !           717:                      &(pGraphs->pSystemFirst), 
        !           718:                      CurrentGraphLine (hWndGraph),
        !           719:                      LineTypeChart)) ;
        !           720:    }
        !           721: 
        !           722: 
        !           723: BOOL QuerySaveChart (HWND hWndParent, PGRAPHSTRUCT pGraph)
        !           724: /*
        !           725:    Effect:        If the graph pGraph is modified, put up a message
        !           726:                   box allowing the user to save the current graph.
        !           727:                   
        !           728:                   Return whether the caller should proceed to load in
        !           729:                   a new or otherwise trash the current graph.
        !           730: */
        !           731:    {  // QuerySaveChart
        !           732: #ifdef KEEP_QUERY
        !           733:    int            iReturn ;
        !           734: 
        !           735:    if (!pGraph->bModified)
        !           736:       return (TRUE) ;
        !           737: 
        !           738:    iReturn = MessageBoxResource (hWndParent, 
        !           739:                                  IDS_SAVECHART, IDS_MODIFIEDCHART,
        !           740:                                  MB_YESNOCANCEL | MB_ICONASTERISK) ;
        !           741: 
        !           742:    if (iReturn == IDCANCEL)
        !           743:       return (FALSE) ;
        !           744: 
        !           745:    if (iReturn == IDYES)
        !           746:       SaveChart (hWndGraphs, 0, 0) ;
        !           747:    return (TRUE) ;
        !           748: #endif
        !           749:    return (TRUE) ;  // we don't want to query nor save change
        !           750: 
        !           751:    }  // QuerySaveChart
        !           752: 
        !           753: void GraphAddAction ()
        !           754:    {
        !           755:    PGRAPHSTRUCT      pGraph ;
        !           756: 
        !           757:    pGraph = GraphData (hWndGraph) ;
        !           758: 
        !           759:    SizeGraphComponents (hWndGraph) ;
        !           760:    
        !           761:    LegendSetSelection (hWndGraphLegend,
        !           762:       LegendNumItems (hWndGraphLegend) - 1) ;
        !           763: 
        !           764:    if (PlayingBackLog ())
        !           765:       PlaybackChart (pGraph->hWnd) ;
        !           766:    }
        !           767: 
        !           768: BOOL OpenChartVer1 (HANDLE hFile,
        !           769:                     DISKCHART *pDiskChart,
        !           770:                     PGRAPHSTRUCT pGraph)
        !           771:    {  // OpenChartVer1
        !           772:    bDelayAddAction = TRUE ;
        !           773:    pGraph->Visual = pDiskChart->Visual ;
        !           774:    pGraph->gOptions = pDiskChart->gOptions ;
        !           775:    pGraph->gMaxValues = pDiskChart->gMaxValues ;
        !           776:    pGraph->bManualRefresh = pDiskChart->bManualRefresh ;
        !           777:    pGraphs->gInterval = (INT) (pGraph->gOptions.eTimeInterval * (FLOAT) 1000.0) ;
        !           778:    ReadLines (hFile, pDiskChart->dwNumLines,
        !           779:                &(pGraph->pSystemFirst), &(pGraph->pLineFirst), IDM_VIEWCHART) ;
        !           780:    
        !           781:    bDelayAddAction = FALSE ;
        !           782: 
        !           783:    GraphAddAction () ;
        !           784: 
        !           785:    return (TRUE) ;
        !           786:    }  // OpenChartVer1
        !           787: 
        !           788: 
        !           789: 
        !           790: BOOL OpenChart (HWND hWndGraph,
        !           791:                 HANDLE hFile,
        !           792:                 DWORD dwMajorVersion,
        !           793:                 DWORD dwMinorVersion,
        !           794:                 BOOL bChartFile)
        !           795:    {  // OpenChart
        !           796:    PGRAPHSTRUCT   pGraph ;
        !           797:    DISKCHART      DiskChart ;
        !           798:    BOOL           bSuccess = TRUE ;
        !           799: 
        !           800:    pGraph = pGraphs ;
        !           801:    if (!pGraph)
        !           802:       {
        !           803:       bSuccess = FALSE ;
        !           804:       goto Exit0 ;
        !           805:       }
        !           806: 
        !           807:    if (!FileRead (hFile, &DiskChart, sizeof (DISKCHART)))
        !           808:       {
        !           809:       bSuccess = FALSE ;
        !           810:       goto Exit0 ;
        !           811:       }
        !           812: 
        !           813: 
        !           814:    switch (dwMajorVersion)
        !           815:       {
        !           816:       case (1):
        !           817: 
        !           818:          SetHourglassCursor() ;
        !           819:          
        !           820:          ResetGraphView (hWndGraph) ;
        !           821: 
        !           822:          OpenChartVer1 (hFile, &DiskChart, pGraph) ;
        !           823: 
        !           824:          // change to chart view if we are opening a 
        !           825:          // chart file
        !           826:          if (bChartFile && iPerfmonView != IDM_VIEWCHART)
        !           827:             {
        !           828:             SendMessage (hWndMain, WM_COMMAND, (LONG)IDM_VIEWCHART, 0L) ;
        !           829:             }
        !           830: 
        !           831:          if (iPerfmonView == IDM_VIEWCHART)
        !           832:             {
        !           833:             SetPerfmonOptions (&DiskChart.perfmonOptions) ;
        !           834:             }
        !           835:          
        !           836:          SetArrowCursor() ;
        !           837: 
        !           838:          break ;
        !           839:       }  // switch
        !           840: 
        !           841: Exit0:
        !           842: 
        !           843:    if (bChartFile)
        !           844:       {
        !           845:       CloseHandle (hFile) ;
        !           846:       }
        !           847: 
        !           848:    return (bSuccess) ;
        !           849:    }  // OpenChart
        !           850: 
        !           851: BOOL SaveChart (HWND hWndGraph, HANDLE hInputFile, BOOL bGetFileName)
        !           852:    {
        !           853:    PGRAPHSTRUCT   pGraph ;
        !           854:    PLINE          pLine ;
        !           855:    HANDLE         hFile ;
        !           856:    DISKCHART      DiskChart ;
        !           857:    PERFFILEHEADER FileHeader ;
        !           858:    TCHAR          szFileName [256] ;
        !           859:    BOOL           newFileName = FALSE ;
        !           860: 
        !           861:    if (hInputFile)
        !           862:       {
        !           863:       // use the input file handle if it is available
        !           864:       // this is the case for saving workspace data
        !           865:       hFile = hInputFile ;
        !           866:       }
        !           867:    else
        !           868:       {
        !           869:       if (pChartFullFileName)
        !           870:          {
        !           871:          lstrcpy (szFileName, pChartFullFileName) ;
        !           872:          }
        !           873:       if (bGetFileName || pChartFullFileName == NULL)
        !           874:          {
        !           875: //         if (!pChartFullFileName)
        !           876: //            {
        !           877: //            StringLoad (IDS_GRAPH_FNAME, szFileName) ;
        !           878: //            }
        !           879: 
        !           880:          if (!FileGetName (hWndGraph, IDS_CHARTFILE, szFileName))
        !           881:             {
        !           882:             return (FALSE) ;
        !           883:             }
        !           884:          newFileName = TRUE ;
        !           885:          }
        !           886: 
        !           887:       hFile = FileHandleCreate (szFileName) ;
        !           888: 
        !           889:       if (hFile && newFileName)
        !           890:          {
        !           891:          ChangeSaveFileName (szFileName, IDM_VIEWCHART) ;
        !           892:          }
        !           893:       else if (!hFile)
        !           894:          {
        !           895:          DlgErrorBox (hWndGraph, ERR_CANT_OPEN, szFileName) ;
        !           896:          }
        !           897:       }
        !           898: 
        !           899:    if (!hFile)
        !           900:       return (FALSE) ;
        !           901: 
        !           902:    pGraph = pGraphs ;
        !           903:    if (!pGraph)
        !           904:       {
        !           905:       if (!hInputFile)
        !           906:          {
        !           907:          CloseHandle (hFile) ;
        !           908:          }
        !           909:       return (FALSE) ;
        !           910:       }
        !           911: 
        !           912:    if (!hInputFile)
        !           913:       {
        !           914:       // only need to write file header if not workspace 
        !           915:       memset (&FileHeader, 0, sizeof (FileHeader)) ;
        !           916:       lstrcpy (FileHeader.szSignature, szPerfChartSignature) ;
        !           917:       FileHeader.dwMajorVersion = ChartMajorVersion ;
        !           918:       FileHeader.dwMinorVersion = ChartMinorVersion ;
        !           919:    
        !           920:       if (!FileWrite (hFile, &FileHeader, sizeof (PERFFILEHEADER)))
        !           921:          {
        !           922:          goto Exit0 ;
        !           923:          }
        !           924:       }
        !           925: 
        !           926:    DiskChart.Visual = pGraph->Visual ;
        !           927:    DiskChart.gOptions = pGraph->gOptions ;
        !           928:    DiskChart.gMaxValues = pGraph->gMaxValues ;
        !           929:    DiskChart.dwNumLines = NumLines (pGraph->pLineFirst) ;
        !           930:    DiskChart.bManualRefresh = pGraph->bManualRefresh ;
        !           931:    DiskChart.perfmonOptions = Options ;
        !           932: 
        !           933:    if (!FileWrite (hFile, &DiskChart, sizeof (DISKCHART)))
        !           934:       {
        !           935:       goto Exit0 ;
        !           936:       }
        !           937: 
        !           938:    for (pLine = pGraph->pLineFirst ;
        !           939:         pLine ;
        !           940:         pLine = pLine->pLineNext)
        !           941:       {  // for
        !           942:       if (!WriteLine (pLine, hFile))
        !           943:          {
        !           944:          goto Exit0 ;
        !           945:          }
        !           946:       }  // for
        !           947: 
        !           948:    if (!hInputFile)
        !           949:       {
        !           950:       CloseHandle (hFile) ;
        !           951:       }
        !           952: 
        !           953:    return (TRUE) ;
        !           954: 
        !           955: Exit0:
        !           956:    if (!hInputFile)
        !           957:       {
        !           958:       CloseHandle (hFile) ;
        !           959: 
        !           960:       // only need to report error if not workspace 
        !           961:       DlgErrorBox (hWndGraph, ERR_SETTING_FILE, szFileName) ;
        !           962:       }
        !           963:    return (FALSE) ;
        !           964: 
        !           965:    }  // SaveChart
        !           966: 
        !           967: #define TIME_TO_WRITE 6
        !           968: BOOL ExportChartLabels (HANDLE hFile, PGRAPHSTRUCT pGraph)
        !           969: {
        !           970:    TCHAR          UnicodeBuff [MiscTextLen] ;
        !           971:    CHAR           TempBuff [LongTextLen] ;
        !           972:    int            StringLen ;
        !           973:    PLINESTRUCT    pLine;
        !           974:    int            TimeToWriteFile ;
        !           975:    int            iIndex ;
        !           976:    LPTSTR         lpItem ;
        !           977: 
        !           978:    for (iIndex = 0 ; iIndex < 5 ; iIndex++)
        !           979:       {
        !           980:       // for iIndex == 0, get counter name 
        !           981:       // for iIndex == 1, get instance name
        !           982:       // for iIndex == 2, get parent name
        !           983:       // for iIndex == 3, get object name 
        !           984:       // for iIndex == 4, get computer name
        !           985:       if (iIndex == 4)
        !           986:          {
        !           987:          // the last label field, write date/time labels
        !           988:          strcpy (TempBuff, LineEndStr) ;
        !           989:          StringLen = strlen (TempBuff) ;
        !           990:          StringLoad (IDS_EXPORT_DATE, UnicodeBuff) ;
        !           991:          ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
        !           992:          strcat (TempBuff, pDelimiter) ;
        !           993:          StringLen = strlen (TempBuff) ;
        !           994:       
        !           995:          StringLoad (IDS_EXPORT_TIME, UnicodeBuff) ;
        !           996:          ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
        !           997:          strcat (TempBuff, pDelimiter) ;
        !           998:          StringLen = strlen (TempBuff) ;
        !           999:          }
        !          1000:       else
        !          1001:          {
        !          1002:          strcpy (TempBuff, LineEndStr) ;
        !          1003:          strcat (TempBuff, pDelimiter) ;
        !          1004:          strcat (TempBuff, pDelimiter) ;
        !          1005:          StringLen = strlen (TempBuff) ;
        !          1006:          }
        !          1007: 
        !          1008:       TimeToWriteFile = 0 ;
        !          1009: 
        !          1010:       for (pLine=pGraph->pLineFirst; pLine; pLine=pLine->pLineNext)
        !          1011:          {
        !          1012:          switch (iIndex)
        !          1013:             {
        !          1014:             case 0:
        !          1015:                lpItem = (LPTSTR) pLine->lnCounterName ;
        !          1016:                break ;
        !          1017: 
        !          1018:             case 1:
        !          1019:                lpItem = (LPTSTR) pLine->lnInstanceName ;
        !          1020:                break ;
        !          1021: 
        !          1022:             case 2:
        !          1023:                lpItem = (LPTSTR) pLine->lnPINName ;
        !          1024:                break ;
        !          1025: 
        !          1026:             case 3:
        !          1027:                lpItem = (LPTSTR) pLine->lnObjectName ;
        !          1028:                break ;
        !          1029: 
        !          1030:             case 4:
        !          1031:                lpItem = (LPTSTR) pLine->lnSystemName ;
        !          1032:                break ;
        !          1033:             }
        !          1034: 
        !          1035:          if (lpItem)
        !          1036:             {
        !          1037:             ConvertUnicodeStr (&TempBuff[StringLen], lpItem) ;
        !          1038:             }
        !          1039:          else
        !          1040:             {
        !          1041:             TempBuff[StringLen] = '\0' ;
        !          1042:             }
        !          1043:          strcat (TempBuff, pDelimiter);
        !          1044:          StringLen = strlen (TempBuff) ;
        !          1045:    
        !          1046:          if (++TimeToWriteFile > TIME_TO_WRITE)
        !          1047:             {
        !          1048:             // better write the buffers before they overflow.
        !          1049:             // there are better ways to check for overflow 
        !          1050:             // but this is good enough
        !          1051:    
        !          1052:             if (!FileWrite (hFile, TempBuff, StringLen))
        !          1053:                {
        !          1054:                goto Exit0 ;
        !          1055:                }
        !          1056:             StringLen = TimeToWriteFile = 0 ;
        !          1057:             }
        !          1058:          }     // for each line
        !          1059: 
        !          1060:       if (StringLen)
        !          1061:          {
        !          1062:          // write the last block of data
        !          1063:          if (!FileWrite (hFile, TempBuff, StringLen))
        !          1064:             {
        !          1065:             goto Exit0 ;
        !          1066:             }
        !          1067:          }
        !          1068:       }     // for iIndex
        !          1069: 
        !          1070:    return (TRUE) ;
        !          1071: 
        !          1072: Exit0:
        !          1073:    return (FALSE) ;
        !          1074: 
        !          1075: }  // ExportChartLabels
        !          1076: 
        !          1077: BOOL ExportLogChart (HANDLE hFile, PGRAPHSTRUCT pGraph)
        !          1078: {
        !          1079:    TCHAR          UnicodeBuff [MiscTextLen] ;
        !          1080:    CHAR           TempBuff [LongTextLen] ;
        !          1081:    int            StringLen ;
        !          1082:    PLINESTRUCT    pLine;
        !          1083:    int            TimeToWriteFile ;
        !          1084:    FLOAT          eValue ;
        !          1085:    int            iLogTic ;
        !          1086:    BOOL           bFirstTime = TRUE ;
        !          1087:    SYSTEMTIME     LogSystemTime ;
        !          1088:    LOGPOSITION    LogPosition ;
        !          1089: 
        !          1090:    iLogTic = PlaybackLog.StartIndexPos.iPosition ;
        !          1091: 
        !          1092:    // we have to export every point from the log file 
        !          1093: 
        !          1094:    for ( ; iLogTic <= PlaybackLog.StopIndexPos.iPosition ; iLogTic++)
        !          1095:       {
        !          1096: 
        !          1097:       PlaybackLines (pGraphs->pSystemFirst, 
        !          1098:                      pGraphs->pLineFirst, 
        !          1099:                      iLogTic) ;
        !          1100: 
        !          1101:       if (!bFirstTime)
        !          1102:          {
        !          1103:          // export the values
        !          1104:          TimeToWriteFile = 0 ;
        !          1105: 
        !          1106:          
        !          1107:          if (!LogPositionN (iLogTic, &LogPosition))
        !          1108:             {
        !          1109:             goto Exit0 ;
        !          1110:             }
        !          1111: 
        !          1112:          LogPositionSystemTime (&LogPosition, &LogSystemTime) ;
        !          1113: 
        !          1114:          strcpy (TempBuff, LineEndStr) ;
        !          1115:          StringLen = strlen (TempBuff) ;
        !          1116: 
        !          1117:          SystemTimeDateString (&LogSystemTime, UnicodeBuff) ;
        !          1118:          ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
        !          1119:          strcat (TempBuff, pDelimiter) ;
        !          1120:          StringLen = strlen (TempBuff) ;
        !          1121: 
        !          1122:          SystemTimeTimeString (&LogSystemTime, UnicodeBuff) ;
        !          1123:          ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
        !          1124:          strcat (TempBuff, pDelimiter) ;
        !          1125:          StringLen = strlen (TempBuff) ;
        !          1126: 
        !          1127:          for (pLine=pGraph->pLineFirst; pLine; pLine=pLine->pLineNext)
        !          1128:             {
        !          1129:       
        !          1130:             eValue = (*(pLine->valNext))(pLine) ;
        !          1131: 
        !          1132:             TSPRINTF (UnicodeBuff,
        !          1133:                       eValue > (FLOAT)999999.0 ?
        !          1134:                            szLargeValueFormat : szSmallValueFormat,
        !          1135:                       eValue) ;
        !          1136:             ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
        !          1137:             strcat (TempBuff, pDelimiter) ;
        !          1138:             StringLen = strlen (TempBuff) ;
        !          1139: 
        !          1140:             if (++TimeToWriteFile > TIME_TO_WRITE)
        !          1141:                {
        !          1142:                if (!FileWrite (hFile, TempBuff, StringLen))
        !          1143:                   {
        !          1144:                   goto Exit0 ;
        !          1145:                   }
        !          1146:                StringLen = TimeToWriteFile = 0 ;
        !          1147:                TempBuff[0] = '\0' ;
        !          1148:                }
        !          1149:             }
        !          1150: 
        !          1151:          if (StringLen)
        !          1152:             {
        !          1153:             if (!FileWrite (hFile, TempBuff, StringLen))
        !          1154:                {
        !          1155:                goto Exit0 ;
        !          1156:                }
        !          1157:             }
        !          1158:          }
        !          1159:       else
        !          1160:          {
        !          1161:          // skip the first data point since we
        !          1162:          // need 2 points to form the first value
        !          1163:          bFirstTime = FALSE ;
        !          1164:          }
        !          1165:       }
        !          1166: 
        !          1167:    return (TRUE) ;
        !          1168: 
        !          1169: Exit0:
        !          1170:    return (FALSE) ;
        !          1171: 
        !          1172: }  // ExportLogChart
        !          1173: 
        !          1174: BOOL ExportLineValue (HANDLE hFile, PGRAPHSTRUCT pGraph,
        !          1175:    int CurrentIndex, int iDataPoint)
        !          1176: {
        !          1177:    TCHAR          UnicodeBuff [MiscTextLen] ;
        !          1178:    CHAR           TempBuff [LongTextLen] ;
        !          1179:    int            StringLen ;
        !          1180:    PLINESTRUCT    pLine;
        !          1181:    int            MaxValues ;
        !          1182:    int            TimeToWriteFile ;
        !          1183:    SYSTEMTIME     *pSystemTime ;
        !          1184:    BOOL           ValidValue ;
        !          1185: 
        !          1186:    pSystemTime = pGraph->pDataTime ;
        !          1187:    pSystemTime += CurrentIndex ;
        !          1188: 
        !          1189:    if (pSystemTime->wYear == 0 && pSystemTime->wYear == 0)
        !          1190:       {
        !          1191:       // ignore value that has 0 system time
        !          1192:       return (TRUE) ;
        !          1193:       }
        !          1194: 
        !          1195:    MaxValues = pGraph->gMaxValues ;
        !          1196:    strcpy (TempBuff, LineEndStr) ;
        !          1197:    StringLen = strlen (TempBuff) ;
        !          1198: 
        !          1199:    SystemTimeDateString (pSystemTime, UnicodeBuff) ;
        !          1200:    ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
        !          1201:    strcat (TempBuff, pDelimiter) ;
        !          1202:    StringLen = strlen (TempBuff) ;
        !          1203: 
        !          1204:    SystemTimeTimeString (pSystemTime, UnicodeBuff) ;
        !          1205:    ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
        !          1206:    strcat (TempBuff, pDelimiter) ;
        !          1207:    StringLen = strlen (TempBuff) ;
        !          1208: 
        !          1209:    TimeToWriteFile = 0 ;
        !          1210:    for (pLine=pGraph->pLineFirst; pLine; pLine=pLine->pLineNext)
        !          1211:       {
        !          1212:       if (!pLine->bFirstTime)
        !          1213:          {
        !          1214:          ValidValue = FALSE ;
        !          1215:          // check if this is a valid value
        !          1216:          if (pLine->lnValidValues == MaxValues)
        !          1217:             {
        !          1218:             // this is the simple case where we have filled up 
        !          1219:             // the whole buffer
        !          1220:             ValidValue = TRUE ;
        !          1221:             }
        !          1222:          else if (pLine->lnValidValues <= iDataPoint)
        !          1223:             {
        !          1224:             if (CurrentIndex <= iDataPoint &&
        !          1225:                CurrentIndex > iDataPoint - pLine->lnValidValues)
        !          1226:                {
        !          1227:                ValidValue = TRUE ;
        !          1228:                }
        !          1229:             }
        !          1230:          else
        !          1231:             {
        !          1232:             if (CurrentIndex <= iDataPoint ||
        !          1233:                CurrentIndex > (MaxValues - pLine->lnValidValues + iDataPoint))
        !          1234:                {
        !          1235:                // this is the case when we start the new line in the middle
        !          1236:                // and data buffer has been wrap-around.
        !          1237:                ValidValue = TRUE ;
        !          1238:                }
        !          1239:             }
        !          1240: 
        !          1241:          // only export the data when we determine it is valid
        !          1242:          if (ValidValue)
        !          1243:             {
        !          1244:             TSPRINTF (UnicodeBuff,
        !          1245:                pLine->lnValues[CurrentIndex] > (FLOAT)999999.0 ?
        !          1246:                szLargeValueFormat : szSmallValueFormat,
        !          1247:                pLine->lnValues[CurrentIndex]) ;
        !          1248:             ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
        !          1249:             }
        !          1250:          }
        !          1251:       strcat (TempBuff, pDelimiter) ;
        !          1252:       StringLen = strlen (TempBuff) ;
        !          1253: 
        !          1254:       if (++TimeToWriteFile > TIME_TO_WRITE)
        !          1255:          {
        !          1256:          // better write the buffers before they overflow.
        !          1257:          // there are better ways to check for overflow 
        !          1258:          // but this is good enough
        !          1259:    
        !          1260:          if (!FileWrite (hFile, TempBuff, StringLen))
        !          1261:             {
        !          1262:             goto Exit0 ;
        !          1263:             }
        !          1264:          StringLen = TimeToWriteFile = 0 ;
        !          1265:          TempBuff[0] = '\0' ;
        !          1266:          }
        !          1267:       }
        !          1268: 
        !          1269:    if (StringLen)
        !          1270:       {
        !          1271:       // write the last block of data
        !          1272:       if (!FileWrite (hFile, TempBuff, StringLen))
        !          1273:          {
        !          1274:          goto Exit0 ;
        !          1275:          }
        !          1276:       }
        !          1277: 
        !          1278:    return (TRUE) ;
        !          1279: 
        !          1280: Exit0:
        !          1281:    return (FALSE) ;
        !          1282: 
        !          1283: }     // ExportLineValue
        !          1284: 
        !          1285: BOOL ExportCurrentChart (HANDLE hFile, PGRAPHSTRUCT pGraph)
        !          1286: {
        !          1287:    int            KnownValue,
        !          1288:                   MaxValues,
        !          1289:                   iValidValues,
        !          1290:                   iDataPoint ;
        !          1291:    BOOL           SimpleCase = FALSE ;
        !          1292:    int            iIndex ;
        !          1293: 
        !          1294:    MaxValues = pGraph->gMaxValues ;
        !          1295:    KnownValue = pGraph->gKnownValue ;
        !          1296:    iValidValues = pGraph->gTimeLine.iValidValues ;
        !          1297: 
        !          1298:    if (iValidValues < MaxValues)
        !          1299:       {
        !          1300:       // data have not wrapped around, so the oldest time
        !          1301:       // is started at 0.
        !          1302:       SimpleCase = TRUE ;
        !          1303:       iValidValues = (KnownValue % MaxValues) + 1 ;
        !          1304:       }
        !          1305: 
        !          1306:    iDataPoint = KnownValue % MaxValues ;
        !          1307: 
        !          1308:    if (!SimpleCase)
        !          1309:       {
        !          1310:       for (iIndex = iDataPoint+1 ; iIndex < MaxValues ; iIndex++)
        !          1311:          {
        !          1312:          if (!ExportLineValue (hFile, pGraph, iIndex, iDataPoint))
        !          1313:             {
        !          1314:             goto Exit0 ;
        !          1315:             }
        !          1316:          }
        !          1317:       }
        !          1318: 
        !          1319:    for (iIndex = 0 ; iIndex <= iDataPoint ; iIndex++)
        !          1320:       {
        !          1321:       if (!ExportLineValue (hFile, pGraph, iIndex, iDataPoint))
        !          1322:          {
        !          1323:          goto Exit0 ;
        !          1324:          }
        !          1325:       }
        !          1326: 
        !          1327:    return (TRUE) ;
        !          1328: 
        !          1329: Exit0:
        !          1330:    return (FALSE) ;
        !          1331: 
        !          1332: }  // ExportCurrentChart
        !          1333: 
        !          1334: 
        !          1335: void ExportChart (void)
        !          1336: {
        !          1337: 
        !          1338:    PGRAPHSTRUCT   pGraph ;
        !          1339:    HANDLE         hFile = 0 ;
        !          1340:    LPTSTR         pFileName = NULL ;
        !          1341:    INT            ErrCode = 0 ;
        !          1342: 
        !          1343:    if (!(pGraph = pGraphs))
        !          1344:       {
        !          1345:       return ;
        !          1346:       }
        !          1347: 
        !          1348:    // see if there is anything to export..
        !          1349:    if (!(pGraph->pLineFirst))
        !          1350:       {
        !          1351:       return ;
        !          1352:       }
        !          1353: 
        !          1354:    SetHourglassCursor() ;
        !          1355:    
        !          1356:    if (ErrCode = ExportFileOpen (hWndGraph, &hFile, pGraph->gInterval, &pFileName))
        !          1357:       {
        !          1358:       goto Exit0 ;
        !          1359:       }
        !          1360: 
        !          1361:    if (!pFileName)
        !          1362:       {
        !          1363:       // this is the case when user cancel.
        !          1364:       goto Exit0 ;
        !          1365:       }
        !          1366: 
        !          1367:    // export the column labels
        !          1368:    if (!ExportChartLabels (hFile, pGraph))
        !          1369:       {
        !          1370:    
        !          1371:       ErrCode = ERR_EXPORT_FILE ;
        !          1372:       goto Exit0 ;
        !          1373:       }
        !          1374: 
        !          1375:    // export the lines
        !          1376:    if (PlayingBackLog())
        !          1377:       {
        !          1378:       if (!ExportLogChart (hFile, pGraph))
        !          1379:          {
        !          1380:          ErrCode = ERR_EXPORT_FILE ;
        !          1381:          goto Exit0 ;
        !          1382:          }
        !          1383:       }
        !          1384:    else
        !          1385:       {
        !          1386:       if (!ExportCurrentChart (hFile, pGraph))
        !          1387:          {
        !          1388:          ErrCode = ERR_EXPORT_FILE ;
        !          1389:          goto Exit0 ;
        !          1390:          }
        !          1391:       }
        !          1392: Exit0:
        !          1393: 
        !          1394:    SetArrowCursor() ;
        !          1395: 
        !          1396:    if (hFile)
        !          1397:       {
        !          1398:       CloseHandle (hFile) ;
        !          1399:       }
        !          1400: 
        !          1401:    if (pFileName)
        !          1402:       {
        !          1403:       if (ErrCode)
        !          1404:          {
        !          1405:          DlgErrorBox (hWndGraph, ErrCode, pFileName) ;
        !          1406:          }
        !          1407: 
        !          1408:       MemoryFree (pFileName) ;
        !          1409:       }
        !          1410: 
        !          1411: }     // ExportChart
        !          1412: 
        !          1413: 
        !          1414: typedef struct CHARTDATAPOINTSTRUCT
        !          1415:    {
        !          1416:    int         iLogIndex ;
        !          1417:    int         xDispDataPoint ;
        !          1418:    } CHARTDATAPOINT, *PCHARTDATAPOINT ;
        !          1419: 
        !          1420: void PlaybackChartDataPoint (PCHARTDATAPOINT pChartDataPoint)
        !          1421:    {  // PlaybackChartDataPoint
        !          1422:    int            iDisplayTics ;       // num visual points to display
        !          1423:    int            iDisplayTic ;
        !          1424:    int            iLogTic ;
        !          1425:    int            iLogTicsMove ;
        !          1426:    BOOL           bFirstTime = TRUE;
        !          1427:    int            iLogTicsRemaining ;
        !          1428:    int            numOfData, xDispDataPoint, rectWidth, xPos ;
        !          1429:    PGRAPHSTRUCT   pGraph ;
        !          1430: 
        !          1431:    pGraph = GraphData (hWndGraph) ;
        !          1432: 
        !          1433:    iLogTicsRemaining = PlaybackLog.iSelectedTics ;
        !          1434: 
        !          1435: 
        !          1436:    // we only have iDisplayTics-1 points since
        !          1437:    // we have to use the first two sample points to
        !          1438:    // get the first data points.
        !          1439:    if (iLogTicsRemaining <= pGraphs->gMaxValues)
        !          1440:       {
        !          1441:       iDisplayTics = iLogTicsRemaining ;
        !          1442:       }
        !          1443:    else
        !          1444:       {
        !          1445:       iDisplayTics = pGraphs->gMaxValues ;
        !          1446:       }
        !          1447: 
        !          1448:    iDisplayTic = -1 ;
        !          1449:    iLogTic = PlaybackLog.StartIndexPos.iPosition ;
        !          1450: 
        !          1451:    numOfData      = pGraph->gMaxValues - 1 ;
        !          1452:    rectWidth      = pGraph->rectData.right - pGraph->rectData.left ;
        !          1453:    xDispDataPoint = pGraph->rectData.left ;
        !          1454: 
        !          1455:    while (iDisplayTics && numOfData)
        !          1456:       {
        !          1457: 
        !          1458:       if (!bFirstTime)
        !          1459:          {
        !          1460:          iDisplayTic++ ;
        !          1461:          }
        !          1462:       else
        !          1463:          {
        !          1464:          bFirstTime = FALSE ;
        !          1465: 
        !          1466:          // get the second sample data to form the first data point
        !          1467:          iLogTic++ ;
        !          1468:          iLogTicsRemaining-- ;
        !          1469: 
        !          1470:          iDisplayTic++ ;
        !          1471:          }
        !          1472: 
        !          1473:       pChartDataPoint[iDisplayTic].iLogIndex = iLogTic ;
        !          1474:       pChartDataPoint[iDisplayTic].xDispDataPoint = xDispDataPoint ;
        !          1475: 
        !          1476:       // setup DDA to get the index of the next sample point
        !          1477:       iLogTicsMove = DDA_DISTRIBUTE (iLogTicsRemaining, iDisplayTics) ;
        !          1478:       iLogTicsRemaining -= iLogTicsMove ;
        !          1479:       iLogTic += iLogTicsMove ;
        !          1480: 
        !          1481: 
        !          1482:       xPos = DDA_DISTRIBUTE (rectWidth, numOfData) ;
        !          1483:       xDispDataPoint += xPos ;
        !          1484:       numOfData-- ;
        !          1485:       rectWidth -= xPos ;
        !          1486: 
        !          1487:       iDisplayTics-- ;
        !          1488: 
        !          1489:       }  // while
        !          1490: 
        !          1491:    }  // PlaybackChartDataPoint
        !          1492: 
        !          1493: 
        !          1494: BOOL
        !          1495: BuildNewValueListForGraph (
        !          1496: )
        !          1497: {
        !          1498:     PGRAPHSTRUCT    pGraph;
        !          1499: 
        !          1500:     pGraph = pGraphs;   // set local pointer to global pointer
        !          1501:     
        !          1502:     return BuildValueListForSystems (
        !          1503:         pGraphs->pSystemFirst,
        !          1504:         pGraphs->pLineFirst);
        !          1505: 
        !          1506: }
        !          1507: 

unix.superglobalmegacorp.com

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