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

1.1     ! root        1: /*
        !             2: ==============================================================================
        !             3: 
        !             4:   Application:
        !             5: 
        !             6:             Microsoft Windows NT (TM) Performance Monitor
        !             7: 
        !             8:   File:
        !             9:             legend.c - legend window routines.                          
        !            10: 
        !            11:             This file contains code creating the legend window, which is
        !            12:             a child of the graph windows. The legend window displays a
        !            13:             legend line for each line in the associated graph. It also 
        !            14:             includes an area called the label, which are headers for those
        !            15:             lines.
        !            16: 
        !            17: 
        !            18:   Copyright 1992, Microsoft Corporation. All Rights Reserved.
        !            19: ==============================================================================
        !            20: */
        !            21: 
        !            22: 
        !            23: //==========================================================================//
        !            24: //                                  Includes                                //
        !            25: //==========================================================================//
        !            26: 
        !            27: 
        !            28: #include <stdio.h>      // for sprintf
        !            29: #include "perfmon.h"
        !            30: #include "legend.h"     // external declarations for this file
        !            31: 
        !            32: #include "owndraw.h"
        !            33: 
        !            34: #include "alert.h"      // for EditAlert
        !            35: #include "grafdata.h"   // for EditChart
        !            36: #include "pmemory.h"    // for MemoryXXX (mallloc-type) routines
        !            37: #include "utils.h"
        !            38: #include "valuebar.h"   // for StatusTimer
        !            39: #include "playback.h"   // for PlayingBackLog()
        !            40: 
        !            41: #define eScaleValueSpace       TEXT(">9999999999.0")
        !            42: 
        !            43: //==========================================================================//
        !            44: //                                  Constants                               //
        !            45: //==========================================================================//
        !            46: 
        !            47: 
        !            48: #define dwGraphLegendClassStyle     (CS_HREDRAW | CS_VREDRAW)
        !            49: #define iGraphLegendClassExtra      (0)
        !            50: #define iGraphLegendWindowExtra     (sizeof (PLEGEND))
        !            51: #define dwGraphLegendWindowStyle    (WS_CHILD | WS_VISIBLE) 
        !            52: 
        !            53: #define xLegendBorderWidth          (xDlgBorderWidth)
        !            54: #define yLegendBorderHeight         (yDlgBorderHeight)
        !            55: 
        !            56: #define iLabelLen                   30
        !            57: #define iLegendColMax               1000
        !            58: 
        !            59: #define LEFTORIENTATION             1
        !            60: #define CENTERORIENTATION           2
        !            61: #define RIGHTORIENTATION            3
        !            62: 
        !            63: #define LegendColorCol              0
        !            64: #define LegendScaleCol              1
        !            65: #define LegendCounterCol            2
        !            66: #define LegendInstanceCol           3
        !            67: #define LegendParentCol             4
        !            68: #define LegendObjectCol             5
        !            69: #define LegendSystemCol             6  
        !            70: 
        !            71: #define iLegendNumCols              7
        !            72: 
        !            73: #define iLegendMaxVisibleItems      8
        !            74: 
        !            75: #define dwGraphLegendItemsWindowClass  TEXT("ListBox")
        !            76: #define dwGraphLegendItemsWindowStyle           \
        !            77:    (LBS_NOTIFY | LBS_NOINTEGRALHEIGHT | LBS_OWNERDRAWFIXED | \
        !            78:     WS_VISIBLE | WS_CHILD | WS_VSCROLL)
        !            79: 
        !            80: 
        !            81: //==========================================================================//
        !            82: //                                  Typedefs                                //
        !            83: //==========================================================================//
        !            84: 
        !            85: 
        !            86: typedef struct LEGENDCOLSTRUCT
        !            87:    {
        !            88:    TCHAR          szLabel [iLabelLen] ;
        !            89:    int            xMinWidth ;
        !            90:    int            xMaxWidth ;
        !            91:    int            xWidth ;
        !            92:    int            xPos ;
        !            93:    int            iOrientation ;
        !            94:    } LEGENDCOL ;
        !            95: 
        !            96: typedef LEGENDCOL *PLEGENDCOL ;
        !            97: 
        !            98: 
        !            99: typedef struct LEGENDTRUCT
        !           100:    {
        !           101:    HWND           hWndItems ;
        !           102:    HFONT          hFontItems ;
        !           103:    HFONT          hFontLabels ;
        !           104:    int            xMinWidth ;
        !           105:    int            yLabelHeight ;
        !           106:    int            yItemHeight ;
        !           107:    int            iNumItemsVisible ;
        !           108:    LEGENDCOL      aCols [iLegendNumCols] ;
        !           109:    int            iLineType ;
        !           110:    PLINE          pCurrentLine ;    // current selected line
        !           111:    }  LEGEND ;
        !           112: 
        !           113: typedef LEGEND *PLEGEND ;
        !           114: 
        !           115: 
        !           116: //==========================================================================//
        !           117: //                                   Macros                                 //
        !           118: //==========================================================================//
        !           119: 
        !           120: 
        !           121: #define LabelTopMargin()      (2)
        !           122: #define LegendLeftMargin()    (3 + ThreeDPad)
        !           123: 
        !           124: #define LegendItemTopMargin() (yBorderHeight)
        !           125: 
        !           126: 
        !           127: #define IsLegendLabelVisible()  (TRUE)
        !           128: 
        !           129: #define ColCanGrow(pCol)                     \
        !           130:    (pCol->xMaxWidth > pCol->xWidth)
        !           131: 
        !           132: 
        !           133: #define LegendHorzMargin()    (3)
        !           134: 
        !           135: 
        !           136: 
        !           137: //==========================================================================//
        !           138: //                                Local Data                                //
        !           139: //==========================================================================//
        !           140: 
        !           141: 
        !           142: // LEGEND            Legend ;
        !           143: PLEGEND     pGraphLegendData ;
        !           144: PLEGEND     pAlertLegendData ;
        !           145: 
        !           146: #define  LegendData(hWnd)     \
        !           147:    ((hWnd == hWndGraphLegend) ? pGraphLegendData : pAlertLegendData )
        !           148: 
        !           149: //==========================================================================//
        !           150: //                              Local Functions                             //
        !           151: //==========================================================================//
        !           152: void LegendSetCurrentLine (PLEGEND pLegend, int iIndex)
        !           153:    {
        !           154:    pLegend->pCurrentLine =
        !           155:       (PLINESTRUCT) LBData (pLegend->hWndItems, iIndex) ;
        !           156: 
        !           157:    if (pLegend->pCurrentLine == (PLINESTRUCT) LB_ERR)
        !           158:       {
        !           159:       pLegend->pCurrentLine = NULL ;
        !           160:       }
        !           161:    }  // LegendSetCurrentLine
        !           162: 
        !           163: #if 0
        !           164: PLEGEND LegendData (HWND hWnd)
        !           165:    {
        !           166:    return ((PLEGEND) GetWindowLong (hWnd, 0)) ;
        !           167:    }
        !           168: #endif
        !           169: 
        !           170: 
        !           171: PLEGEND AllocateLegendData (HWND hWnd, BOOL bChartLegend)
        !           172:    {
        !           173:    PLEGEND        pLegend ;
        !           174: 
        !           175:    pLegend = MemoryAllocate (sizeof (LEGEND)) ;
        !           176: //   SetWindowLong (hWnd, 0, (LONG) pLegend) ;
        !           177: 
        !           178:    if (bChartLegend)
        !           179:       {
        !           180:       hWndGraphLegend = hWnd ;
        !           181:       pGraphLegendData = pLegend ;
        !           182:       }
        !           183:    else
        !           184:       {
        !           185:       hWndAlertLegend = hWnd ;
        !           186:       pAlertLegendData = pLegend ;
        !           187:       }
        !           188: 
        !           189:    return (pLegend) ;
        !           190:    }
        !           191: 
        !           192: 
        !           193: 
        !           194: void DrawLegendLabel (PLEGEND pLegend,
        !           195:                       HDC hDC,
        !           196:                       HWND hWnd)
        !           197:    {  // DrawLegendLabel
        !           198:    int            i ;
        !           199:    int            xPos ;
        !           200:    RECT           rect ;
        !           201:    RECT           rectLB ;
        !           202:    INT            LocalThreeDPad = ThreeDPad - 1 ;
        !           203: 
        !           204:    SetBkColor (hDC, crLightGray) ;
        !           205: 
        !           206:    SelectFont (hDC, pLegend->hFontLabels) ;
        !           207: 
        !           208:    GetClientRect (hWnd, &rect) ;
        !           209: //   Fill (hDC, crLightGray, &rect) ;
        !           210:    ExtTextOut (hDC, rect.left, rect.top,
        !           211:       ETO_OPAQUE, &(rect), NULL, 0, NULL ) ;
        !           212: 
        !           213:    GetWindowRect (pLegend->hWndItems, &rectLB) ;
        !           214:    ScreenRectToClient (hWnd, &rectLB) ;
        !           215:    ThreeDConcave1 (hDC, 
        !           216:                   rectLB.left - LocalThreeDPad,
        !           217:                   rectLB.top - LocalThreeDPad,
        !           218:                   rectLB.right + LocalThreeDPad,
        !           219:                   rectLB.bottom + LocalThreeDPad) ;
        !           220: 
        !           221:    for (i = 0 ;
        !           222:         i < iLegendNumCols ;
        !           223:         i++)
        !           224:       {  // for
        !           225:       rect.left = pLegend->aCols[i].xPos ;
        !           226:       rect.top = yBorderHeight ;
        !           227:       rect.right = rect.left + pLegend->aCols[i].xWidth - LegendHorzMargin () ;
        !           228:       rect.bottom = pLegend->yLabelHeight ;
        !           229: 
        !           230:       switch (pLegend->aCols[i].iOrientation)
        !           231:          {  // switch
        !           232:          case LEFTORIENTATION:
        !           233:             SetTextAlign (hDC, TA_LEFT) ;
        !           234:             xPos = rect.left ;
        !           235:             break ;
        !           236: 
        !           237:          case CENTERORIENTATION:
        !           238:             SetTextAlign (hDC, TA_CENTER) ;
        !           239:             xPos = (rect.left + rect.right) / 2 ;
        !           240:             break ;
        !           241: 
        !           242:          case RIGHTORIENTATION:
        !           243:             SetTextAlign (hDC, TA_RIGHT) ;
        !           244:             xPos = rect.right ;
        !           245:             break ;
        !           246: 
        !           247:          default:
        !           248:             xPos = rect.left ;
        !           249:             break ;
        !           250:          }  // switch
        !           251: 
        !           252:       ExtTextOut (hDC, 
        !           253:                   xPos, rect.top, 
        !           254:                   ETO_OPAQUE,
        !           255:                   &rect,
        !           256:                   pLegend->aCols[i].szLabel,
        !           257:                   lstrlen (pLegend->aCols[i].szLabel),
        !           258:                   NULL) ;
        !           259:       }  // for
        !           260:    }  // DrawLegendLabel
        !           261: 
        !           262: 
        !           263: 
        !           264: void DrawColorCol (PLEGEND pLegend,
        !           265:                    PLINE pLine,
        !           266:                    int iCol,
        !           267:                    HDC hDC,
        !           268:                    int yPos)
        !           269: /*
        !           270:    Effect:        Draw the "color" column of a legend entry. The color 
        !           271:                   column displays a small sample of the line drawing.
        !           272: 
        !           273:                   For charts, the sample is a line of the correct style,
        !           274:                   color, and width.  Since we are using wide lines, 
        !           275:                   the round endcaps of the lines will breach the column.
        !           276:                   Therefore we need to set the clip region. We could
        !           277:                   remove this clipping if we find a way to change the
        !           278:                   end cap design.  
        !           279: 
        !           280:                   For alerts, the sample is a small circle which echos
        !           281:                   the design in the alert log itself.
        !           282: */      
        !           283:    {  // DrawColorCol
        !           284:    HBRUSH         hBrush, hBrushPrevious ;
        !           285:    RECT           rect ;
        !           286:    int            yMiddle ;
        !           287:    int            iCircle ;
        !           288: 
        !           289: 
        !           290: 
        !           291:    rect.left = pLegend->aCols[iCol].xPos - LegendLeftMargin () + 2 ;
        !           292:    rect.top = yPos + 1 ;
        !           293:    rect.right = rect.left + pLegend->aCols[iCol].xWidth - LegendHorzMargin () ;
        !           294:    rect.bottom = yPos + pLegend->yItemHeight - 1 ;
        !           295: 
        !           296:    yMiddle = rect.top + (rect.bottom - rect.top) / 2 ;
        !           297:    iCircle = rect.bottom - rect.top - 2 ;
        !           298:  
        !           299:   switch (pLegend->iLineType)
        !           300:       {  // switch
        !           301:       case LineTypeChart:
        !           302:    
        !           303:          if (pLine->Visual.iWidth == 1)
        !           304:             {
        !           305:             // simple case with thin pen
        !           306:             hBrush = SelectBrush (hDC, hbLightGray) ;
        !           307:             Rectangle (hDC, rect.left, rect.top, rect.right, rect.bottom) ;
        !           308:    
        !           309:             HLine (hDC, pLine->hPen, 
        !           310:                    rect.left + 1, rect.right - 1, yMiddle) ;
        !           311:             SelectBrush (hDC, hBrush) ;
        !           312:             }
        !           313:          else
        !           314:             {
        !           315:             // thicker pen width, have to set ClipRect so
        !           316:             // it will not draw otherside the rect.
        !           317:             SaveDC (hDC) ;
        !           318:             hBrush = SelectBrush (hDC, hbLightGray) ;
        !           319:             Rectangle (hDC, rect.left, rect.top, rect.right, rect.bottom) ;
        !           320:    
        !           321:             IntersectClipRect (hDC, 
        !           322:                                rect.left + 1,
        !           323:                                rect.top + 1,
        !           324:                                rect.right - 1,
        !           325:                                rect.bottom - 1) ;
        !           326:             HLine (hDC, pLine->hPen, 
        !           327:                    rect.left + 1, rect.right - 1, yMiddle) ;
        !           328:             SelectBrush (hDC, hBrush) ;
        !           329:             RestoreDC (hDC, -1) ;
        !           330:             }
        !           331:          break ;
        !           332: 
        !           333: 
        !           334:       case LineTypeAlert:
        !           335:          hBrushPrevious = SelectBrush (hDC, pLine->hBrush) ;
        !           336: 
        !           337:          Ellipse (hDC,
        !           338:                   rect.left + 2,
        !           339:                   rect.top + 2,
        !           340:                   rect.left + 2 + iCircle,
        !           341:                   rect.top + 2 + iCircle) ;
        !           342: 
        !           343:          SelectBrush (hDC, hBrushPrevious) ;
        !           344:          break ;
        !           345:       }  // switch
        !           346: 
        !           347:    }  // DrawColorCol
        !           348: 
        !           349: 
        !           350: void DrawLegendCol (PLEGEND pLegend,
        !           351:                     int iCol,
        !           352:                     HDC hDC,
        !           353:                     int yPos,
        !           354:                     LPTSTR lpszValue)
        !           355: /*
        !           356:    Effect:        Draw the value lpszValue for the column iCol on hDC.
        !           357: 
        !           358:    Assert:        The foreground and background text colors of hDC are
        !           359:                   properly set.
        !           360: */
        !           361:    {  // DrawLegendCol
        !           362:    RECT           rect ;
        !           363:    int            xPos ;
        !           364: 
        !           365:    rect.left = pLegend->aCols[iCol].xPos - LegendLeftMargin () ;
        !           366:    rect.top = yPos ;
        !           367:    rect.right = rect.left + pLegend->aCols[iCol].xWidth - LegendHorzMargin () ;
        !           368:    rect.bottom = yPos + pLegend->yItemHeight ;
        !           369: 
        !           370: //   SetTextAlign (hDC, TA_TOP) ;   
        !           371:    switch (pLegend->aCols[iCol].iOrientation)
        !           372:       {  // switch
        !           373:       case LEFTORIENTATION:
        !           374:          SetTextAlign (hDC, TA_LEFT) ;
        !           375:          xPos = rect.left ;
        !           376:          break ;
        !           377: 
        !           378:       case CENTERORIENTATION:
        !           379:          SetTextAlign (hDC, TA_CENTER) ;
        !           380:          xPos = (rect.left + rect.right) / 2 ;
        !           381:          break ;
        !           382: 
        !           383:       case RIGHTORIENTATION:
        !           384:          SetTextAlign (hDC, TA_RIGHT) ;
        !           385:          xPos = rect.right ;
        !           386:          break ;
        !           387: 
        !           388:       default:
        !           389:          xPos = rect.left ;
        !           390:          break ;
        !           391:       }  // switch
        !           392: 
        !           393:    ExtTextOut (hDC, 
        !           394:                xPos, rect.top + LegendItemTopMargin (), 
        !           395:                ETO_OPAQUE | ETO_CLIPPED,
        !           396:                &rect,
        !           397:                lpszValue,
        !           398:                lstrlen (lpszValue),
        !           399:                NULL) ;
        !           400:    }  // DrawLegendCol
        !           401: 
        !           402: 
        !           403: void DrawLegendItem (PLEGEND pLegend,
        !           404:                      PLINESTRUCT pLine,
        !           405:                      int yPos,
        !           406:                      HDC hDC)
        !           407:    {
        !           408:    TCHAR          szValue [256] ;
        !           409:    TCHAR          szInstance [256] ;
        !           410:    TCHAR          szParent [256] ;
        !           411:    TCHAR          szNoName[4] ;
        !           412: 
        !           413:    szNoName[0] = szNoName[1] = szNoName[2] = TEXT('-') ;
        !           414:    szNoName[3] = TEXT('\0') ;
        !           415: 
        !           416:    //=============================//
        !           417:    // Determine Instance, Parent  //
        !           418:    //=============================//
        !           419: 
        !           420:    // It's possible that there will be no instance, therefore
        !           421:    // the lnInstanceName would be NULL.
        !           422: 
        !           423:    if (pLine->lnObject.NumInstances > 0)
        !           424:       {
        !           425:       // Test for the parent object instance name title index.
        !           426:       // If there is one, it implies that there will be a valid
        !           427:       // Parent Object Name and a valid Parent Object Instance Name.
        !           428: 
        !           429:       // If the Parent Object title index is 0 then
        !           430:       // just display the instance name.
        !           431: 
        !           432:       lstrcpy (szInstance, pLine->lnInstanceName) ;
        !           433:       if (pLine->lnInstanceDef.ParentObjectTitleIndex &&
        !           434:           pLine->lnPINName)
        !           435:          {
        !           436:          // Get the Parent Object Name.
        !           437:          lstrcpy (szParent, pLine->lnPINName) ;
        !           438:          }
        !           439:       else
        !           440:          {
        !           441:          lstrcpy (szParent, szNoName) ;
        !           442:          }
        !           443:       }
        !           444:    else
        !           445:       {
        !           446:       lstrcpy (szInstance, szNoName) ;
        !           447:       lstrcpy (szParent, szNoName) ;
        !           448:       }
        !           449: 
        !           450:    //=============================//
        !           451:    // Draw Color                  //
        !           452:    //=============================//
        !           453: 
        !           454:    DrawColorCol (pLegend, pLine, LegendColorCol, hDC, yPos) ;
        !           455: 
        !           456:    //=============================//
        !           457:    // Draw Scale/Value            //
        !           458:    //=============================//
        !           459: 
        !           460:    if (pLegend->iLineType == LineTypeChart)
        !           461:       {
        !           462:       if (pLine->eScale < (FLOAT) 1.0)
        !           463:          {
        !           464:          TSPRINTF (szValue, TEXT("%6.6f"), pLine->eScale) ;
        !           465:          }
        !           466:       else
        !           467:          {
        !           468:          TSPRINTF (szValue, TEXT("%10.3f"), pLine->eScale) ;
        !           469:          }
        !           470:       }
        !           471:    else
        !           472:       {
        !           473:       FLOAT tempAlertValue ;
        !           474: 
        !           475:       tempAlertValue = pLine->eAlertValue ;
        !           476:       if (tempAlertValue < (FLOAT) 0.0)
        !           477:          {
        !           478:          tempAlertValue = -tempAlertValue ;
        !           479:          }
        !           480: 
        !           481:       if (tempAlertValue >= (FLOAT) 10000.0)
        !           482:          {
        !           483:          if (tempAlertValue < (FLOAT) 1.0E+8)
        !           484:             {
        !           485:             TSPRINTF (szValue, TEXT("%c%10.0f"),
        !           486:                pLine->bAlertOver ? TEXT('>') : TEXT('<'),
        !           487:                pLine->eAlertValue) ;
        !           488:             }
        !           489:          else
        !           490:             {
        !           491:             TSPRINTF (szValue, TEXT("%c%10.3e"),
        !           492:                pLine->bAlertOver ? TEXT('>') : TEXT('<'),
        !           493:                pLine->eAlertValue) ;
        !           494:             }
        !           495:          }
        !           496:       else
        !           497:          {
        !           498:          TSPRINTF (szValue, TEXT("%c%10.4f"),
        !           499:             pLine->bAlertOver ? TEXT('>') : TEXT('<'),
        !           500:             pLine->eAlertValue) ;
        !           501:          }
        !           502:       }
        !           503: 
        !           504:    SetTextAlign (hDC, TA_TOP) ;   
        !           505: 
        !           506:    DrawLegendCol (pLegend, LegendScaleCol,
        !           507:                   hDC, yPos, szValue) ;
        !           508: 
        !           509: 
        !           510:    //=============================//
        !           511:    // Draw Counter                //
        !           512:    //=============================//
        !           513: 
        !           514:    DrawLegendCol (pLegend, LegendCounterCol,
        !           515:                   hDC, yPos, pLine->lnCounterName) ;
        !           516: 
        !           517:    
        !           518:    //=============================//
        !           519:    // Draw Instance               //
        !           520:    //=============================//
        !           521: 
        !           522:    DrawLegendCol (pLegend, LegendInstanceCol,
        !           523:                   hDC, yPos, szInstance) ;
        !           524: 
        !           525:    //=============================//
        !           526:    // Draw Parent                 //
        !           527:    //=============================//
        !           528: 
        !           529:    DrawLegendCol (pLegend, LegendParentCol,  
        !           530:                   hDC, yPos, szParent) ;
        !           531: 
        !           532:    //=============================//
        !           533:    // Draw Object                 //
        !           534:    //=============================//
        !           535: 
        !           536:    DrawLegendCol (pLegend, LegendObjectCol,
        !           537:                   hDC, yPos, pLine->lnObjectName) ;
        !           538: 
        !           539:    //=============================//
        !           540:    // Draw System                 //
        !           541:    //=============================//
        !           542: 
        !           543:    DrawLegendCol (pLegend, LegendSystemCol,
        !           544:                   hDC, yPos, pLine->lnSystemName) ;
        !           545: 
        !           546:    }
        !           547: 
        !           548: 
        !           549: //==========================================================================//
        !           550: //                              Message Handlers                            //
        !           551: //==========================================================================//
        !           552: 
        !           553: 
        !           554: BOOL OnLegendCreate (HWND hWnd, LPCREATESTRUCT lpCS)
        !           555:    {
        !           556:    PLEGEND        pLegend ;
        !           557:    HDC            hDC ;
        !           558:    int            iCol ;
        !           559:    BOOL           bChartLegend ;
        !           560: 
        !           561:    bChartLegend = (lpCS->lpCreateParams) == (LPVOID) TRUE ;
        !           562: 
        !           563:    pLegend = AllocateLegendData (hWnd, bChartLegend) ;
        !           564: 
        !           565:    if (!pLegend)
        !           566:       return (FALSE) ;
        !           567: 
        !           568:    if (bChartLegend)
        !           569:       {
        !           570:       pLegend->iLineType = LineTypeChart ;
        !           571:       }
        !           572:    else
        !           573:       {
        !           574:       pLegend->iLineType = LineTypeAlert ;
        !           575:       }
        !           576: 
        !           577:    pLegend->hFontItems = hFontScales ;
        !           578:    pLegend->hFontLabels = hFontScalesBold ;
        !           579:    hDC = GetDC (hWnd) ;
        !           580: 
        !           581:    //=============================//
        !           582:    // Load Labels                 //
        !           583:    //=============================//
        !           584: 
        !           585:    StringLoad (IDS_LABELCOLOR, pLegend->aCols[LegendColorCol].szLabel) ;
        !           586:    if (pLegend->iLineType == LineTypeChart)
        !           587:       StringLoad (IDS_LABELSCALE, 
        !           588:                   pLegend->aCols[LegendScaleCol].szLabel) ;
        !           589:    else
        !           590:       StringLoad (IDS_LABELVALUE,
        !           591:                   pLegend->aCols[LegendScaleCol].szLabel) ;
        !           592:    StringLoad (IDS_LABELCOUNTER, pLegend->aCols[LegendCounterCol].szLabel) ;
        !           593:    StringLoad (IDS_LABELINSTANCE, pLegend->aCols[LegendInstanceCol].szLabel) ;
        !           594:    StringLoad (IDS_LABELPARENT, pLegend->aCols[LegendParentCol].szLabel) ;
        !           595:    StringLoad (IDS_LABELOBJECT, pLegend->aCols[LegendObjectCol].szLabel) ;
        !           596:    StringLoad (IDS_LABELSYSTEM, pLegend->aCols[LegendSystemCol].szLabel) ;
        !           597: 
        !           598: 
        !           599:    //=============================//
        !           600:    // Label dimensions            //
        !           601:    //=============================//
        !           602: 
        !           603:    SelectFont (hDC, pLegend->hFontLabels) ;
        !           604:    pLegend->yLabelHeight = FontHeight (hDC, TRUE) + 2 * LabelTopMargin () ;
        !           605: 
        !           606:    //=============================//
        !           607:    // Column dimensions           //
        !           608:    //=============================//
        !           609: 
        !           610:    for (iCol = 0 ;
        !           611:         iCol < iLegendNumCols ;
        !           612:         iCol++)
        !           613:       {  // for
        !           614:       pLegend->aCols[iCol].iOrientation = LEFTORIENTATION ;
        !           615:       pLegend->aCols[iCol].xMinWidth = 
        !           616:          TextWidth (hDC, pLegend->aCols[iCol].szLabel) + LegendHorzMargin () ;
        !           617:       }  // for
        !           618: 
        !           619:    SelectFont (hDC, pLegend->hFontItems) ;
        !           620:    pLegend->yItemHeight = FontHeight (hDC, TRUE) + 2 * LegendItemTopMargin () ;
        !           621: 
        !           622:    pLegend->aCols[LegendColorCol].xMaxWidth = max (3 * xScrollWidth,
        !           623:       pLegend->aCols[LegendColorCol].xMinWidth) ;
        !           624: 
        !           625:    pLegend->aCols[LegendScaleCol].xMaxWidth = TextWidth (hDC, eScaleValueSpace) ;
        !           626:    pLegend->aCols[LegendCounterCol].xMaxWidth = iLegendColMax ;
        !           627:    pLegend->aCols[LegendInstanceCol].xMaxWidth = iLegendColMax ;
        !           628:    pLegend->aCols[LegendParentCol].xMaxWidth = iLegendColMax ;
        !           629:    pLegend->aCols[LegendObjectCol].xMaxWidth = iLegendColMax ;
        !           630:    pLegend->aCols[LegendSystemCol].xMaxWidth = iLegendColMax ;
        !           631:    
        !           632:    pLegend->aCols[LegendColorCol].iOrientation = LEFTORIENTATION ;
        !           633:    pLegend->aCols[LegendScaleCol].iOrientation = RIGHTORIENTATION ;
        !           634: 
        !           635:    ReleaseDC (hWnd, hDC) ;   
        !           636: 
        !           637:    //=============================//
        !           638:    // Create Legend Items Listbox //
        !           639:    //=============================//
        !           640: 
        !           641:    pLegend->hWndItems =
        !           642:       CreateWindow (TEXT("ListBox"),               // window class
        !           643:                     NULL,                          // window caption
        !           644:                     dwGraphLegendItemsWindowStyle, // window style
        !           645:                     0, 0, 0, 0,                    // window size and pos
        !           646:                     hWnd,                          // parent window
        !           647:                     NULL,                          // menu
        !           648:                     hInstance,                     // program instance
        !           649:                     (LPVOID) TRUE) ;               // user-supplied data
        !           650:    }  // OnLegendCreate
        !           651:    
        !           652: 
        !           653: void static OnSize (HWND hWnd, int xWidth, int yHeight)
        !           654: /*
        !           655:    Effect:        Perform all actions necessary when the legend window is
        !           656:                   being resized. In particular, set the width and starting
        !           657:                   position for each column of the legend list and labels.
        !           658: 
        !           659:    Internals:     What we do is determine the amount of space in the
        !           660:                   width that is greater than the minimum, and allocate
        !           661:                   that space among each of the columns that is willing to
        !           662:                   be larger than minimum. If there is not enough room for
        !           663:                   the minimum, don't bother with calculations.
        !           664: */
        !           665: 
        !           666:    {  // OnSize
        !           667:    PLEGEND        pLegend ;
        !           668:    PLEGENDCOL     pCol ;
        !           669:    int            xMin ;
        !           670:    int            xSlack ;
        !           671:    int            iColsToGrow ;
        !           672:    int            iCol ;
        !           673: 
        !           674:    pLegend = LegendData (hWnd) ;
        !           675: 
        !           676:    //=============================//
        !           677:    // Resize Legend Items         //
        !           678:    //=============================//
        !           679: 
        !           680:    if (IsLegendLabelVisible ())
        !           681:       MoveWindow (pLegend->hWndItems, 
        !           682:                   LegendLeftMargin (), pLegend->yLabelHeight + ThreeDPad,
        !           683:                   xWidth - 2 * LegendLeftMargin (),
        !           684:                   yHeight - pLegend->yLabelHeight - yLegendBorderHeight,
        !           685:                   TRUE) ;
        !           686:    else
        !           687:       MoveWindow (pLegend->hWndItems,
        !           688:                   0, 0, 
        !           689:                   xWidth, yHeight,
        !           690:                   TRUE) ;
        !           691:                   
        !           692:       
        !           693:    //=============================//
        !           694:    // Allocate width to Columns   //
        !           695:    //=============================//
        !           696: 
        !           697:    xMin = LegendMinWidth (hWnd) ;
        !           698:    xSlack = max (xWidth - xMin, 0) ;
        !           699:    iColsToGrow = 0 ;
        !           700: 
        !           701:    for (iCol = 0 ;
        !           702:         iCol < iLegendNumCols ;
        !           703:         iCol++)
        !           704:       {  // for
        !           705:       pCol = &(pLegend->aCols[iCol]) ;
        !           706: 
        !           707:       pCol->xWidth = pCol->xMinWidth ;
        !           708:       if (ColCanGrow (pCol))
        !           709:          iColsToGrow++ ;
        !           710:       }  // for
        !           711: 
        !           712:    for (iCol = 0 ;
        !           713:         iCol < iLegendNumCols ;
        !           714:         iCol++)
        !           715:       {  // for
        !           716:       pCol = &(pLegend->aCols[iCol]) ;
        !           717: 
        !           718:       if (ColCanGrow (pCol))
        !           719:          {
        !           720:          if ((pCol->xWidth + xSlack / iColsToGrow) >
        !           721:              pCol->xMaxWidth)
        !           722:             {  // if
        !           723:             pCol->xWidth = pCol->xMaxWidth ;
        !           724:             xSlack -= (pCol->xMaxWidth - pCol->xMinWidth) ;
        !           725:             iColsToGrow-- ;
        !           726:             }  // if
        !           727:          }  // if
        !           728:       }  // for
        !           729: 
        !           730:    for (iCol = 0 ;
        !           731:         iCol < iLegendNumCols ;
        !           732:         iCol++)
        !           733:       {  // for
        !           734:       pCol = &(pLegend->aCols[iCol]) ;
        !           735: 
        !           736:       if (ColCanGrow (pCol))
        !           737:         pCol->xWidth += xSlack / iColsToGrow ;
        !           738:       }  // for
        !           739: 
        !           740:    if (pLegend->aCols[LegendCounterCol].xWidth <
        !           741:       pLegend->aCols[LegendCounterCol].xMaxWidth)
        !           742:       {
        !           743:       // cut some from the other columns and give them to CounterCol
        !           744:       if (pLegend->aCols[LegendColorCol].xWidth - xScrollWidth >=
        !           745:           pLegend->aCols[LegendColorCol].xMinWidth)
        !           746:          {
        !           747:          pLegend->aCols[LegendColorCol].xWidth -= xScrollWidth ;      
        !           748:          pLegend->aCols[LegendCounterCol].xWidth += xScrollWidth ;
        !           749:          }
        !           750:       if (pLegend->aCols[LegendInstanceCol].xWidth - xScrollWidth >=
        !           751:           pLegend->aCols[LegendInstanceCol].xMinWidth)
        !           752:          {
        !           753:          pLegend->aCols[LegendInstanceCol].xWidth -= xScrollWidth ;      
        !           754:          pLegend->aCols[LegendCounterCol].xWidth += xScrollWidth ;
        !           755:          }
        !           756:       if (pLegend->aCols[LegendParentCol].xWidth - xScrollWidth >=
        !           757:           pLegend->aCols[LegendParentCol].xMinWidth)
        !           758:          {
        !           759:          pLegend->aCols[LegendParentCol].xWidth -= xScrollWidth ;      
        !           760:          pLegend->aCols[LegendCounterCol].xWidth += xScrollWidth ;
        !           761:          }
        !           762:       }
        !           763: 
        !           764:    
        !           765:    //=============================//
        !           766:    // Set Column positions        //
        !           767:    //=============================//
        !           768: 
        !           769:    pLegend->aCols[0].xPos = LegendLeftMargin () ;
        !           770:    for (iCol = 1 ;
        !           771:         iCol < iLegendNumCols ;
        !           772:         iCol++)
        !           773:       {  // for
        !           774:       pLegend->aCols[iCol].xPos = 
        !           775:          pLegend->aCols[iCol - 1].xPos + pLegend->aCols[iCol - 1].xWidth ;
        !           776: 
        !           777:       if (iCol == LegendCounterCol)
        !           778:          {
        !           779:          // add some space between Scale/Value col & Counter col
        !           780:          pLegend->aCols[LegendCounterCol].xPos += LegendLeftMargin () ;
        !           781:          }
        !           782:       }  // for
        !           783: 
        !           784:    }  // OnSize
        !           785: 
        !           786: 
        !           787: void static OnPaint (HWND hWnd)
        !           788:    {  // OnPaint
        !           789:    PLEGEND        pLegend ;
        !           790:    HDC            hDC ;
        !           791:    PAINTSTRUCT    ps ;
        !           792: 
        !           793:    hDC = BeginPaint (hWnd, &ps) ;
        !           794: 
        !           795:    if (IsLegendLabelVisible ())
        !           796:       {
        !           797:       pLegend = LegendData (hWnd) ;
        !           798:       DrawLegendLabel (pLegend, hDC, hWnd) ;
        !           799:       }
        !           800: 
        !           801: 
        !           802:    EndPaint (hWnd, &ps) ;
        !           803:    }  // OnPaint
        !           804: 
        !           805: 
        !           806: void OnDrawLegendItem (HWND hWnd,
        !           807:                         LPDRAWITEMSTRUCT lpDI)
        !           808:    {  // OnDrawItem
        !           809:    HFONT          hFontPrevious ;
        !           810:    HDC            hDC ;
        !           811:    PLEGEND        pLegend ;
        !           812:    PLINESTRUCT    pLine ;
        !           813:    int            iLBIndex ;
        !           814:    COLORREF       preBkColor ;
        !           815:    COLORREF       preTextColor ;
        !           816: 
        !           817:    
        !           818:    hDC = lpDI->hDC ;
        !           819:    iLBIndex = DIIndex (lpDI) ;
        !           820: 
        !           821:    pLegend = LegendData (hWnd) ;
        !           822: 
        !           823:    if (iLBIndex == -1)
        !           824:       pLine = NULL ;
        !           825:    else
        !           826:       pLine = (PLINESTRUCT) LBData (pLegend->hWndItems, iLBIndex) ;
        !           827: 
        !           828:    //=============================//
        !           829:    // Set DC attributes           //
        !           830:    //=============================//
        !           831: 
        !           832: 
        !           833:    if (DISelected (lpDI))
        !           834:       {  // if
        !           835:       preTextColor = SetTextColor (hDC, GetSysColor (COLOR_HIGHLIGHTTEXT)) ;
        !           836:       preBkColor = SetBkColor (hDC, GetSysColor (COLOR_HIGHLIGHT)) ;
        !           837:       }  // if
        !           838:    ExtTextOut (hDC, lpDI->rcItem.left, lpDI->rcItem.top,
        !           839:       ETO_OPAQUE, &(lpDI->rcItem), NULL, 0, NULL ) ;
        !           840:    
        !           841: 
        !           842:    //=============================//
        !           843:    // Draw Legend Item            //
        !           844:    //=============================//
        !           845: 
        !           846:    hFontPrevious = SelectFont (hDC, pLegend->hFontItems) ;
        !           847:    if (pLine)
        !           848:       DrawLegendItem (pLegend, pLine, lpDI->rcItem.top, hDC) ;
        !           849:    SelectFont (hDC, hFontPrevious) ;
        !           850: 
        !           851:    //=============================//
        !           852:    // Draw Focus                  //
        !           853:    //=============================//
        !           854: 
        !           855:    if (DIFocus (lpDI))
        !           856:       DrawFocusRect (hDC, &(lpDI->rcItem)) ;
        !           857: 
        !           858: 
        !           859:    if (DISelected (lpDI))
        !           860:       {  // if
        !           861:       preTextColor = SetTextColor (hDC, preTextColor) ;
        !           862:       preBkColor = SetBkColor (hDC, preBkColor) ;
        !           863:       }  // if
        !           864:    }  // OnDrawItem
        !           865: 
        !           866: 
        !           867: void static OnMeasureItem (HWND hWnd,
        !           868:                            LPMEASUREITEMSTRUCT lpMI)
        !           869:    {  // OnMeasureItem
        !           870:    PLEGEND        pLegend ;
        !           871: 
        !           872:    pLegend = LegendData (hWnd) ;
        !           873:    lpMI->itemHeight = pLegend->yItemHeight ;
        !           874:    }  // OnMeasureItem
        !           875: 
        !           876: 
        !           877: void static OnDestroy (HWND hWnd)
        !           878:    {
        !           879:    PLEGEND        pLegend ;
        !           880: 
        !           881:    pLegend = LegendData (hWnd) ;
        !           882:    MemoryFree (pLegend) ;
        !           883:    }  // OnDestroy
        !           884: 
        !           885: 
        !           886: 
        !           887: void static OnDoubleClick (HWND hWnd)
        !           888:    {
        !           889:    PLEGEND        pLegend ;
        !           890: 
        !           891:    pLegend = LegendData (hWnd) ;
        !           892:    if (!pLegend)
        !           893:       return ;
        !           894: 
        !           895:    switch (pLegend->iLineType)
        !           896:       {  // switch
        !           897:       case LineTypeChart:
        !           898:          EditChart (hWndMain) ;
        !           899:          break ;
        !           900: 
        !           901:       case LineTypeAlert:
        !           902:          EditAlert (hWndAlert) ;
        !           903:          break ;
        !           904:       }  // switch
        !           905:    }  // OnDoubleClick
        !           906: 
        !           907: 
        !           908: 
        !           909: void static OnSelectionChanged (HWND hWnd)
        !           910:    {  // OnSelectionChanged
        !           911:    PLEGEND        pLegend ;
        !           912:    PGRAPHSTRUCT         pGraph ;
        !           913:    int            iIndex ;
        !           914: 
        !           915: 
        !           916:    pLegend = LegendData (hWnd) ;
        !           917: 
        !           918:    // set the new selected line
        !           919:    iIndex = LBSelection (pLegend->hWndItems) ;
        !           920: 
        !           921:    if (iIndex == LB_ERR)
        !           922:       return ;
        !           923: 
        !           924:    LegendSetCurrentLine (pLegend, iIndex) ;
        !           925: 
        !           926:    if (pLegend->iLineType == LineTypeChart)
        !           927:       {
        !           928:       pGraph = GraphData (hWndGraph) ;
        !           929:       
        !           930:       if (!PlayingBackLog())
        !           931:          {
        !           932:          // update the min, max, & avg of the current line
        !           933:          UpdateValueBarData (pGraph) ;
        !           934:          }
        !           935: 
        !           936:       // update the valuebar display
        !           937:       StatusTimer (hWndGraphStatus, TRUE) ;
        !           938: 
        !           939:       // change the Current highlighted line if necessary
        !           940:       if (pGraph && pGraph->HighLightOnOff)
        !           941:          {
        !           942:          WindowInvalidate (hWndGraphDisplay) ;
        !           943:          }
        !           944:       }
        !           945:    }  // OnSelectionChanged
        !           946: 
        !           947: 
        !           948: //==========================================================================//
        !           949: //                             Exported Functions                           //
        !           950: //==========================================================================//
        !           951: 
        !           952: 
        !           953: LRESULT APIENTRY GraphLegendWndProc (HWND hWnd,
        !           954:                                      WORD wMsg,
        !           955:                                      WPARAM wParam,
        !           956:                                      LONG lParam)
        !           957:    {  // GraphLegendWndProc
        !           958:    BOOL           bCallDefProc ;
        !           959:    LRESULT        lReturnValue ;
        !           960: 
        !           961: 
        !           962:    bCallDefProc = FALSE ;
        !           963:    lReturnValue = 0L ;
        !           964: 
        !           965:    switch (wMsg)
        !           966:       {  // switch
        !           967:       case WM_DELETEITEM:
        !           968:          break ;
        !           969: 
        !           970:       case WM_COMMAND:
        !           971:          switch (HIWORD (wParam))
        !           972:             {  // switch
        !           973:             case LBN_DBLCLK:
        !           974:                OnDoubleClick (hWnd) ;
        !           975:                break ;
        !           976: 
        !           977:             case LBN_SELCHANGE:
        !           978:                OnSelectionChanged (hWnd) ;
        !           979:                break ;
        !           980: 
        !           981:             default:
        !           982:                break ;
        !           983:             }  // switch
        !           984:          break ;
        !           985: 
        !           986:       case WM_CREATE:
        !           987:          OnLegendCreate (hWnd, (LPCREATESTRUCT) lParam) ;
        !           988:          break ;
        !           989: 
        !           990:       case WM_DESTROY:
        !           991:          OnDestroy (hWnd) ;
        !           992:          break ;
        !           993: 
        !           994:       case WM_DRAWITEM:
        !           995:          OnDrawLegendItem (hWnd, (LPDRAWITEMSTRUCT) lParam) ;
        !           996:          break ;
        !           997: 
        !           998:       case WM_MEASUREITEM:
        !           999:          OnMeasureItem (hWnd, (LPMEASUREITEMSTRUCT) lParam) ;
        !          1000:          break ;
        !          1001: 
        !          1002:       case WM_PAINT:
        !          1003:          OnPaint (hWnd) ;
        !          1004:          break ;
        !          1005: 
        !          1006:       case WM_SIZE:
        !          1007:          OnSize (hWnd, LOWORD (lParam), HIWORD (lParam)) ;
        !          1008:          break ;
        !          1009: 
        !          1010:       default:
        !          1011:          bCallDefProc = TRUE ;
        !          1012:       }  // switch
        !          1013: 
        !          1014: 
        !          1015:    if (bCallDefProc)
        !          1016:       lReturnValue = DefWindowProc (hWnd, wMsg, wParam, lParam) ;
        !          1017: 
        !          1018:    return (lReturnValue);
        !          1019:    }  // GraphLegendWndProc
        !          1020: 
        !          1021: 
        !          1022: int LegendMinWidth (HWND hWnd)
        !          1023:    {
        !          1024:    PLEGEND        pLegend ;
        !          1025:    int            iCol ;
        !          1026:    int            xMinWidth ;
        !          1027: 
        !          1028:    pLegend = LegendData (hWnd) ;
        !          1029:    xMinWidth = 0 ;
        !          1030: 
        !          1031:    for (iCol = 0 ;
        !          1032:         iCol < iLegendNumCols ;
        !          1033:         iCol++)
        !          1034:       {  // for
        !          1035:       xMinWidth += pLegend->aCols[iCol].xMinWidth ;
        !          1036:       }  // for
        !          1037: 
        !          1038:    return (xMinWidth) ;
        !          1039:    }
        !          1040: 
        !          1041: 
        !          1042: int LegendMinHeight (HWND hWnd)
        !          1043:    {
        !          1044:    PLEGEND        pLegend ;
        !          1045: 
        !          1046:    pLegend = LegendData (hWnd) ;
        !          1047: 
        !          1048:    if (IsLegendLabelVisible ())
        !          1049:       return (pLegend->yLabelHeight + pLegend->yItemHeight) ;
        !          1050:    else
        !          1051:       return (pLegend->yItemHeight) ;
        !          1052:    }
        !          1053: 
        !          1054: 
        !          1055: int LegendHeight (HWND hWnd, int yGraphHeight)
        !          1056: /*
        !          1057:    Effect:        Return the best height for the Legend window given the 
        !          1058:                   number of items and label visibility of the legend, as
        !          1059:                   well as the overall height of the graph.
        !          1060: */
        !          1061:    {  // LegendHeight
        !          1062:    PLEGEND        pLegend ;
        !          1063:    int            yPreferredHeight ;
        !          1064: 
        !          1065:    pLegend = LegendData (hWnd) ;
        !          1066: 
        !          1067:    yPreferredHeight = yLegendBorderHeight +
        !          1068:                       pLegend->yItemHeight * 
        !          1069:                       PinInclusive (LBNumItems (pLegend->hWndItems),
        !          1070:                                     1, iLegendMaxVisibleItems) ;
        !          1071:    if (IsLegendLabelVisible ())
        !          1072:       yPreferredHeight += pLegend->yLabelHeight ;
        !          1073: 
        !          1074:    return (min (yPreferredHeight, yGraphHeight / 2)) ;
        !          1075:    }  // LegendHeight
        !          1076: 
        !          1077: 
        !          1078: 
        !          1079: int LegendFullHeight (HWND hWnd, HDC hDC)
        !          1080: /*
        !          1081:    Effect:        Return the best height for the Legend window given the 
        !          1082:                   number of items and label visibility of the legend, as
        !          1083:                   well as the overall height of the graph.
        !          1084: */
        !          1085:    {  // LegendHeight
        !          1086:    PLEGEND        pLegend ;
        !          1087:    int            yPreferredHeight ;
        !          1088: 
        !          1089:    pLegend = LegendData (hWnd) ;
        !          1090: 
        !          1091:    yPreferredHeight = yLegendBorderHeight +
        !          1092:                       pLegend->yItemHeight * 
        !          1093:                       LBNumItems (pLegend->hWndItems) ;
        !          1094:    if (IsLegendLabelVisible ())
        !          1095:       yPreferredHeight += pLegend->yLabelHeight ;
        !          1096: 
        !          1097:    return (yPreferredHeight) ;
        !          1098:    }  // LegendFullHeight
        !          1099: 
        !          1100: 
        !          1101: 
        !          1102: 
        !          1103: HWND CreateGraphLegendWindow (HWND hWndGraph)
        !          1104:    {
        !          1105:    return (CreateWindow (szGraphLegendClass,       // class
        !          1106:                          NULL,                     // caption
        !          1107:                          dwGraphLegendWindowStyle, // window style
        !          1108:                          0, 0,                     // position
        !          1109:                          0, 0,                     // size
        !          1110:                          hWndGraph,                // parent window
        !          1111:                          NULL,                     // menu
        !          1112:                          hInstance,                // program instance
        !          1113:                          (LPVOID) TRUE)) ;         // user-supplied data
        !          1114:    }
        !          1115: 
        !          1116: 
        !          1117: BOOL GraphLegendInitializeApplication (void)
        !          1118: /*
        !          1119:    Called By:     GraphInitializeApplication only
        !          1120: */
        !          1121:    {
        !          1122:    WNDCLASS       wc ;
        !          1123: 
        !          1124:    wc.style          = dwGraphLegendClassStyle ;
        !          1125:    wc.lpfnWndProc    = (WNDPROC) GraphLegendWndProc ;
        !          1126:    wc.hInstance      = hInstance ;
        !          1127:    wc.cbClsExtra     = iGraphLegendClassExtra ;
        !          1128:    wc.cbWndExtra     = iGraphLegendWindowExtra ;
        !          1129:    wc.hIcon          = NULL ;
        !          1130:    wc.hCursor        = LoadCursor (NULL, IDC_ARROW) ;
        !          1131:    wc.hbrBackground  = hbLightGray ;
        !          1132:    wc.lpszMenuName   = NULL ;
        !          1133:    wc.lpszClassName  = szGraphLegendClass ;
        !          1134: 
        !          1135:    return (RegisterClass (&wc)) ;
        !          1136:    }
        !          1137: 
        !          1138: 
        !          1139: BOOL LegendAddItem (HWND hWnd, PLINESTRUCT pLine)
        !          1140: /*
        !          1141:    Effect:        Add a legend entry for the line pLine. Don't select
        !          1142:                   the line as current entry here, because this will cause
        !          1143:                   the scroll bar to unneccesarily appear for a moment.
        !          1144:                   If you want this line to be the current line, resize 
        !          1145:                   the legend first, then set as current line.
        !          1146: 
        !          1147:    See Also:      ChartInsertLine, AlertInsertLine.                  
        !          1148: */
        !          1149:    {  // LegendAddItem
        !          1150:    PLEGEND        pLegend ;
        !          1151: 
        !          1152:    pLegend = LegendData (hWnd) ;
        !          1153:    LBAdd (pLegend->hWndItems, pLine) ;
        !          1154: 
        !          1155:    return (TRUE) ;
        !          1156:    }  // LegendAddItem
        !          1157: 
        !          1158: 
        !          1159: void LegendDeleteItem (HWND hWndLegend, 
        !          1160:                        PLINE pLine)
        !          1161:    {  // LegendDeleteItem
        !          1162:    PLEGEND        pLegend ;
        !          1163:    int            iIndex ;
        !          1164:    int            iNextIndex ;
        !          1165:    int            iNumItems ;
        !          1166:    PGRAPHSTRUCT   pGraph ;
        !          1167: 
        !          1168:    pLegend = LegendData (hWndLegend) ;
        !          1169:    if (!pLegend)
        !          1170:       return ;
        !          1171: 
        !          1172:    iNumItems = LBNumItems (pLegend->hWndItems) ;
        !          1173: 
        !          1174:    iIndex = LBFind (pLegend->hWndItems, pLine) ;
        !          1175: 
        !          1176:    if (iIndex != LB_ERR)
        !          1177:       {
        !          1178:       LBDelete (pLegend->hWndItems, iIndex) ;
        !          1179:       }
        !          1180: 
        !          1181:    // no need to do anything if iNumItems is 1 to begin with
        !          1182:    if (iNumItems != LB_ERR && iNumItems > 1)
        !          1183:       {
        !          1184:       if (iIndex == iNumItems - 1)
        !          1185:          {
        !          1186:          // deleting the last line, then set selection
        !          1187:          // to the previous legend line
        !          1188:          iNextIndex = iIndex - 1 ;
        !          1189:          }
        !          1190:       else
        !          1191:          {
        !          1192:          // set the selection to the next legend line
        !          1193:          iNextIndex = iIndex ;
        !          1194:          }
        !          1195: 
        !          1196:       LBSetSelection (pLegend->hWndItems, iNextIndex) ;
        !          1197:       LegendSetCurrentLine (pLegend, iNextIndex) ;
        !          1198: 
        !          1199:       if (pLegend->iLineType == LineTypeChart)
        !          1200:          {
        !          1201:          // update the min, max, & avg of the current line
        !          1202:          pGraph = GraphData (hWndGraph) ;
        !          1203: 
        !          1204:          if (!PlayingBackLog())
        !          1205:             {
        !          1206:             // update the min, max, & avg of the current line
        !          1207:             UpdateValueBarData (pGraph) ;
        !          1208:             }
        !          1209:    
        !          1210:          // update the valuebar display
        !          1211:          StatusTimer (hWndGraphStatus, TRUE) ;
        !          1212:          }
        !          1213:       }
        !          1214: 
        !          1215:    }  // LegendDeleteItem
        !          1216: 
        !          1217: 
        !          1218: PLINE LegendCurrentLine (HWND hWndLegend)
        !          1219:    {  // LegendCurrentLine
        !          1220:    PLEGEND        pLegend ;
        !          1221: 
        !          1222:    pLegend = LegendData (hWndLegend) ;
        !          1223: 
        !          1224:    if (!pLegend)
        !          1225:       return (NULL) ;
        !          1226: 
        !          1227:    return (pLegend->pCurrentLine) ;
        !          1228: 
        !          1229:    }  // LegendCurrentLine
        !          1230: 
        !          1231: 
        !          1232: 
        !          1233: int LegendNumItems (HWND hWndLegend)
        !          1234:    {  // LegendNumItems
        !          1235:    PLEGEND        pLegend ;
        !          1236: 
        !          1237:    pLegend = LegendData (hWndLegend) ;
        !          1238: 
        !          1239:    return (LBNumItems (pLegend->hWndItems)) ;
        !          1240:    }  // LegendNumItems
        !          1241: 
        !          1242: 
        !          1243: 
        !          1244: void LegendSetSelection (HWND hWndLegend, int iIndex)
        !          1245:    {  // LegendSetSelection
        !          1246:    PLEGEND        pLegend ;
        !          1247: 
        !          1248:    pLegend = LegendData (hWndLegend) ;
        !          1249:    LBSetSelection (pLegend->hWndItems, iIndex) ;
        !          1250:    LegendSetCurrentLine (pLegend, iIndex) ;
        !          1251:    }  // LegendSetSelection   
        !          1252: 
        !          1253: 
        !          1254: 
        !          1255: #ifdef KEEP_PRINT
        !          1256: 
        !          1257: void PrintLegend (HDC hDC, PGRAPHSTRUCT pGraph, HWND hWndLegend,
        !          1258:                   RECT rectLegend)
        !          1259:    {
        !          1260:    PLEGEND        pLegend ;
        !          1261:    int            yItemHeight ;
        !          1262:    HFONT          hFontItems ;
        !          1263:    PLINE          pLine ;
        !          1264:    int            iIndex ;
        !          1265:    int            iIndexNum ;
        !          1266: 
        !          1267: 
        !          1268:    pLegend = LegendData (hWndLegend) ;
        !          1269: 
        !          1270:    yItemHeight = pLegend->yItemHeight ;
        !          1271:    hFontItems = pLegend->hFontItems ;
        !          1272: 
        !          1273:    pLegend->hFontItems = hFontPrinterScales ;
        !          1274:    SelectFont (hDC, pLegend->hFontItems) ;
        !          1275: 
        !          1276:    pLegend->yItemHeight = FontHeight (hDC, TRUE) ;
        !          1277: 
        !          1278:    iIndexNum = LBNumItems (pLegend->hWndItems) ;
        !          1279:    for (iIndex = 0 ;
        !          1280:         iIndex < iIndexNum ;
        !          1281:         iIndex++)
        !          1282:       {  // for
        !          1283:       pLine = (PLINE) LBData (pLegend->hWndItems, iIndex) ;
        !          1284:       DrawLegendItem (pLegend, pLine, iIndex * pLegend->yItemHeight, hDC) ;
        !          1285:       }  // for
        !          1286: 
        !          1287:    pLegend->hFontItems = hFontItems ;
        !          1288:    pLegend->yItemHeight = yItemHeight ;
        !          1289: 
        !          1290: 
        !          1291:    SelectBrush (hDC, GetStockObject (HOLLOW_BRUSH)) ;
        !          1292:    SelectPen (hDC, GetStockObject (BLACK_PEN)) ;
        !          1293:    Rectangle (hDC, 0, 0, 
        !          1294:               rectLegend.right - rectLegend.left,
        !          1295:               rectLegend.bottom - rectLegend.top) ;
        !          1296:    }
        !          1297: #endif
        !          1298: 
        !          1299: 
        !          1300: void ClearLegend (HWND hWndLegend)
        !          1301:    {
        !          1302:    PLEGEND        pLegend ;
        !          1303: 
        !          1304:    pLegend = LegendData (hWndLegend) ;
        !          1305:    if (!pLegend)
        !          1306:       return ;
        !          1307: 
        !          1308:    LBReset (pLegend->hWndItems) ;
        !          1309:    pLegend->pCurrentLine = NULL ;
        !          1310:    }
        !          1311: 
        !          1312: void LegendSetRedraw (HWND hWndLegend, BOOL bRedraw)
        !          1313:    {
        !          1314:    PLEGEND        pLegend ;
        !          1315: 
        !          1316:    pLegend = LegendData (hWndLegend) ;
        !          1317:    if (!pLegend)
        !          1318:       return ;
        !          1319: 
        !          1320:    LBSetRedraw (pLegend->hWndItems, bRedraw) ;
        !          1321: }
        !          1322: 
        !          1323: 

unix.superglobalmegacorp.com

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