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