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

1.1     ! root        1: //==========================================================================//
        !             2: //                                  Includes                                //
        !             3: //==========================================================================//
        !             4: 
        !             5: 
        !             6: #include <stdio.h>
        !             7: #include "perfmon.h"
        !             8: #include "grafdisp.h"      // external declarations for this file
        !             9: 
        !            10: #include "grafdata.h"      // for InsertGraph, et al.
        !            11: #include "graph.h"
        !            12: #include "legend.h"
        !            13: #include "line.h"          // for LineCreatePen
        !            14: #include "perfmops.h"      // for DoWindowDrag
        !            15: #include "playback.h"      // for PlayingBackLog
        !            16: #include "valuebar.h"
        !            17: #include "utils.h"
        !            18: #include "timeline.h"      // for IsTLineWindowUp & TLineRedraw 
        !            19: 
        !            20: //==========================================================================//
        !            21: //                                  Constants                               //
        !            22: //==========================================================================//
        !            23: 
        !            24: // this macro is used in doing a simple DDA (Digital Differential Analyzer)
        !            25: // * 10 + 5 is to make the result round up with .5
        !            26: #define DDA_DISTRIBUTE(TotalTics, numOfData) \
        !            27:    ((TotalTics * 10 / numOfData) + 5) / 10
        !            28: 
        !            29: HDC   hGraphDisplayDC ;
        !            30: //=============================//
        !            31: // GraphDisplay Class          //
        !            32: //=============================//
        !            33: 
        !            34: 
        !            35: TCHAR   szGraphDisplayWindowClass[] = TEXT("PerfmonGraphDisplayClass") ;
        !            36: #define dwGraphDisplayClassStyle    (CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC)
        !            37: #define iGraphDisplayClassExtra     (0)
        !            38: #define iGraphDisplayWindowExtra    (0)
        !            39: #define dwGraphDisplayWindowStyle   (WS_CHILD | WS_VISIBLE)
        !            40: 
        !            41: 
        !            42: 
        !            43: //==========================================================================//
        !            44: //                              Local Functions                             //
        !            45: //==========================================================================//
        !            46: BOOL UpdateTimeLine (HDC hDC, PGRAPHSTRUCT pGraph, BOOL getLastTimeLocation) ;
        !            47: 
        !            48: #if 0
        !            49: PGRAPHSTRUCT GraphData (HWND hWndGraphDisplay)
        !            50: /*
        !            51:    Effect:        Return the graph associated with graph display window
        !            52:                   hWndGraphData. At the present time, we only have one
        !            53:                   graph data window and one graph structure. In the
        !            54:                   future, we may have several of each. The graph structure
        !            55:                   is conceptually instance data of the graph display
        !            56:                   window. Use of this function allows for easier additions
        !            57:                   to the code.
        !            58: */
        !            59:    {
        !            60:    return (pGraphs) ;
        !            61:    }
        !            62: #endif
        !            63: 
        !            64: INT ScaleAndInvertY (FLOAT ey, 
        !            65:                      PLINESTRUCT pLineStruct,
        !            66:                      PGRAPHSTRUCT pGraph)
        !            67: /*
        !            68:    Effect:        Given data value ey, scale and fit the value to fit
        !            69:                   within the graph data area of the window, considering
        !            70:                   the scale set for the line and the current size of the
        !            71:                   data rectangle.
        !            72: */   
        !            73:    {  // ScaleAndInvertY
        !            74:    INT     yGraphDataHeight,               // Height of graph area
        !            75:            yInverted ;                     // Scaled & Inverted Y.
        !            76:    FLOAT   eppd,
        !            77:            eyScaled ;
        !            78: 
        !            79: 
        !            80:    // Take care of any scaling now, at output time.
        !            81:    ey *= pLineStruct->eScale ;
        !            82: 
        !            83:    // Calculate the Cy of the graph area.
        !            84:    yGraphDataHeight = pGraph->rectData.bottom - pGraph->rectData.top ;
        !            85: 
        !            86:    // Calculate the pixels per data point.
        !            87:    eppd = (FLOAT) ((FLOAT) yGraphDataHeight / (FLOAT) pGraph->gOptions.iVertMax) ;
        !            88:    eyScaled = eppd * ey ;
        !            89:    yInverted = (INT) (((FLOAT) yGraphDataHeight) - eyScaled) ;
        !            90: 
        !            91:    yInverted += pGraph->rectData.top ;
        !            92:    
        !            93:    // Clamp the range to fit with in the graph portion of the windows
        !            94:    yInverted = PinInclusive (yInverted, 
        !            95:                              pGraph->rectData.top, pGraph->rectData.bottom) ;
        !            96:    return (yInverted) ;
        !            97:    }  // ScaleAndInvertY
        !            98: 
        !            99: 
        !           100: 
        !           101: BOOL DrawGrid (HDC hDC, 
        !           102:                PGRAPHSTRUCT pGraph,
        !           103:                LPRECT lpRect,
        !           104:                BOOL bForPaint)
        !           105: /*
        !           106:    Effect:        Draw the grid lines in the graph display window.
        !           107:                   These grid lines are in the graph data area only,
        !           108:                   which is indicated by pGraph->rectData.
        !           109: 
        !           110:    Called By:     OnPaint only.
        !           111: */
        !           112:    {  // DrawGrid
        !           113:    int            iGrid, iLines ;
        !           114:    int            xGrid, yGrid ;
        !           115:    POINT          aPoints [4 * iGraphMaxTics] ;
        !           116:    DWORD          aCounts [2 * iGraphMaxTics] ;
        !           117:    HPEN           hPenPrevious ;
        !           118:    int            bottomAdjust ;
        !           119: 
        !           120:    if (!pGraph->gOptions.bHorzGridChecked && 
        !           121:        !pGraph->gOptions.bVertGridChecked)   
        !           122:       return (FALSE) ;
        !           123: 
        !           124: 
        !           125:    hPenPrevious = SelectPen (hDC, IsPrinterDC (hDC) ?
        !           126:       GetStockObject (BLACK_PEN) : pGraph->hGridPen) ;
        !           127: 
        !           128:    iLines = 0 ;
        !           129: 
        !           130:    if (pGraph->gOptions.bHorzGridChecked)
        !           131:       {
        !           132:       for (iGrid = 1 ;
        !           133:            iGrid < pGraph->yNumTics ;
        !           134:            iGrid++)
        !           135:          {  // for
        !           136:          yGrid = pGraph->ayTics[iGrid] + pGraph->rectData.top ;
        !           137:          if (yGrid >= lpRect->top &&
        !           138:              yGrid <= lpRect->bottom)
        !           139:             {  // if
        !           140:             aPoints[2 * iLines].x = lpRect->left ;
        !           141:             aPoints[2 * iLines].y = yGrid ;
        !           142:             aPoints[2 * iLines + 1].x = lpRect->right ;
        !           143:             aPoints[2 * iLines + 1].y = yGrid ;
        !           144: 
        !           145:             aCounts[iLines] = 2 ;
        !           146:             iLines++ ;
        !           147:             }  // if
        !           148:          }  // for
        !           149:       }  // if
        !           150: 
        !           151:    if (pGraph->gOptions.bVertGridChecked)
        !           152:       {
        !           153:       bottomAdjust = lpRect->bottom + (bForPaint ? 1 : 0) ;
        !           154:       for (iGrid = 1 ;
        !           155:            iGrid < pGraph->xNumTics ;
        !           156:            iGrid++)
        !           157:          {  // for
        !           158:          xGrid = pGraph->axTics[iGrid] + pGraph->rectData.left ;
        !           159:          if (xGrid >= lpRect->left &&
        !           160:              xGrid <= lpRect->right)
        !           161:             {  // if
        !           162:             aPoints[2 * iLines].x = xGrid ;
        !           163:             aPoints[2 * iLines].y = lpRect->top ;
        !           164:             aPoints[2 * iLines + 1].x = xGrid ;
        !           165:             aPoints[2 * iLines + 1].y = bottomAdjust ;
        !           166: 
        !           167:             aCounts[iLines] = 2 ;
        !           168:             iLines++ ;
        !           169:             }  // if
        !           170:          }  // for
        !           171:       }  // if
        !           172: 
        !           173:    if (iLines)
        !           174:       PolyPolyline (hDC, aPoints, aCounts, iLines) ;
        !           175: 
        !           176:    SelectPen (hDC, hPenPrevious) ;
        !           177: 
        !           178:    return (TRUE) ;
        !           179:    }  // DrawGrid
        !           180: 
        !           181: 
        !           182: 
        !           183: BOOL DrawBarChartData (HDC hDC, 
        !           184:                        PGRAPHSTRUCT pGraph)
        !           185:    {  // DrawBarChartData
        !           186:    PLINESTRUCT pLineStruct ;
        !           187:    PFLOAT      pDataPoints ;
        !           188:    INT         nLegendItems,
        !           189:                cx,
        !           190:                cxBar,
        !           191:                xDataPoint,
        !           192:                y ;
        !           193:    RECT        rectBar ;
        !           194:    RECT        rectBkgrnd ;
        !           195:    HBRUSH      hOldBrush ;
        !           196:    FLOAT       eValue ;
        !           197:    PLINESTRUCT pCurrentLine ;
        !           198: 
        !           199:    // Determine how many items are in the legend.
        !           200: 
        !           201:    nLegendItems = 0 ;
        !           202: 
        !           203:    for (pLineStruct = pGraph->pLineFirst ;
        !           204:         pLineStruct ;
        !           205:         pLineStruct = pLineStruct->pLineNext)
        !           206:       {  // for
        !           207:       nLegendItems++ ;
        !           208:       }  // for
        !           209: 
        !           210:    if (nLegendItems == 0)
        !           211:       return(FALSE) ;
        !           212: 
        !           213:    // get current select line for highlighting
        !           214:    if (pGraph->HighLightOnOff)
        !           215:       {
        !           216:       pCurrentLine = CurrentGraphLine (hWndGraph) ;
        !           217:       }
        !           218:    else
        !           219:       {
        !           220:       pCurrentLine = NULL ;
        !           221:       }
        !           222: 
        !           223:    // Determine the width of each bar.
        !           224:    cx = pGraph->rectData.right - pGraph->rectData.left ;
        !           225: 
        !           226: 
        !           227:    if (PlayingBackLog())
        !           228:       {
        !           229:       // get the average using the start and stop data point 
        !           230:       // from the log file
        !           231:       PlaybackLines (pGraph->pSystemFirst, 
        !           232:                      pGraph->pLineFirst, 
        !           233:                      PlaybackLog.StartIndexPos.iPosition) ;
        !           234:       PlaybackLines (pGraph->pSystemFirst, 
        !           235:                      pGraph->pLineFirst, 
        !           236:                      PlaybackLog.StopIndexPos.iPosition) ;
        !           237:       }
        !           238:    else
        !           239:       {
        !           240:       // Loop through all the DataLines and draw a bar for
        !           241:       // it's last value.
        !           242:       xDataPoint = pGraph->gKnownValue % pGraph->gMaxValues ;
        !           243:       }
        !           244: 
        !           245:    rectBar.bottom = pGraph->rectData.bottom + 1 ;
        !           246: 
        !           247:    rectBkgrnd = pGraph->rectData ;
        !           248: 
        !           249:    hOldBrush = SelectBrush (hDC, hBrushFace) ;
        !           250: 
        !           251:    PatBlt (hDC, 
        !           252:            rectBkgrnd.left, rectBkgrnd.top,
        !           253:            rectBkgrnd.right - rectBkgrnd.left,
        !           254:            rectBkgrnd.bottom - rectBkgrnd.top + 1,
        !           255:            PATCOPY) ;
        !           256:    DrawGrid(hDC, pGraph, &(rectBkgrnd), FALSE) ;
        !           257: 
        !           258:    rectBar.right = pGraph->rectData.left ;
        !           259:    for (pLineStruct = pGraph->pLineFirst ;
        !           260:         pLineStruct ;
        !           261:         pLineStruct = pLineStruct->pLineNext)
        !           262:       {  // for
        !           263:       pDataPoints = pLineStruct->lnValues ;
        !           264: 
        !           265:       if (PlayingBackLog())
        !           266:          {
        !           267:          eValue = (*(pLineStruct->valNext))(pLineStruct) ;
        !           268:          }
        !           269:       else
        !           270:          {
        !           271:          eValue = pDataPoints[xDataPoint] ;
        !           272:          }
        !           273: 
        !           274: 
        !           275:       y = ScaleAndInvertY (eValue,
        !           276:                            pLineStruct,
        !           277:                            pGraph) ;
        !           278: 
        !           279:       rectBar.left   = rectBar.right ;
        !           280:       rectBar.top    = y ;
        !           281: 
        !           282:       // nomore line to draw
        !           283:       if (nLegendItems == 0 )
        !           284:          {
        !           285:          break ;
        !           286:          }
        !           287: 
        !           288:       cxBar = DDA_DISTRIBUTE (cx, nLegendItems) ;
        !           289:       rectBar.right  = rectBar.left + cxBar ;
        !           290: 
        !           291:       // setup for next DDA
        !           292:       nLegendItems-- ;
        !           293:       cx -= cxBar ;
        !           294: 
        !           295:       // NOTE: this handle creation should be moved to line
        !           296:       //       create time.
        !           297: 
        !           298:       if (pCurrentLine == pLineStruct)
        !           299:          {
        !           300:          SetBkColor (hDC, crWhite) ;
        !           301:          }
        !           302:       else
        !           303:          {
        !           304:          SetBkColor (hDC, pLineStruct->Visual.crColor) ;
        !           305:          }
        !           306:        ExtTextOut (hDC, rectBar.right, rectBar.top, ETO_OPAQUE,
        !           307:          &rectBar, NULL, 0, NULL) ;
        !           308:       }  // for
        !           309: 
        !           310:    return (TRUE) ;
        !           311:    }
        !           312: 
        !           313: 
        !           314: /***************************************************************************
        !           315:  * DrawTLGraphData - Draw Time Line Graph Data.
        !           316:  *
        !           317:  *  Some notes about drawing the DataPoint graphs.
        !           318:  *
        !           319:  *      1]  It's real expensive to make a GDI call. So, we do not
        !           320:  *          make a MoveToEx and LineTo call for each point.  Instead
        !           321:  *          we create a polyline and send it down to GDI.
        !           322:  *
        !           323:  *      2]  The X coordinates for each point in the polyline is generated
        !           324:  *          from our favorite xDataPoint to xWindows DDA.
        !           325:  *
        !           326:  *      3]  The Y coordinate is generated from the pLineStruct->lnValues[x]
        !           327:  *          data associated with each line.
        !           328:  ***************************************************************************/
        !           329: BOOL DrawTLGraphData (HDC hDC, 
        !           330:                       BOOL bForPaint,
        !           331:                       PRECT prctPaint, 
        !           332:                       PGRAPHSTRUCT pGraph)
        !           333: /*
        !           334:    Called By:     UpdateGraphDisplay only. 
        !           335: */
        !           336:    {
        !           337:    PLINESTRUCT pLineStruct ;
        !           338:    HPEN        hPen = 0 ;
        !           339:    HPEN        hOldPen ;
        !           340:    PFLOAT      pDataPoints ;
        !           341:    INT         i, j,
        !           342:                iValidValues,
        !           343:                xDispDataPoint,
        !           344:                xLeftLimit,
        !           345:                xRightLimit ;
        !           346:    PPOINT      pptDataPoints ;
        !           347:    INT         numOfData, rectWidth, xPos ;
        !           348:    PLINESTRUCT pCurrentLine ;
        !           349:    INT         DrawZeroPoint = 0 ;
        !           350: 
        !           351: //   SetBkColor (hDC, crLightGray) ;
        !           352: 
        !           353:    if (!IsPrinterDC (hDC))
        !           354:       {
        !           355:       if (bForPaint)
        !           356:          {
        !           357:          IntersectClipRect (hDC, 
        !           358:                             pGraph->rectData.left,
        !           359:                             pGraph->rectData.top,
        !           360:                             pGraph->rectData.right,
        !           361:                             pGraph->rectData.bottom + 1) ;
        !           362:          }
        !           363:       else
        !           364:          {
        !           365:          IntersectClipRect (hDC, 
        !           366:                             pGraph->rectData.left,
        !           367:                             pGraph->rectData.top,
        !           368:                             PlayingBackLog () ? 
        !           369:                               pGraph->rectData.right :
        !           370:                               min (pGraph->rectData.right,
        !           371:                                    pGraph->gTimeLine.xLastTime + 2),
        !           372:                             pGraph->rectData.bottom + 1) ;
        !           373:          }
        !           374:       }
        !           375: 
        !           376:    xLeftLimit  = prctPaint->left  - pGraph->gTimeLine.ppd - 1 ;
        !           377: //   xRightLimit = prctPaint->right + pGraph->gTimeLine.ppd ;
        !           378:    xRightLimit = prctPaint->right ;
        !           379:    pptDataPoints  = pGraph->pptDataPoints ;
        !           380: 
        !           381:    iValidValues   = pGraph->gTimeLine.iValidValues ;
        !           382: 
        !           383:    if (!PlayingBackLog() &&
        !           384:       pGraph->gOptions.iGraphOrHistogram == LINE_GRAPH)
        !           385:       {
        !           386:       // drawing the 0th at the end of the chart.
        !           387:       DrawZeroPoint = 1 ;
        !           388:       if (iValidValues == pGraph->gMaxValues)
        !           389:          {
        !           390:          iValidValues++ ;
        !           391:          }
        !           392:       }
        !           393: 
        !           394:    // get current select line for highlighting
        !           395:    if (pGraph->HighLightOnOff)
        !           396:       {
        !           397:       pCurrentLine = CurrentGraphLine (hWndGraph) ;
        !           398:       }
        !           399:    else
        !           400:       {
        !           401:       pCurrentLine = NULL ;
        !           402:       }
        !           403: 
        !           404:    // loop through lines to plot
        !           405:    for (pLineStruct = pGraph->pLineFirst ;
        !           406:         pLineStruct || pCurrentLine;
        !           407:         pLineStruct = pLineStruct->pLineNext)
        !           408:       {  // for
        !           409: 
        !           410:       if (pLineStruct == NULL)
        !           411:          {
        !           412:          // now draw the current line
        !           413:          pLineStruct = pCurrentLine ;
        !           414:          }
        !           415:       else if (pLineStruct == pCurrentLine)
        !           416:          {
        !           417:          // skip this line and draw it later
        !           418:          continue ;
        !           419:          }
        !           420: 
        !           421:       // "Localize" some variables from the line data structure.
        !           422:       pDataPoints    = pLineStruct->lnValues ;
        !           423: 
        !           424: 
        !           425:       rectWidth      = pGraph->rectData.right - pGraph->rectData.left ;
        !           426:       numOfData      = pGraph->gMaxValues - 1 + DrawZeroPoint ;
        !           427: 
        !           428:       // Generate the polyline data.
        !           429:       xDispDataPoint = pGraph->rectData.left ;
        !           430: 
        !           431:       // Only process points that lie within the update region.
        !           432:       // Also only process points that have valid data.
        !           433:       j = 0 ;
        !           434: 
        !           435:       for (i = 0 ; i < iValidValues ; i++)
        !           436:          {  // for
        !           437:          if (xDispDataPoint > xRightLimit)
        !           438:             {
        !           439:             // we are done!
        !           440:             break ;
        !           441:             }
        !           442:          if (xDispDataPoint >= xLeftLimit)
        !           443:             {
        !           444:             // It is within the limits, plot the point
        !           445:             pptDataPoints[j].x = xDispDataPoint ;
        !           446:             pptDataPoints[j].y = ScaleAndInvertY (
        !           447:                (i == pGraph->gMaxValues) ? pDataPoints[0] : pDataPoints[i],
        !           448:                pLineStruct,
        !           449:                pGraph) ;
        !           450:             j++ ;
        !           451:             }  // if
        !           452: 
        !           453:          // setup for the next point
        !           454:          if (!numOfData)
        !           455:             {
        !           456:             // no more points to go
        !           457:             break ;
        !           458:             }
        !           459: 
        !           460:          xPos = DDA_DISTRIBUTE (rectWidth, numOfData) ;
        !           461:          xDispDataPoint += xPos ;
        !           462:          numOfData-- ;
        !           463:          rectWidth -= xPos ;
        !           464:          }  // for i
        !           465: 
        !           466:       // only need to draw the line if there is point to draw.
        !           467:       if (j > 0)
        !           468:          {
        !           469:          // Set the pen color and draw the polyline.
        !           470:          if (IsPrinterDC (hDC))
        !           471:             {
        !           472:             hPen = LineCreatePen (hDC, &(pLineStruct->Visual), TRUE) ;
        !           473:             hOldPen = SelectObject (hDC, hPen) ;
        !           474:             }
        !           475:          else
        !           476:             {
        !           477:             if (pCurrentLine == pLineStruct)
        !           478:                {
        !           479:                // highlight this line by turning it into White color
        !           480:                hOldPen = SelectObject (hDC, hWhitePen) ;
        !           481:                }
        !           482:             else
        !           483:                {
        !           484:                SelectObject (hDC, pLineStruct->hPen) ;
        !           485:                }
        !           486:             }
        !           487: 
        !           488:          Polyline(hDC, pptDataPoints, j) ;
        !           489: 
        !           490:          if (hPen)
        !           491:             {
        !           492:             SelectObject (hDC, hOldPen) ;
        !           493: 
        !           494:             if (hPen != hWhitePen)
        !           495:                {
        !           496:                DeletePen (hPen) ;
        !           497:                }
        !           498:             hPen = 0 ;
        !           499:             }
        !           500:          }
        !           501: 
        !           502:       if (pCurrentLine == pLineStruct)
        !           503:          {
        !           504:          // We are done...
        !           505:          break ;
        !           506:          }
        !           507:       }  // for pLine
        !           508: 
        !           509:    if (IsTLineWindowUp())
        !           510:       {
        !           511:       // re-draw the timelines if need
        !           512:       TLineRedraw (hDC, pGraph) ;
        !           513:       }
        !           514: 
        !           515:    // reset the clipping region
        !           516:    SelectClipRgn (hDC, pGraph->hGraphRgn) ;
        !           517: 
        !           518:    return (TRUE) ;
        !           519:    }  // DrawTLGraphData
        !           520: 
        !           521: 
        !           522: 
        !           523: /***************************************************************************
        !           524:  * bInitTimeLine - Initialize the fields of the time line structure.
        !           525:  ***************************************************************************/
        !           526: BOOL bInitTimeLine(PGRAPHSTRUCT pGraph)
        !           527: {
        !           528: 
        !           529:         pGraph->gTimeLine.xLastTime      = 0 ;
        !           530:         pGraph->gTimeLine.ppd            = 0 ;
        !           531:         pGraph->gTimeLine.rppd           = 0 ;
        !           532:         pGraph->gTimeLine.iValidValues   = 1 ;
        !           533: 
        !           534:         return (TRUE) ;
        !           535: 
        !           536: }
        !           537: 
        !           538: 
        !           539: /***************************************************************************
        !           540:  * Scale Time Line
        !           541:  *
        !           542:  *  This routine should be called from the WM_SIZE message.
        !           543:  *  It does the scaling from the number of data points to the
        !           544:  *  size of the window.
        !           545:  ***************************************************************************/
        !           546: void ScaleTimeLine (PGRAPHSTRUCT pGraph)
        !           547:    {
        !           548:    INT     nDataPoints,
        !           549:            cxClient ;
        !           550: 
        !           551:    // Calculate the pels per data point.
        !           552:    nDataPoints = pGraph->gMaxValues - 1 ;
        !           553:    cxClient    = pGraph->rectData.right - pGraph->rectData.left ;
        !           554: 
        !           555:    // ppd  = Pixels per DataPoint.
        !           556:    // rppd = Remaining Pixels per DataPoint.
        !           557:    pGraph->gTimeLine.ppd  = cxClient / nDataPoints ;
        !           558:    pGraph->gTimeLine.rppd = cxClient % nDataPoints ;
        !           559:    }
        !           560: 
        !           561: 
        !           562: void DisplayTimeLine(HDC hDC, PGRAPHSTRUCT pGraph)
        !           563: /*
        !           564:    Called By:     OnPaint only.
        !           565: 
        !           566:    Assert:        xDisplayPoint has been set by UpdateTimeLine on this
        !           567:                   same timer tick.
        !           568: */
        !           569:    {  // DisplayTimeLine
        !           570:    INT     xDisplayPoint ;
        !           571:    RECT    rect ;
        !           572: 
        !           573:    if (pGraph->gTimeLine.xLastTime == -1)
        !           574:       {
        !           575:       UpdateTimeLine (hGraphDisplayDC, pGraph, TRUE) ;
        !           576:       }
        !           577: 
        !           578:    // xDisplayPoint is X coordinate to display the time line at.
        !           579:    if ((xDisplayPoint = pGraph->gTimeLine.xLastTime) == 0)
        !           580:       return ;
        !           581: 
        !           582:    SelectBrush (hDC, pGraph->hbRed) ;
        !           583: 
        !           584:    if (xDisplayPoint >= pGraph->rectData.right)
        !           585:       {
        !           586:       rect.left   = pGraph->rectData.left ;
        !           587:       }
        !           588:    else
        !           589:       {
        !           590: //      rect.left   = xDisplayPoint++ ;
        !           591:       rect.left   = xDisplayPoint ;
        !           592:       }
        !           593:    rect.top    = pGraph->rectData.top ;
        !           594:    rect.right  = rect.left + 2 ;
        !           595:    rect.bottom = pGraph->rectData.bottom ;
        !           596: 
        !           597: //   IntersectRect (&rect, &rect, &pGraph->rectData) ;
        !           598:    if (rect.right > pGraph->rectData.right)
        !           599:       {
        !           600:       rect.right = pGraph->rectData.right ;
        !           601:       }
        !           602:    PatBlt (hDC, 
        !           603:            rect.left, rect.top,
        !           604:            rect.right - rect.left,
        !           605:            rect.bottom - rect.top + 1 ,
        !           606:            PATCOPY) ;
        !           607:          
        !           608:    }  // DisplayTimeLine
        !           609: 
        !           610: 
        !           611: 
        !           612: int SuggestedNumTics (int iRange)
        !           613: /*
        !           614:    Effect:        Return an appropriate number of tic marks to display
        !           615:                   within iRange pixels.
        !           616: 
        !           617:                   These numbers are empirically chosen for pleasing 
        !           618:                   results.
        !           619: */
        !           620:    {  // SuggestedNumTics
        !           621:    if (iRange < 20)
        !           622:       return (0) ;
        !           623: 
        !           624:    if (iRange < 50)
        !           625:       return (2) ;
        !           626: 
        !           627:    if (iRange < 100)
        !           628:       return (4) ;
        !           629: 
        !           630:    if (iRange < 150)
        !           631:       return (5) ;
        !           632: 
        !           633:    if (iRange < 300)
        !           634:       return (10) ;
        !           635: 
        !           636:    if (iRange < 500)
        !           637:       return (20) ;
        !           638: 
        !           639:    return (25) ;
        !           640:    }  // SuggestedNumTics
        !           641: 
        !           642: 
        !           643: 
        !           644: void SetGridPositions (PGRAPHSTRUCT pGraph)
        !           645:    {  // SetGridPositions
        !           646:    int            xDataWidth ;
        !           647:    int            yDataHeight ;
        !           648: 
        !           649:    int            iCurrentTicPixels ;
        !           650:    int            iNumTics ;
        !           651: 
        !           652:    int            i ;
        !           653: 
        !           654: 
        !           655:    //=============================//
        !           656:    // Set number of Tics          //
        !           657:    //=============================//
        !           658: 
        !           659:    xDataWidth = pGraph->rectData.right - pGraph->rectData.left ;
        !           660:    yDataHeight = pGraph->rectData.bottom - pGraph->rectData.top ;
        !           661: 
        !           662:    pGraph->xNumTics = PinInclusive (SuggestedNumTics (xDataWidth),
        !           663:                                     0, iGraphMaxTics) ;
        !           664:    pGraph->yNumTics = PinInclusive (SuggestedNumTics (yDataHeight),
        !           665:                                     0, iGraphMaxTics) ;
        !           666: 
        !           667:    // if we have more tics than possible integral values, reduce the number
        !           668:    // of tics.
        !           669:    if (pGraph->gOptions.iVertMax < pGraph->yNumTics)
        !           670:       pGraph->yNumTics = pGraph->gOptions.iVertMax ;
        !           671: 
        !           672: 
        !           673:    //=============================//
        !           674:    // Set X Tic Positions         //
        !           675:    //=============================//
        !           676: 
        !           677:    if (pGraph->xNumTics)
        !           678:       {
        !           679:       iNumTics = pGraph->xNumTics ;
        !           680: 
        !           681:       pGraph->axTics[0] = 0 ;
        !           682:       for (i = 1 ;
        !           683:            i < pGraph->xNumTics ;
        !           684:            i++)
        !           685:          {  // for
        !           686:          if (iNumTics == 0)
        !           687:             {
        !           688:             break ;
        !           689:             }
        !           690:          iCurrentTicPixels = DDA_DISTRIBUTE (xDataWidth, iNumTics) ;
        !           691:          pGraph->axTics [i] = pGraph->axTics [i - 1] + iCurrentTicPixels ;
        !           692: 
        !           693:          xDataWidth -= iCurrentTicPixels ;
        !           694:          iNumTics-- ;
        !           695:          }  // for
        !           696:       }  // if
        !           697: 
        !           698: 
        !           699:    //=============================//
        !           700:    // Set Y Tic Positions         //
        !           701:    //=============================//
        !           702: 
        !           703:    if (pGraph->yNumTics)
        !           704:       {
        !           705:       iNumTics = pGraph->yNumTics ;
        !           706: 
        !           707:       pGraph->ayTics[0] = 0 ;
        !           708:       for (i = 1 ;
        !           709:            i < pGraph->yNumTics ;
        !           710:            i++)
        !           711:          {  // for
        !           712:          if (iNumTics == 0)
        !           713:             {
        !           714:             break ;
        !           715:             }
        !           716:          iCurrentTicPixels = DDA_DISTRIBUTE (yDataHeight, iNumTics) ;
        !           717:          pGraph->ayTics [i] = pGraph->ayTics [i- 1] + iCurrentTicPixels ;
        !           718: 
        !           719:          yDataHeight -= iCurrentTicPixels ;
        !           720:          iNumTics-- ;
        !           721:          }  // for
        !           722:       }  // if
        !           723:    }  // SetGridPositions
        !           724: 
        !           725: 
        !           726: 
        !           727: int GraphVerticalScaleWidth (HDC hDC,
        !           728:                              PGRAPHSTRUCT pGraph)
        !           729:    {
        !           730:    TCHAR          szMaxValue [20] ;
        !           731:    int            xWidth ;
        !           732: 
        !           733:    if (!pGraph->gOptions.bLabelsChecked)
        !           734:       return (0) ;
        !           735: 
        !           736: 
        !           737: //   SelectFont (hDC, IsPrinterDC (hDC) ? hFontPrinterScales : hFontScales) ;
        !           738: 
        !           739: 
        !           740:    TSPRINTF (szMaxValue, TEXT(" %1d "),
        !           741:             pGraph->gOptions.iVertMax * 10 ) ;
        !           742: 
        !           743:    xWidth = TextWidth (hDC, szMaxValue) ;
        !           744: 
        !           745:    return (xWidth) ;
        !           746:    }
        !           747: 
        !           748: 
        !           749: 
        !           750: void DrawGraphScale (HDC hDC, 
        !           751:                      PGRAPHSTRUCT pGraph)
        !           752:    {
        !           753:    TCHAR   szScale [20] ;
        !           754: 
        !           755:    INT     len,
        !           756:            i,
        !           757:            nLines,
        !           758:            iUnitsPerLine ;
        !           759:    FLOAT   ePercentOfTotal  ;
        !           760:    FLOAT   eDiff ;
        !           761:    BOOL    bUseFloatingPt = FALSE ;
        !           762: 
        !           763:    //=============================//
        !           764:    // Draw Vertical Scale?        //
        !           765:    //=============================//
        !           766: 
        !           767:    if (!pGraph->gOptions.bLabelsChecked)
        !           768:        return ;
        !           769: 
        !           770:    // Get the number of lines.
        !           771:    nLines = pGraph->yNumTics ;
        !           772: 
        !           773:    // Calculate what percentage of the total each line represents.
        !           774:    ePercentOfTotal = ((FLOAT) 1.0) / ((FLOAT) nLines)  ;
        !           775: 
        !           776:    // Calculate the amount (number of units) of the Vertical max each
        !           777:    // each line in the graph represents.
        !           778:    iUnitsPerLine = (INT) ((FLOAT) pGraph->gOptions.iVertMax * ePercentOfTotal) ;
        !           779:    ePercentOfTotal *= (FLOAT) pGraph->gOptions.iVertMax ;
        !           780:    eDiff = (FLOAT)iUnitsPerLine - ePercentOfTotal ;
        !           781:    if (eDiff < (FLOAT) 0.0)
        !           782:       eDiff = -eDiff ;
        !           783: 
        !           784:    if (eDiff > (FLOAT) 0.1)
        !           785:       bUseFloatingPt = TRUE ;
        !           786: 
        !           787:    //=============================//
        !           788:    // Set Drawing Attributes      //
        !           789:    //=============================//
        !           790: 
        !           791: //   SelectFont (hDC, IsPrinterDC (hDC) ? hFontPrinterScales : hFontScales) ;
        !           792:    SetBkMode(hDC, TRANSPARENT) ;
        !           793:    SetTextAlign (hDC, TA_TOP | TA_RIGHT) ;
        !           794:    SelectObject(hDC, GetStockObject (BLACK_PEN)) ;
        !           795: 
        !           796:    // Set the background color to gray
        !           797:    if (!IsPrinterDC (hDC))
        !           798:       FillRect (hDC, &(pGraph->rectVertScale), hbLightGray) ;
        !           799: 
        !           800:    // Now Output each string.
        !           801:    for (i = 0 ; 
        !           802:         i < nLines ; 
        !           803:         i++)
        !           804:       {  // for
        !           805:       if (bUseFloatingPt)
        !           806:          {
        !           807:          len = TSPRINTF (szScale, TEXT("%1.1f"),
        !           808:             (FLOAT)pGraph->gOptions.iVertMax - ((FLOAT)i *
        !           809:              ePercentOfTotal)) ;
        !           810:          TextOut (hDC,
        !           811:                   pGraph->rectVertScale.right,
        !           812:                   pGraph->ayTics[i] +
        !           813:                   pGraph->rectData.top - HalfTextHeight,
        !           814:                   szScale,
        !           815:                   lstrlen(szScale)) ;
        !           816:          }
        !           817:       else
        !           818:          {
        !           819:          len = TSPRINTF (szScale, TEXT("%d"),
        !           820:                          pGraph->gOptions.iVertMax - (i * iUnitsPerLine)) ;
        !           821:          TextOut (hDC,
        !           822:                   pGraph->rectVertScale.right,
        !           823:                   pGraph->ayTics[i] +
        !           824:                   pGraph->rectData.top - HalfTextHeight,
        !           825:                   szScale,
        !           826:                   lstrlen(szScale)) ;
        !           827:          }
        !           828:       }  // for
        !           829: 
        !           830:    // Output the "min value" separately.
        !           831:    TextOut (hDC, 
        !           832:             pGraph->rectVertScale.right,
        !           833:             pGraph->rectData.bottom - HalfTextHeight,
        !           834:             TEXT("0"),
        !           835:             1) ;
        !           836:    }  // DrawGraphScale
        !           837: 
        !           838: 
        !           839: 
        !           840: void SizeGraphDisplayComponentsRect (HDC hDC,
        !           841:                                      PGRAPHSTRUCT pGraph,
        !           842:                                      RECT rectDisplay)
        !           843:    {  // SizeGraphDisplayComponentsRect
        !           844:    int            xScaleWidth ;
        !           845: 
        !           846:    if (!rectDisplay.right || !rectDisplay.bottom)
        !           847:       return ;
        !           848: 
        !           849:    //=============================//
        !           850:    // Size the Vertical Scale     //
        !           851:    //=============================//
        !           852: 
        !           853:    xScaleWidth = GraphVerticalScaleWidth (hDC, pGraph) ;
        !           854:    pGraph->rectVertScale.left = rectDisplay.left ;
        !           855:    pGraph->rectVertScale.top = rectDisplay.top ;
        !           856:    pGraph->rectVertScale.right = rectDisplay.left + xScaleWidth ;
        !           857:    pGraph->rectVertScale.bottom = rectDisplay.bottom ;
        !           858: 
        !           859:    //=============================//
        !           860:    // Size the Horizontal Scale   //
        !           861:    //=============================//
        !           862: 
        !           863:    pGraph->rectHorzScale.left = 0 ;
        !           864:    pGraph->rectHorzScale.top = 0 ;
        !           865:    pGraph->rectHorzScale.right = 0 ;
        !           866:    pGraph->rectHorzScale.bottom = 0 ;
        !           867: 
        !           868:    //=============================//
        !           869:    // Size the Data Area          //
        !           870:    //=============================//
        !           871: 
        !           872:    pGraph->rectData.left = pGraph->rectVertScale.right + 3 + ThreeDPad ;
        !           873:    pGraph->rectData.right = rectDisplay.right - 5 - ThreeDPad ;
        !           874:    pGraph->rectData.top = rectDisplay.top + 5 + ThreeDPad ;
        !           875:    pGraph->rectData.bottom = rectDisplay.bottom - 5 - ThreeDPad ;
        !           876: 
        !           877:    SetGridPositions (pGraph) ;
        !           878:    ScaleTimeLine (pGraph) ;
        !           879: 
        !           880:    //==========================================//
        !           881:    // Invalidate the last time line poisition  //
        !           882:    //==========================================//
        !           883:    pGraph->gTimeLine.xLastTime = -1 ;
        !           884: 
        !           885:    if (pGraph->hGraphRgn)
        !           886:       {
        !           887:       DeleteObject (pGraph->hGraphRgn) ;
        !           888:       }
        !           889: 
        !           890:    pGraph->hGraphRgn = CreateRectRgn (rectDisplay.left,
        !           891:       rectDisplay.top,
        !           892:       rectDisplay.right,
        !           893:       rectDisplay.bottom) ;
        !           894: 
        !           895:    SelectClipRgn (hDC, pGraph->hGraphRgn) ;
        !           896: 
        !           897:    }  // SizeGraphDisplayComponentsRect
        !           898: 
        !           899: 
        !           900: void SizeGraphDisplayComponents (HWND hWnd)
        !           901: /*
        !           902:    Effect:        Given the graph display window hWnd, of size 
        !           903:                   (xWidth x yHeight), determine the size and position
        !           904:                   of the various graph display components: the vertical
        !           905:                   scale, the horizontal scale, and the data area.
        !           906: 
        !           907:    Called By:     OnSize, any other routine that changes the visibility
        !           908:                   of a vertical or horizontal scale.
        !           909: 
        !           910:    Note:          This function has multiple return points.
        !           911: */
        !           912:    {  // SizeGraphDisplayComponents
        !           913:    PGRAPHSTRUCT   pGraph ;
        !           914:    RECT           rectClient ;
        !           915: 
        !           916:    pGraph = GraphData (hWnd) ;
        !           917:    GetClientRect (hWnd, &rectClient) ;
        !           918: 
        !           919:    SizeGraphDisplayComponentsRect (hGraphDisplayDC, pGraph, rectClient) ;
        !           920:    }
        !           921: 
        !           922: 
        !           923: void UpdateGraphDisplay (HDC hDC,
        !           924:                          BOOL bForPaint,
        !           925:                          LPRECT lpRect,
        !           926:                          PGRAPHSTRUCT pGraph)
        !           927: /*
        !           928:    Effect:        Draw the portions of the graph that change as the
        !           929:                   graph's values change. This includes the background,
        !           930:                   the grid, the lines, and the timeline.
        !           931: */
        !           932:    {  // UpdateGraphDisplay
        !           933:    RECT           rectUpdate ;
        !           934: 
        !           935:    if (!bForPaint && !IsPrinterDC (hDC) && 
        !           936:        pGraph->gOptions.iGraphOrHistogram == LINE_GRAPH)
        !           937:       {
        !           938:       HBRUSH         hOldBrush ;
        !           939: 
        !           940:       rectUpdate = pGraph->rectData ;
        !           941:       rectUpdate.bottom += 1 ;
        !           942: 
        !           943:       IntersectRect (&rectUpdate, lpRect, &rectUpdate) ;
        !           944:       hOldBrush = SelectBrush (hDC, hBrushFace) ;
        !           945: 
        !           946:       PatBlt (hDC, 
        !           947:               rectUpdate.left, rectUpdate.top,
        !           948:               rectUpdate.right - rectUpdate.left,
        !           949:               rectUpdate.bottom - rectUpdate.top,
        !           950:               PATCOPY) ;
        !           951:       }
        !           952:    else
        !           953:       {
        !           954:       IntersectRect (&rectUpdate, lpRect, &pGraph->rectData) ;
        !           955:       }
        !           956:    
        !           957:    if (pGraph->gOptions.iGraphOrHistogram == LINE_GRAPH)
        !           958:       {
        !           959:       DrawGrid(hDC, pGraph, &rectUpdate, bForPaint) ;
        !           960:       if (pGraph->pLineFirst != NULL)
        !           961:           {
        !           962:           DrawTLGraphData(hDC, bForPaint, &rectUpdate, pGraph) ;
        !           963:           if (!PlayingBackLog ())
        !           964:              DisplayTimeLine(hDC, pGraph) ;
        !           965:           }
        !           966:       }
        !           967:    else
        !           968:       {
        !           969:       DrawBarChartData (hDC, pGraph) ;
        !           970:       }
        !           971:    }  // UpdateGraphDisplay
        !           972: 
        !           973:                     
        !           974: BOOL UpdateTimeLine (HDC hDC, 
        !           975:                      PGRAPHSTRUCT pGraph,
        !           976:                      BOOL getLastTimeLocation)
        !           977: /*
        !           978:    Called By:     GraphTimer only.
        !           979: 
        !           980:    See Also:      UpdateGraphDisplay.
        !           981: */
        !           982:    {
        !           983:    INT     i,
        !           984:            xDisplayPoint,
        !           985:            xDataPoint ;
        !           986:    RECT    rctUpdate ;
        !           987:    INT     xLastTime ;
        !           988:    INT     rectWidth,
        !           989:            xPos,
        !           990:            numOfPoints ;
        !           991: 
        !           992: 
        !           993:    if ((xLastTime = pGraph->gTimeLine.xLastTime) != 0)
        !           994:       {
        !           995:       if ((pGraph->gKnownValue % pGraph->gMaxValues) == 1)
        !           996:          {
        !           997:          // Data wrap around case
        !           998:          rctUpdate.left   = pGraph->rectData.left ;
        !           999:          rctUpdate.right  = pGraph->rectData.left +
        !          1000:              pGraph->gTimeLine.ppd + 1 ;
        !          1001:          }
        !          1002:       else
        !          1003:          {
        !          1004:          rctUpdate.left   = xLastTime - pGraph->gTimeLine.ppd ;
        !          1005:          rctUpdate.right  = xLastTime +
        !          1006:              pGraph->gTimeLine.ppd + 1 ;
        !          1007:          }
        !          1008:       rctUpdate.top    = pGraph->rectData.top ;
        !          1009:       rctUpdate.bottom = pGraph->rectData.bottom + 1 ;
        !          1010:       }
        !          1011: 
        !          1012:    // Calculate where to draw the time line.
        !          1013:    // This is done by running a simple DDA (Digital Differential Analyzer)
        !          1014:    // We have to position the time depending upon the size of the
        !          1015:    // graph window.  In essence we need to calculate the x display
        !          1016:    // coordinate.
        !          1017: 
        !          1018:    // Note we should wrap Known Value in UpdateGLData.
        !          1019:    // We should also use a data buffer of 256 bytes so we can
        !          1020:    // wrap with and AND.
        !          1021: 
        !          1022:    // xDataPoint =  pGraph->gKnownValue ;
        !          1023:    xDataPoint =  pGraph->gKnownValue % pGraph->gMaxValues ;
        !          1024: 
        !          1025:    xDisplayPoint = pGraph->rectData.left ;
        !          1026: 
        !          1027:    numOfPoints = pGraph->gMaxValues - 1 ;
        !          1028: 
        !          1029:    if (!PlayingBackLog() &&
        !          1030:       pGraph->gOptions.iGraphOrHistogram == LINE_GRAPH)
        !          1031:       {
        !          1032:       // drawing the 0th at the end of the chart.
        !          1033:       // So, we do have gMaxValues points
        !          1034:       numOfPoints++ ;
        !          1035:       if ((pGraph->gKnownValue % pGraph->gMaxValues) == 0)
        !          1036:          {
        !          1037:          xDataPoint = pGraph->gMaxValues ;
        !          1038:          }
        !          1039:       }
        !          1040: 
        !          1041:    rectWidth = pGraph->rectData.right - pGraph->rectData.left ;
        !          1042: 
        !          1043:    for (i = 0 ; i < xDataPoint ; i++)
        !          1044:       {
        !          1045:       if (numOfPoints == 0)
        !          1046:          {
        !          1047:          break ;
        !          1048:          }
        !          1049:       xPos = DDA_DISTRIBUTE (rectWidth, numOfPoints) ;
        !          1050:       xDisplayPoint += xPos ;
        !          1051:       rectWidth -= xPos ;
        !          1052:       numOfPoints-- ;
        !          1053:       }  // for
        !          1054: 
        !          1055:    pGraph->gTimeLine.xLastTime = xDisplayPoint ;
        !          1056: 
        !          1057:    if (!getLastTimeLocation && iPerfmonView == IDM_VIEWCHART && !bPerfmonIconic)
        !          1058:       {
        !          1059:       UpdateGraphDisplay (hDC, FALSE, &rctUpdate, pGraph) ;
        !          1060:       }
        !          1061: 
        !          1062:    return(TRUE) ;
        !          1063:    }
        !          1064: 
        !          1065: 
        !          1066: //==========================================================================//
        !          1067: //                              Message Handlers                            //
        !          1068: //==========================================================================//
        !          1069: 
        !          1070: 
        !          1071: void /*static*/ OnCreate (HWND hWnd)
        !          1072: /*
        !          1073:    Effect:        Perform all actions needed when a GraphDisplay window is 
        !          1074:                   created.
        !          1075:                   In particular, initialize the graph instance data and
        !          1076:                   create the child windows.
        !          1077: 
        !          1078:    Called By:     GraphDisplayWndProc, in response to a WM_CREATE message.
        !          1079: */
        !          1080:    {  // OnCreate
        !          1081:    LOGBRUSH       LogBrush ;
        !          1082:    TEXTMETRIC     tmScales ;
        !          1083: 
        !          1084:    hGraphDisplayDC = GetDC(hWnd) ;
        !          1085: 
        !          1086:    SelectFont(hGraphDisplayDC, hFontScales) ;
        !          1087:    GetTextMetrics(hGraphDisplayDC, &tmScales) ;
        !          1088:    HalfTextHeight = tmScales.tmHeight / 2 ;
        !          1089: 
        !          1090:    SetBkColor (hGraphDisplayDC, crLightGray) ;
        !          1091: 
        !          1092: 
        !          1093:    InsertGraph(hWnd) ;
        !          1094:    bInitTimeLine(pGraphs) ;
        !          1095: 
        !          1096:    pGraphs->hWnd = hWnd ;
        !          1097: 
        !          1098:    // Create the brush and pen used by the time line.
        !          1099:    // We don't want to create these on every timer tick.
        !          1100: 
        !          1101:    LogBrush.lbStyle = BS_SOLID ;
        !          1102:    LogBrush.lbColor = RGB(0xff, 0, 0) ;
        !          1103:    LogBrush.lbHatch = 0 ;
        !          1104: 
        !          1105:    // Now get the system resources we use "all the time"
        !          1106:    pGraphs->hbRed = CreateBrushIndirect(&LogBrush) ;
        !          1107:    pGraphs->hGridPen = CreatePen (PS_SOLID, 1, crGray) ;
        !          1108: 
        !          1109:    pGraphs->xNumTics = 0 ;
        !          1110:    pGraphs->yNumTics = 0 ;
        !          1111:    }  // OnCreate
        !          1112: 
        !          1113: 
        !          1114: void /*static*/ OnSize (HWND hWnd,
        !          1115:                     WORD xWidth,
        !          1116:                     WORD yHeight)
        !          1117:    {  // OnSize
        !          1118:    PGRAPHSTRUCT   pGraph ;
        !          1119: 
        !          1120:    pGraph = GraphData (hWnd) ;
        !          1121: 
        !          1122:    SizeGraphDisplayComponents (hWnd) ;
        !          1123:    }  // OnSize
        !          1124: 
        !          1125: 
        !          1126: void /*static*/ OnPaint (HWND hWnd)
        !          1127:    {
        !          1128:    HDC            hDC ;
        !          1129:    PAINTSTRUCT    ps ;
        !          1130:    PGRAPHSTRUCT   pGraph ;
        !          1131: 
        !          1132:    pGraph = GraphData (hWnd) ;
        !          1133:    hDC = BeginPaint(hWnd, &ps) ;
        !          1134: 
        !          1135:    DrawGraphDisplay (hDC, ps.rcPaint, pGraph) ;
        !          1136: 
        !          1137:    EndPaint(hWnd, &ps) ;
        !          1138:    }  // OnPaint
        !          1139: 
        !          1140: 
        !          1141: //==========================================================================//
        !          1142: //                             Exported Functions                           //
        !          1143: //==========================================================================//
        !          1144: 
        !          1145: #ifdef KEEP_PRINT
        !          1146: void PrintGraphDisplay (HDC hDC,
        !          1147:                         PGRAPHSTRUCT pGraph)
        !          1148:    {
        !          1149:    DrawGraphScale (hDC, pGraph) ;
        !          1150: 
        !          1151: 
        !          1152: //!!   UpdateGraphDisplay (hDC, TRUE, &(pGraph->rectData), pGraph) ;
        !          1153: 
        !          1154:    IntersectClipRect (hDC, 0, 0, 10000, 10000) ;
        !          1155:    SelectBrush (hDC, GetStockObject (HOLLOW_BRUSH)) ;
        !          1156:    SelectPen (hDC, GetStockObject (BLACK_PEN)) ;
        !          1157:    Rectangle (hDC, 
        !          1158:               pGraph->rectData.left,
        !          1159:               pGraph->rectData.top,
        !          1160:               pGraph->rectData.right,
        !          1161:               pGraph->rectData.bottom) ;
        !          1162:    }  // PrintGraphDisplay
        !          1163: #endif
        !          1164: 
        !          1165: 
        !          1166: 
        !          1167: void DrawGraphDisplay (HDC hDC,
        !          1168:                        RECT rectDraw,
        !          1169:                        PGRAPHSTRUCT pGraph)
        !          1170:    {
        !          1171:    BOOL        bPaintScale ;
        !          1172:    INT         LocalThreeDPad = ThreeDPad - 1 ;
        !          1173: 
        !          1174:    // Only draw the vertical labels if the paint rectangle
        !          1175:    // any portion of the window to the left of the graph area.
        !          1176: 
        !          1177:    bPaintScale = (rectDraw.left <= pGraph->rectVertScale.right) ;
        !          1178:    if (bPaintScale)
        !          1179:       DrawGraphScale (hDC, pGraph) ;
        !          1180:    if (IsPrinterDC (hDC))
        !          1181:       Rectangle (hDC, 
        !          1182:                  pGraph->rectData.left,
        !          1183:                  pGraph->rectData.top,
        !          1184:                  pGraph->rectData.right,
        !          1185:                  pGraph->rectData.bottom) ;
        !          1186:    else
        !          1187:       ThreeDConcave1 (hDC, 
        !          1188:                      pGraph->rectData.left - LocalThreeDPad,
        !          1189:                      pGraph->rectData.top - LocalThreeDPad,
        !          1190:                      pGraph->rectData.right + LocalThreeDPad,
        !          1191:                      pGraph->rectData.bottom + LocalThreeDPad + 1) ;
        !          1192: 
        !          1193:    UpdateGraphDisplay (hDC, TRUE, &(rectDraw), pGraph) ;
        !          1194:    }  // DrawGraphDisplay
        !          1195: 
        !          1196: 
        !          1197: LRESULT APIENTRY GraphDisplayWndProc (HWND hWnd, 
        !          1198:                                       UINT uMsg, 
        !          1199:                                       WPARAM wParam,
        !          1200:                                       LPARAM lParam)
        !          1201:    {  // GraphDisplayWndProc
        !          1202:    LONG        lret = 0L ;
        !          1203:    BOOL        bCallDefProc = FALSE ;
        !          1204: 
        !          1205:    switch (LOWORD (uMsg))
        !          1206:       {
        !          1207:       case WM_LBUTTONDOWN:
        !          1208:          DoWindowDrag (lParam) ;
        !          1209:          break ;
        !          1210: 
        !          1211:       case WM_LBUTTONDBLCLK:
        !          1212:          SendMessage (hWndMain, uMsg, wParam, lParam) ;
        !          1213:          break ;
        !          1214: 
        !          1215:       case WM_CREATE:
        !          1216:          OnCreate (hWnd) ;
        !          1217:          break ;
        !          1218: 
        !          1219:       case WM_SIZE:
        !          1220:          OnSize (hWnd, LOWORD (lParam), HIWORD (lParam)) ;
        !          1221:          break ;
        !          1222: 
        !          1223:       case WM_DESTROY:
        !          1224:          KillTimer(hWndMain, GRAPH_TIMER_ID) ;
        !          1225:          break ;
        !          1226: 
        !          1227:       case WM_PAINT:
        !          1228:          OnPaint (hWnd) ;
        !          1229:          break ;
        !          1230: 
        !          1231:       case WM_TIMER:
        !          1232:          GraphTimer (hWnd, FALSE) ;
        !          1233:          break ;
        !          1234: 
        !          1235:       default:
        !          1236:          bCallDefProc = TRUE ;
        !          1237:          break ;
        !          1238:       }  // switch
        !          1239: 
        !          1240: 
        !          1241:    if (bCallDefProc)
        !          1242:       {
        !          1243:       lret = DefWindowProc(hWnd, uMsg, wParam, lParam) ;
        !          1244:       }
        !          1245:    return (lret) ;
        !          1246:    }
        !          1247: 
        !          1248: 
        !          1249: BOOL GraphDisplayInitializeApplication (void)
        !          1250:    {  // GraphDisplayInitializeApplication
        !          1251:    WNDCLASS       wc ;
        !          1252: 
        !          1253:    wc.style         = dwGraphDisplayClassStyle ;
        !          1254:    wc.lpfnWndProc   = (WNDPROC) GraphDisplayWndProc ;
        !          1255:    wc.hInstance     = hInstance ;
        !          1256:    wc.cbClsExtra    = iGraphDisplayWindowExtra ;
        !          1257:    wc.cbWndExtra    = iGraphDisplayClassExtra ;
        !          1258:    wc.hIcon         = NULL ;
        !          1259:    wc.hCursor       = LoadCursor(NULL, IDC_ARROW) ;
        !          1260:    wc.hbrBackground = hbLightGray ;
        !          1261:    wc.lpszMenuName  = NULL ;
        !          1262:    wc.lpszClassName = (LPTSTR) szGraphDisplayWindowClass ;
        !          1263: 
        !          1264:    return (RegisterClass (&wc)) ;
        !          1265:    }  // GraphDisplayInitializeApplication
        !          1266: 
        !          1267: 
        !          1268: 
        !          1269: HWND CreateGraphDisplayWindow (HWND hWndGraph)
        !          1270:    {
        !          1271:    return (CreateWindow (szGraphDisplayWindowClass,   // class
        !          1272:                          NULL,                        // caption
        !          1273:                          dwGraphDisplayWindowStyle,   // window style
        !          1274:                          0, 0,                        // position
        !          1275:                          0, 0,                        // size
        !          1276:                          hWndGraph,                   // parent window
        !          1277:                          NULL,                        // menu
        !          1278:                          hInstance,                  // program instance
        !          1279:                          NULL)) ;                     // user-supplied data
        !          1280:    }
        !          1281: 
        !          1282: 
        !          1283: 
        !          1284: BOOL ToggleGraphRefresh (HWND hWnd)
        !          1285:    {  // ToggleGraphRefresh
        !          1286:    PGRAPHSTRUCT   pGraph ;
        !          1287: 
        !          1288:    pGraph = GraphData (hWnd) ;
        !          1289: 
        !          1290:    if (pGraph->bManualRefresh)
        !          1291:       SetGraphTimer (pGraph) ;
        !          1292:    else
        !          1293:       ClearGraphTimer (pGraph) ;
        !          1294: 
        !          1295:    pGraph->bManualRefresh = !pGraph->bManualRefresh ;
        !          1296:    return (pGraph->bManualRefresh) ;
        !          1297:    }  // ToggleGraphRefresh
        !          1298: 
        !          1299: BOOL GraphRefresh (HWND hWnd)
        !          1300:    {  // GraphRefresh
        !          1301:    PGRAPHSTRUCT   pGraph ;
        !          1302: 
        !          1303:    pGraph = GraphData (hWnd) ;
        !          1304: 
        !          1305:    return (pGraph->bManualRefresh) ;
        !          1306:    }  // GraphRefresh
        !          1307: 
        !          1308: 
        !          1309: void GraphTimer (HWND hWnd, 
        !          1310:                  BOOL bForce)
        !          1311: /*
        !          1312:    Effect:        Handle any actions necessary when the graph display
        !          1313:                   window hWnd receives a timer tick. In particular,
        !          1314:                   update the graph display and update the status bar
        !          1315:                   if it is showing.
        !          1316: 
        !          1317:    Called By:     GraphDisplayWndProc, in response to a WM_TIMER message.
        !          1318: */
        !          1319:    {  // GraphTimer
        !          1320:    PGRAPHSTRUCT         pGraph ;
        !          1321: 
        !          1322:    pGraph = GraphData (hWnd) ;
        !          1323: 
        !          1324:    if (!pGraph->pLineFirst)
        !          1325:       return ;
        !          1326: 
        !          1327: 
        !          1328:    if (bForce || !pGraph->bManualRefresh)
        !          1329:       {
        !          1330: 
        !          1331:    
        !          1332:       HandleGraphTimer () ;
        !          1333: 
        !          1334:       // If we are displaying a time-line graph then do the
        !          1335:       // calculations for the minimal update region.
        !          1336:       // If were doing a bar graph, then draw the
        !          1337:       // whole graph area.
        !          1338: 
        !          1339:       if (pGraph->gOptions.iGraphOrHistogram == LINE_GRAPH)
        !          1340:          UpdateTimeLine (hGraphDisplayDC, pGraph, FALSE) ;
        !          1341:       else
        !          1342:          DrawBarChartData (hGraphDisplayDC, pGraph) ;
        !          1343: 
        !          1344:       // Take care of the status bar window
        !          1345:       StatusTimer (hWndGraphStatus, FALSE) ;
        !          1346: 
        !          1347:       }  // if
        !          1348:    }  // GraphTimer
        !          1349: 
        !          1350: // this routine set/reset the line highlight mode
        !          1351: void ChartHighlight (void)
        !          1352:    {
        !          1353:    PGRAPHSTRUCT         pGraph ;
        !          1354: 
        !          1355: 
        !          1356:    if (pGraph = GraphData (hWndGraph))
        !          1357:       {
        !          1358:       if (pGraph->pLineFirst)
        !          1359:          {
        !          1360:          // toggle the HightlightOnOff mode
        !          1361:          pGraph->HighLightOnOff = !pGraph->HighLightOnOff ;
        !          1362:          WindowInvalidate (hWndGraphDisplay) ;
        !          1363:          }
        !          1364:       else
        !          1365:          {
        !          1366:          // no line availble, just turn it off
        !          1367:          pGraph->HighLightOnOff = FALSE ;
        !          1368:          }
        !          1369:       }
        !          1370:    }  // ChartHighlight
        !          1371: 
        !          1372: 

unix.superglobalmegacorp.com

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