Annotation of mstools/samples/sdktools/perfmon/alert.c, revision 1.1.1.1

1.1       root        1: //==========================================================================//
                      2: //                                  Includes                                //
                      3: //==========================================================================//
                      4: 
                      5: #include <stdio.h>
                      6: #include "perfmon.h"
                      7: #include "alert.h"         // External declarations for this file
                      8: 
                      9: #include "addline.h"       // for AddLine
                     10: #include "fileutil.h"      // for FileRead
                     11: #include "legend.h"
                     12: #include "line.h"
                     13: #include "pmemory.h"       // for MemoryXXX (mallloc-type) routines
                     14: #include "owndraw.h"       // for OwnerDraw macros
                     15: #include "perfdata.h"      // for UpdateLines
                     16: #include "perfmops.h"      // for SystemAdd
                     17: #include "playback.h"      // for PlaybackLines
                     18: #include "status.h"        // for StatusUpdateAlerts   
                     19: #include "system.h"        // for SystemGet
                     20: #include "utils.h"
                     21: #include "menuids.h"       // for IDM_VIEWALERT
                     22: #include "fileopen.h"      // for FileGetName
                     23: 
                     24: #include <lmcons.h>
                     25: #include <lmmsg.h>
                     26: #include <lmerr.h>
                     27: 
                     28: #define WM_SEND_NETWORK_ALERT (WM_USER + 101)
                     29: 
                     30: //==========================================================================//
                     31: //                                  Typedefs                                //
                     32: //==========================================================================//
                     33: 
                     34: typedef NET_API_STATUS
                     35: (*pNetMessageBufferSend) (
                     36:     IN  LPTSTR  servername,
                     37:     IN  LPTSTR  msgname,
                     38:     IN  LPTSTR  fromname,
                     39:     IN  LPBYTE  buf,
                     40:     IN  DWORD   buflen
                     41:     );
                     42: 
                     43: typedef struct ALERTENTRYSTRUCT
                     44:    {
                     45:    SYSTEMTIME     SystemTime ;
                     46:    PLINE          pLine ;
                     47:    FLOAT          eValue ;
                     48:    BOOL           bOver ;
                     49:    FLOAT          eAlertValue ;
                     50:    LPTSTR         lpszInstance ;
                     51:    LPTSTR         lpszParent ;
                     52:    INT            StringWidth ;
                     53:    } ALERTENTRY ;
                     54: 
                     55: typedef ALERTENTRY *PALERTENTRY ;
                     56: 
                     57: //====
                     58: //====
                     59: 
                     60: //==========================================================================//
                     61: //                                  Constants                               //
                     62: //==========================================================================//
                     63: 
                     64: 
                     65: #define szNumberFormat         TEXT("%12.3f")
                     66: #define szMediumnNumberFormat  TEXT("%12.0f")
                     67: #define szLargeNumberFormat    TEXT("%12.4e")
                     68: #define eNumber                ((FLOAT) 99999999.999)
                     69: #define eLargeNumber           ((FLOAT) 999999999999.0)
                     70: 
                     71: #define szNumberPrototype        TEXT("99999999.999")
                     72: 
                     73: 
                     74: #define szConditionFormat        TEXT("  %c  ")
                     75: #define szConditionPrototype     TEXT("  >  ")
                     76: 
                     77: #define szDatePrototype          TEXT("12/31/1999   ")
                     78: #define szTimePrototype          TEXT("12:34:56.9 pm  ")
                     79: 
                     80: #define ALERTLOGMAXITEMS         1000
                     81: 
                     82: #define szAlertFormat TEXT("%s %s %12.3f %c %12.3f %s,  %s,  %s,  %s,  %s")
                     83: 
                     84: 
                     85: //==========================================================================//
                     86: //                                   Macros                                 //
                     87: //==========================================================================//
                     88: 
                     89: 
                     90: #define AlertItemTopMargin()     (yBorderHeight)
                     91: 
                     92: 
                     93: 
                     94: //==========================================================================//
                     95: //                              Local Functions                             //
                     96: //==========================================================================//
                     97: INT ExportAlertLine (PLINE pLine, FLOAT eValue, SYSTEMTIME *pSystemTime, HANDLE hExportFile) ;
                     98: 
                     99: #if 0
                    100: PALERT AlertData (HWND hWndAlert)
                    101:    {
                    102:    return (&Alert) ;
                    103:    }
                    104: #endif
                    105: 
                    106: PALERT AllocateAlertData (HWND hWndAlert)
                    107:    {
                    108:    PALERT           pAlert ;
                    109: 
                    110:    pAlert = AlertData (hWndAlert) ;
                    111: 
                    112:    pAlert->hWnd = hWndAlert ;
                    113:    pAlert->hAlertListBox = DialogControl (hWndAlert, IDD_ALERTLOG) ;
                    114:    pAlert->iStatus = iPMStatusClosed ;
                    115:    pAlert->bManualRefresh = FALSE ;
                    116:    pAlert->bModified = FALSE ;
                    117: 
                    118:    pAlert->Visual.iColorIndex = 0 ;
                    119:    pAlert->Visual.iWidthIndex = -1 ;
                    120:    pAlert->Visual.iStyleIndex = -1 ;
                    121: 
                    122:    pAlert->iIntervalMSecs = iDefaultAlertIntervalSecs * 1000 ;
                    123:    pAlert->pSystemFirst = NULL ;
                    124:    pAlert->pLineFirst = NULL ;
                    125: 
                    126:    pAlert->MessageName[0] = TEXT('\0') ;
                    127: 
                    128:    return (pAlert) ;
                    129:    }  // AllocateAlertData
                    130: 
                    131: 
                    132: void FreeAlertData (PALERT pAlert)
                    133:    {  // FreeAlertData
                    134:    }  // FreeAlertData
                    135: 
                    136: 
                    137: BOOL SetAlertTimer (PALERT pAlert)
                    138:    {
                    139:    if (pAlert->iStatus == iPMStatusCollecting)
                    140:       KillTimer (pAlert->hWnd, AlertTimerID) ;
                    141: 
                    142:    pAlert->iStatus = iPMStatusCollecting ;
                    143:    SetTimer (pAlert->hWnd, AlertTimerID, pAlert->iIntervalMSecs, NULL) ;
                    144:    return (TRUE) ;
                    145:    }
                    146: 
                    147: 
                    148: BOOL ClearAlertTimer (PALERT pAlert)
                    149:    {  // ClearAlertTimer
                    150:    if (!PlayingBackLog())
                    151:       {
                    152:       KillTimer (pAlert->hWnd, AlertTimerID) ;
                    153:       }
                    154:    pAlert->iStatus = iPMStatusClosed ;
                    155: 
                    156:    return (TRUE) ;
                    157:    }  // ClearAlertTimer
                    158: 
                    159: 
                    160: BOOL AlertExec (LPTSTR lpszImageName, LPTSTR lpszCommandLine)
                    161: /*
                    162:    Effect:        WinExec is considered obsolete. We're supposed to use
                    163:                   CreateProcess, which allows considerably more control.
                    164:                   For perfmon, we only execute a program when an alert
                    165:                   occurs, and we really don't know anything about the
                    166:                   program, so can't really do much.  We just set some
                    167:                   defaults and go.
                    168: 
                    169:    Called By:     SignalAlert only.
                    170: */
                    171:    {  // ExecProcess
                    172:    STARTUPINFO    si ;
                    173:    PROCESS_INFORMATION  pi ;
                    174:    int            StringLen ;
                    175:    TCHAR          TempBuffer [ 2 * FilePathLen ] ;
                    176: 
                    177:    memset (&si, 0, sizeof (STARTUPINFO)) ;
                    178:    si.cb = sizeof (STARTUPINFO) ;
                    179:    
                    180:    memset (&pi, 0, sizeof (PROCESS_INFORMATION)) ;
                    181: 
                    182:    lstrcpy (TempBuffer, lpszImageName) ;
                    183:    StringLen = lstrlen (TempBuffer) ;
                    184:    TempBuffer [StringLen] = TEXT(' ') ;
                    185:    StringLen++ ;
                    186:    lstrcpy (&TempBuffer[StringLen], lpszCommandLine) ;
                    187: 
                    188:    return (CreateProcess (NULL, TempBuffer,
                    189:                           NULL, NULL, FALSE,
                    190:                           (DWORD) NORMAL_PRIORITY_CLASS,
                    191:                           NULL, NULL,
                    192:                           &si, &pi)) ;
                    193: 
                    194:    }  // ExecProcess
                    195: 
                    196: 
                    197: BOOL SendNetworkMessage (LPTSTR pText, DWORD TextLen, LPTSTR pMessageName)
                    198: {
                    199:    NET_API_STATUS NetStatus;
                    200:    HANDLE dllHandle ;
                    201:    pNetMessageBufferSend SendFunction ;
                    202: 
                    203:    //
                    204:    // Dynamically link to netapi32.dll.  If it's not there just return.  Return
                    205:    // TRUE so we won't try to send this alert again.
                    206:    //
                    207: 
                    208:    dllHandle = LoadLibraryA("NetApi32.Dll") ;
                    209:    if ( dllHandle == INVALID_HANDLE_VALUE )
                    210:       {
                    211:       return(TRUE) ;
                    212:       }
                    213: 
                    214:    //
                    215:    // Get the address of the service's main entry point.  This
                    216:    // entry point has a well-known name.
                    217:    //
                    218: 
                    219:    SendFunction = (pNetMessageBufferSend)GetProcAddress(
                    220:       dllHandle, "NetMessageBufferSend") ;
                    221: 
                    222:    if (SendFunction == NULL)
                    223:       {
                    224:       return(TRUE) ;
                    225:       }
                    226: 
                    227:    NetStatus = (*SendFunction) (NULL, pMessageName,
                    228:       NULL, (LPBYTE)pText, TextLen * sizeof(TCHAR)) ;
                    229:    if (NetStatus != NERR_Success)
                    230:       {
                    231:       return (FALSE) ;
                    232:       }
                    233: 
                    234:    return (TRUE) ;   
                    235: }
                    236: 
                    237: 
                    238: // this is the child thread used to send out network alert message.
                    239: // This thread is created at init time and is destroyed at close time
                    240: void NetAlertHandler (LPVOID *pDummy)
                    241:    {
                    242:    MSG      msg;
                    243: 
                    244:    while (GetMessage (&msg, NULL, 0, 0))
                    245:       {
                    246:       // we are only interested in this message
                    247:       if (LOWORD(msg.message) == WM_SEND_NETWORK_ALERT)
                    248:          {
                    249:          SendNetworkMessage ((LPTSTR)(msg.wParam),
                    250:             lstrlen ((LPTSTR)(msg.wParam)),
                    251:             (LPTSTR)(msg.lParam)) ;
                    252:          MemoryFree ((LPTSTR)(msg.wParam)) ;
                    253:          }
                    254:       }
                    255:    }  // NetAlertHandler
                    256: 
                    257: 
                    258: void SignalAlert (HWND hWnd,
                    259:                   HWND hWndAlerts,
                    260:                   PLINE pLine, FLOAT eValue,
                    261:                   SYSTEMTIME *pSystemTime)
                    262: /*
                    263:    Effect:        Perform any actions necessary when a given alert line's
                    264:                   condition is true. In particular, add the alert to the
                    265:                   alert log. Also, depending on the user's wishes, signal
                    266:                   a network alert or beep or run a program.
                    267: 
                    268:                   If we are not viewing the alert screen, add one alert to 
                    269:                   the unviewed list.
                    270: */
                    271:    {
                    272:    int            iIndex ;
                    273:    PALERT         pAlert ;
                    274:    PALERTENTRY    pAlertEntry ;
                    275:    TCHAR          szTime [20] ;
                    276:    TCHAR          szDate [20] ;
                    277:    TCHAR          szInstance [256] ;
                    278:    TCHAR          szParent [256] ;
                    279:    TCHAR          szText [256] ;
                    280: 
                    281: 
                    282:    pAlert = AlertData (hWnd) ;
                    283: 
                    284:    pAlertEntry = MemoryAllocate (sizeof (ALERTENTRY)) ;
                    285:    if (!pAlertEntry)
                    286:       {
                    287:       return ;
                    288:       }
                    289:    pAlertEntry->SystemTime = *pSystemTime ;
                    290:    pAlertEntry->pLine= pLine ;
                    291:    pAlertEntry->eValue = eValue ;
                    292:    pAlertEntry->bOver = pLine->bAlertOver ;
                    293:    pAlertEntry->eAlertValue = pLine->eAlertValue ;
                    294: 
                    295: 
                    296:    //=============================//
                    297:    // Determine Instance, Parent  //
                    298:    //=============================//
                    299: 
                    300:    // It's possible that there will be no instance, therefore
                    301:    // the lnInstanceName would be NULL.
                    302: 
                    303:    if (pLine->lnObject.NumInstances > 0)
                    304:       {
                    305:       // Test for the parent object instance name title index.
                    306:       // If there is one, it implies that there will be a valid
                    307:       // Parent Object Name and a valid Parent Object Instance Name.
                    308: 
                    309:       // If the Parent Object title index is 0 then
                    310:       // just display the instance name.
                    311: 
                    312:       lstrcpy (szInstance, pLine->lnInstanceName) ;
                    313:       if (pLine->lnInstanceDef.ParentObjectTitleIndex && pLine->lnPINName)
                    314:          {
                    315:          // Get the Parent Object Name.
                    316:          lstrcpy (szParent, pLine->lnPINName) ;
                    317:          }
                    318:       else
                    319:          {
                    320:          szParent[0] = TEXT(' ') ;
                    321:          szParent[1] = TEXT('\0') ;
                    322:          }
                    323:       }
                    324:    else
                    325:       {
                    326:       szInstance[0] = TEXT(' ') ;
                    327:       szInstance[1] = TEXT('\0') ;
                    328:       szParent[0] = TEXT(' ') ;
                    329:       szParent[1] = TEXT('\0') ;
                    330:       }
                    331: 
                    332: 
                    333:    pAlertEntry->lpszInstance = StringAllocate (szInstance) ;
                    334:    pAlertEntry->lpszParent = StringAllocate (szParent) ;
                    335:    
                    336:    //=============================//
                    337:    // Add alert to Alert Log      //
                    338:    //=============================//
                    339: 
                    340:    if (LBNumItems (hWndAlerts) >= ALERTLOGMAXITEMS)
                    341:       LBDelete (hWndAlerts, 0) ;
                    342: 
                    343:    iIndex = LBAdd (hWndAlerts, (LPARAM) pAlertEntry) ;
                    344:    LBSetSelection (hWndAlerts, iIndex) ;
                    345: 
                    346:    // no need to check other things if we
                    347:    // are playing back log
                    348:    if (PlayingBackLog())
                    349:       {
                    350:       return ;
                    351:       }
                    352: 
                    353:    //=============================//
                    354:    // Update Status Line          //
                    355:    //=============================//
                    356: 
                    357:    if (iPerfmonView != IDM_VIEWALERT)
                    358:       {
                    359:       if (pAlert->bSwitchToAlert)
                    360:          {
                    361:          SendMessage (hWndMain, WM_COMMAND, (LONG)IDM_VIEWALERT, 0L) ;
                    362:          }
                    363:       else
                    364:          {
                    365:          // if iUnviewedAlerts is over 100, we will display "++"
                    366:          // so, no need to keep updating the icon...
                    367:          if (iUnviewedAlerts < 100)
                    368:             {
                    369:             iUnviewedAlerts ++ ;
                    370:             crLastUnviewedAlert = pLine->Visual.crColor ;
                    371:             StatusUpdateIcons (hWndStatus) ;
                    372:             }
                    373:          }
                    374:       }
                    375: 
                    376: 
                    377:    //=============================//
                    378:    // Network Alert?              //
                    379:    //=============================//
                    380: 
                    381:    szText[0] = TEXT('\0') ;
                    382:    if (pAlert->bNetworkAlert && pAlert->MessageName[0])
                    383:       {  // if
                    384:       LPTSTR   lpAlertMsg ;
                    385: 
                    386:       SystemTimeDateString (pSystemTime, szDate) ;
                    387:       SystemTimeTimeString (pSystemTime, szTime) ;
                    388:       TSPRINTF (szText, szAlertFormat, 
                    389:                 szDate, 
                    390:                 szTime,
                    391:                 eValue, 
                    392:                 pLine->bAlertOver ? TEXT('>') : TEXT('<'),
                    393:                 pLine->eAlertValue,
                    394:                 pLine->lnCounterName,
                    395:                 szInstance,
                    396:                 szParent,
                    397:                 pLine->lnObjectName,
                    398:                 pLine->lnSystemName) ;
                    399:       if (pAlert->dwNetAlertThreadID)
                    400:          {
                    401:          // use thread to send the network alert.
                    402:          // the memory will be released by the child thread when done
                    403:          lpAlertMsg =
                    404:             (LPTSTR) MemoryAllocate (sizeof(TCHAR) * (lstrlen(szText)+1)) ;
                    405:          if (lpAlertMsg)
                    406:             {
                    407:             lstrcpy (lpAlertMsg, szText) ;
                    408:             PostThreadMessage (pAlert->dwNetAlertThreadID,
                    409:                WM_SEND_NETWORK_ALERT,
                    410:                (WPARAM)lpAlertMsg,
                    411:                (LPARAM)pAlert->MessageName) ;
                    412:             }
                    413:          }
                    414:       else
                    415:          {
                    416:          // no thread available, use the slow way to send the network alert
                    417:          SetHourglassCursor() ;
                    418:          SendNetworkMessage (szText,
                    419:             (DWORD) lstrlen(szText),
                    420:             pAlert->MessageName) ;
                    421:          SetArrowCursor() ;
                    422:          }
                    423:       }
                    424: 
                    425: 
                    426:    //=============================//
                    427:    // Run Program?                //
                    428:    //=============================//
                    429: 
                    430:    if (pLine->lpszAlertProgram &&
                    431:        (pLine->bEveryTime || !pLine->bAlerted))
                    432:       {
                    433:       SetHourglassCursor() ;
                    434: 
                    435:       // check if this line has been created earlier in network alert
                    436:       // if not, then create the string
                    437:       if (szText[0] == TEXT('\0'))
                    438:          {
                    439:          SystemTimeDateString (pSystemTime, szDate) ;
                    440:          SystemTimeTimeString (pSystemTime, szTime) ;
                    441: 
                    442:          TSPRINTF (szText, szAlertFormat,
                    443:             szDate,
                    444:             szTime,
                    445:             eValue,
                    446:             pLine->bAlertOver ? TEXT('>') : TEXT('<'),
                    447:             pLine->eAlertValue,
                    448:             pLine->lnCounterName,
                    449:             szInstance,
                    450:             szParent,
                    451:             pLine->lnObjectName,
                    452:             pLine->lnSystemName) ;
                    453:          }
                    454: 
                    455:       AlertExec (pLine->lpszAlertProgram, szText) ;
                    456:       pLine->bAlerted = TRUE ;
                    457:       SetArrowCursor() ;
                    458:       }
                    459:    }  // SignalAlert
                    460: 
                    461: 
                    462: 
                    463: BOOL AlertCondition (PLINE pLine, FLOAT eValue)
                    464: /*
                    465:    Effect:        Return whether the alert test passed for line pLine,
                    466:                   with current data value eValue.
                    467: 
                    468:    Internals:     Don't *ever* say (bFoo == bBar), as non-FALSE values
                    469:                   could be represented by any nonzero number.  Use
                    470:                   BoolEqual or equivalent.
                    471: */
                    472:    {  // AlertCondition
                    473:    BOOL           bOver ;
                    474: 
                    475:    bOver = eValue > pLine->eAlertValue ;
                    476: 
                    477:    return (BoolEqual (bOver, pLine->bAlertOver)) ;
                    478:    }  // AlertCondition
                    479: 
                    480: 
                    481: INT static CheckAlerts (HWND hWnd,
                    482:                         HWND hWndAlerts,
                    483:                         SYSTEMTIME *pSystemTime,
                    484:                         PLINE pLineFirst,
                    485:                         HANDLE hExportFile)
                    486:    {  // CheckAlerts
                    487:    FLOAT          eValue ;
                    488:    PLINE          pLine ;
                    489:    BOOL           bAnyAlerts ;
                    490:    INT            ErrCode = 0 ;
                    491: 
                    492:    bAnyAlerts = FALSE ;
                    493:    if (!PlayingBackLog())
                    494:       {
                    495:       LBSetRedraw (hWndAlerts, FALSE) ;
                    496:       }
                    497: 
                    498:    for (pLine = pLineFirst ;
                    499:         pLine ;
                    500:         pLine = pLine->pLineNext)
                    501:       {
                    502:       if (pLine->bFirstTime)
                    503:          {
                    504:          // skip until we have collect enough samples for the first data
                    505:          continue ;
                    506:          }
                    507: 
                    508:       // Get the new value for this line.
                    509:       eValue = (*(pLine->valNext)) (pLine) ;
                    510:       if (AlertCondition (pLine, eValue))
                    511:          {
                    512:          bAnyAlerts = TRUE ;
                    513: 
                    514:          // the case that hExportFile is when playingback log and that the
                    515:          // listbox is overflowed with alert.  In this case, we have to
                    516:          // walk the log file again to re-generate all the alerts.
                    517:          if (hExportFile)
                    518:             {
                    519:             ErrCode = ExportAlertLine (pLine, eValue, pSystemTime, hExportFile) ;
                    520:             if (ErrCode)
                    521:                {
                    522:                break ;
                    523:                }
                    524:             }
                    525:          else
                    526:             {
                    527:             SignalAlert (hWnd, hWndAlerts, pLine, eValue, pSystemTime) ;
                    528:             }
                    529:          }
                    530:       }  // for
                    531: 
                    532:    if (!PlayingBackLog())
                    533:       {
                    534:       LBSetRedraw (hWndAlerts, TRUE) ;
                    535:       }
                    536: 
                    537:    return (ErrCode) ;
                    538:    }  // CheckAlerts
                    539: 
                    540: 
                    541: 
                    542: 
                    543: void DrawAlertEntry (HWND hWnd,
                    544:                      PALERT pAlert,
                    545:                      PALERTENTRY pAlertEntry,
                    546:                      LPDRAWITEMSTRUCT lpDI,
                    547:                      HDC hDC)
                    548:    {  // DrawAlertEntry
                    549:    PLINE          pLine ;
                    550:    RECT           rectUpdate ;
                    551: 
                    552:    TCHAR          szTime [20] ;
                    553:    TCHAR          szDate [20] ;
                    554:    TCHAR          szText [256] ;
                    555: 
                    556:    HBRUSH         hBrushPrevious ;
                    557:    FLOAT          eLocalValue ;
                    558:    COLORREF       preBkColor ;
                    559:    COLORREF       preTextColor ;
                    560: 
                    561:    pLine = pAlertEntry->pLine ;
                    562: 
                    563:    SystemTimeDateString (&(pAlertEntry->SystemTime), szDate) ;
                    564:    SystemTimeTimeString (&(pAlertEntry->SystemTime), szTime) ;
                    565: 
                    566:    if (DISelected (lpDI)) 
                    567:       {  // if
                    568:       preTextColor = SetTextColor (hDC, GetSysColor (COLOR_HIGHLIGHTTEXT)) ;
                    569:       preBkColor = SetBkColor (hDC, GetSysColor (COLOR_HIGHLIGHT)) ;
                    570:       }  // if
                    571: 
                    572:    //=============================//
                    573:    // Draw Color Dot              //
                    574:    //=============================//
                    575: 
                    576:    rectUpdate.left = 0 ;
                    577:    rectUpdate.top = lpDI->rcItem.top ;
                    578:    rectUpdate.right = pAlert->xColorWidth ;
                    579:    rectUpdate.bottom = lpDI->rcItem.bottom ;
                    580: 
                    581:    ExtTextOut (hDC, rectUpdate.left, rectUpdate.top,
                    582:                ETO_CLIPPED | ETO_OPAQUE,
                    583:                &rectUpdate,
                    584:                NULL, 0,
                    585:                NULL) ;
                    586: 
                    587: //   PatBlt (hDC,
                    588: //           rectUpdate.left,
                    589: //           rectUpdate.top,
                    590: //           rectUpdate.right - rectUpdate.left,
                    591: //           rectUpdate.bottom - rectUpdate.top,
                    592: //           PATCOPY) ;
                    593: 
                    594:    hBrushPrevious = SelectBrush (hDC, pLine->hBrush) ;
                    595: 
                    596:    Ellipse (hDC,
                    597:             rectUpdate.left + 2,
                    598:             rectUpdate.top + 2,
                    599:             rectUpdate.right - 2,
                    600:             rectUpdate.bottom - 2) ;
                    601: 
                    602:    SelectBrush (hDC, hBrushPrevious) ;
                    603: 
                    604:    //=============================//
                    605:    // Draw Date                   //
                    606:    //=============================//
                    607: 
                    608:    rectUpdate.left = rectUpdate.right ;
                    609:    rectUpdate.right = rectUpdate.left + pAlert->xDateWidth ;
                    610: 
                    611:    ExtTextOut (hDC, rectUpdate.left, rectUpdate.top,
                    612:                ETO_CLIPPED | ETO_OPAQUE,
                    613:                &rectUpdate,
                    614:                szDate, lstrlen (szDate),
                    615:                NULL) ;
                    616: 
                    617:    //=============================//
                    618:    // Draw Time                   //
                    619:    //=============================//
                    620: 
                    621:    rectUpdate.left = rectUpdate.right ;
                    622:    rectUpdate.right = rectUpdate.left + pAlert->xTimeWidth ;
                    623: 
                    624:    ExtTextOut (hDC, rectUpdate.left, rectUpdate.top,
                    625:                ETO_CLIPPED | ETO_OPAQUE,
                    626:                &rectUpdate,
                    627:                szTime, lstrlen (szTime),
                    628:                NULL) ;
                    629: 
                    630:    //=============================//
                    631:    // Draw Alert Value            //
                    632:    //=============================//
                    633: 
                    634:    SetTextAlign (hDC, TA_RIGHT) ;
                    635: 
                    636:    rectUpdate.left = rectUpdate.right ;
                    637:    rectUpdate.right = rectUpdate.left + pAlert->xNumberWidth ;
                    638: 
                    639:    if (pAlertEntry->eValue <= eNumber)
                    640:       {
                    641:       TSPRINTF (szText, szNumberFormat,
                    642:                 pAlertEntry->eValue) ;
                    643:       }
                    644:    else if (pAlertEntry->eValue <= eLargeNumber)
                    645:       {
                    646:       TSPRINTF (szText, szMediumnNumberFormat,
                    647:                 pAlertEntry->eValue) ;
                    648:       }
                    649:    else
                    650:       {
                    651:       TSPRINTF (szText, szLargeNumberFormat,
                    652:                 pAlertEntry->eValue) ;
                    653:       }
                    654: 
                    655:    ExtTextOut (hDC, rectUpdate.right, rectUpdate.top,
                    656:                ETO_CLIPPED | ETO_OPAQUE,
                    657:                &rectUpdate,
                    658:                szText, lstrlen (szText),
                    659:                NULL) ;
                    660: 
                    661:    //=============================//
                    662:    // Draw Alert Condition        //
                    663:    //=============================//
                    664: 
                    665:    rectUpdate.left = rectUpdate.right ;
                    666:    rectUpdate.right = rectUpdate.left + pAlert->xConditionWidth ;
                    667: 
                    668:    TSPRINTF (szText, szConditionFormat,
                    669:              pAlertEntry->bOver ? TEXT('>') : TEXT('<')) ;
                    670: 
                    671:    ExtTextOut (hDC, rectUpdate.right, rectUpdate.top,
                    672:                ETO_CLIPPED | ETO_OPAQUE,
                    673:                &rectUpdate,
                    674:                szText, lstrlen (szText),
                    675:                NULL) ;
                    676: 
                    677:    //=============================//
                    678:    // Draw Trigger Value          //
                    679:    //=============================//
                    680: 
                    681:    rectUpdate.left = rectUpdate.right ;
                    682:    rectUpdate.right = rectUpdate.left + pAlert->xNumberWidth ;
                    683: 
                    684:    eLocalValue = pAlertEntry->eAlertValue ;
                    685:    if (eLocalValue < (FLOAT) 0.0)
                    686:       {
                    687:       eLocalValue = -eLocalValue ;
                    688:       }
                    689: 
                    690:    if (eLocalValue <= eNumber)
                    691:       {
                    692:       TSPRINTF (szText, szNumberFormat,
                    693:                 pAlertEntry->eAlertValue) ;
                    694:       }
                    695:    else if (eLocalValue <= eLargeNumber)
                    696:       {
                    697:       TSPRINTF (szText, szMediumnNumberFormat,
                    698:                 pAlertEntry->eAlertValue) ;
                    699:       }
                    700:    else
                    701:       {
                    702:       TSPRINTF (szText, szLargeNumberFormat,
                    703:                 pAlertEntry->eAlertValue) ;
                    704:       }
                    705: 
                    706:    ExtTextOut (hDC, rectUpdate.right, rectUpdate.top,
                    707:                ETO_CLIPPED | ETO_OPAQUE,
                    708:                &rectUpdate,
                    709:                szText, lstrlen (szText),
                    710:                NULL) ;
                    711: 
                    712:    //=============================//
                    713:    // Draw Rest                   //
                    714:    //=============================//
                    715: 
                    716:    SetTextAlign (hDC, TA_LEFT) ;
                    717: 
                    718:    rectUpdate.left = rectUpdate.right ;
                    719:    rectUpdate.right = 10000 ;
                    720:                                ;
                    721:    TSPRINTF (szText, 
                    722:              TEXT("    %s,  %s,  %s,  %s,  %s"),
                    723:              pLine->lnCounterName,
                    724:              pAlertEntry->lpszInstance,
                    725:              pAlertEntry->lpszParent,
                    726:              pLine->lnObjectName,
                    727:              pLine->lnSystemName) ;
                    728: 
                    729:    ExtTextOut (hDC, rectUpdate.left, rectUpdate.top,
                    730:                ETO_OPAQUE,
                    731:                &rectUpdate,
                    732:                szText, lstrlen (szText),
                    733:                NULL) ;
                    734: 
                    735:    // check if we need to bring-up or resize the horiz scrollbar
                    736:    if (pAlertEntry->StringWidth == 0)
                    737:       {
                    738:       pAlertEntry->StringWidth = TextWidth (hDC, szText) + xScrollWidth +
                    739:                   rectUpdate.left ;
                    740:       }
                    741: 
                    742:    if (pAlertEntry->StringWidth > pAlert->xTextExtent)
                    743:       {
                    744:       pAlert->xTextExtent = pAlertEntry->StringWidth ;
                    745:       LBSetHorzExtent (pAlert->hAlertListBox, pAlertEntry->StringWidth) ;
                    746:       }
                    747: 
                    748:    if (DISelected (lpDI))
                    749:       {  // if
                    750:       preTextColor = SetTextColor (hDC, preTextColor) ;
                    751:       preBkColor = SetBkColor (hDC, preBkColor) ;
                    752:       }  // if
                    753:    }  // DrawAlertEntry
                    754: 
                    755: 
                    756: 
                    757: //==========================================================================//
                    758: //                              Message Handlers                            //
                    759: //==========================================================================//
                    760: 
                    761: 
                    762: void static OnDrawItem (HWND hWnd,
                    763:                         LPDRAWITEMSTRUCT lpDI)
                    764:    {  // OnDrawItem
                    765:    HFONT          hFontPrevious ;
                    766:    HDC            hDC ;
                    767:    PALERT         pAlert ;
                    768:    PALERTENTRY    pAlertEntry ;
                    769:    int            iLBIndex ;
                    770: 
                    771:    hDC = lpDI->hDC ;
                    772:    iLBIndex = DIIndex (lpDI) ;
                    773: 
                    774:    pAlert = AlertData (hWnd) ;
                    775: 
                    776:    if (iLBIndex == -1)
                    777:       {
                    778:       pAlertEntry = NULL ;
                    779:       }
                    780:    else
                    781:       {
                    782:       pAlertEntry = (PALERTENTRY) LBData (pAlert->hAlertListBox, iLBIndex) ;
                    783:       if (pAlertEntry == (PALERTENTRY) LB_ERR)
                    784:          {
                    785:          pAlertEntry = NULL ;
                    786:          }
                    787:       }
                    788: 
                    789:    //=============================//
                    790:    // Draw Legend Item            //
                    791:    //=============================//
                    792: 
                    793:    if (pAlertEntry)
                    794:       {
                    795:       hFontPrevious = SelectFont (hDC, pAlert->hFontItems) ;
                    796:       DrawAlertEntry (hWnd, pAlert, pAlertEntry, lpDI, hDC) ;
                    797:       SelectFont (hDC, hFontPrevious) ;
                    798:       }
                    799: 
                    800:    //=============================//
                    801:    // Draw Focus                  //
                    802:    //=============================//
                    803: 
                    804:    if (DIFocus (lpDI))
                    805:       DrawFocusRect (hDC, &(lpDI->rcItem)) ;
                    806: 
                    807:    }  // OnDrawItem
                    808: 
                    809: 
                    810: 
                    811: int static OnCtlColor (HWND hDlg,
                    812:                        HDC hDC)
                    813:    {
                    814:    SetTextColor (hDC, crBlack) ;
                    815:    SetBkColor (hDC, crLightGray) ;
                    816:    return ((int) hbLightGray) ;
                    817:    }
                    818: 
                    819: 
                    820: void static OnInitDialog (HWND hDlg)
                    821:    {
                    822:    HDC            hDC ;
                    823:    PALERT         pAlert ;
                    824: 
                    825:    iUnviewedAlerts = 0 ;
                    826: 
                    827:    pAlert = AllocateAlertData (hDlg) ;
                    828:    if (!pAlert)
                    829:       return ;
                    830: 
                    831:    pAlert->iStatus = iPMStatusClosed ;
                    832:    pAlert->hFontItems = hFontScales ;
                    833: 
                    834:    hDC = GetDC (hDlg) ;
                    835:    SelectFont (hDC, pAlert->hFontItems) ;
                    836: 
                    837:    pAlert->yItemHeight = FontHeight (hDC, TRUE) + 2 * AlertItemTopMargin () ;
                    838: 
                    839:    pAlert->xColorWidth = pAlert->yItemHeight ;
                    840:    pAlert->xDateWidth = TextWidth (hDC, szDatePrototype) ;
                    841:    pAlert->xTimeWidth = TextWidth (hDC, szTimePrototype) ;
                    842:    pAlert->xNumberWidth = TextWidth (hDC, szNumberPrototype) ;
                    843:    pAlert->xConditionWidth = TextWidth (hDC, szConditionPrototype) ;
                    844: 
                    845:    // no Horz. scroll bar to begin with
                    846:    pAlert->xTextExtent = 0 ;
                    847: 
                    848:    pAlert->hNetAlertThread = CreateThread(NULL, (DWORD)0,
                    849:       (LPTHREAD_START_ROUTINE)NetAlertHandler,
                    850:       NULL, (DWORD)0, &(pAlert->dwNetAlertThreadID)) ;
                    851: 
                    852:    if (!(pAlert->hNetAlertThread))
                    853:       {
                    854:       // CreateThread failure, set its ID to zero
                    855:       // so we will not use the thread
                    856:       pAlert->dwNetAlertThreadID = 0 ;
                    857:       }
                    858:    else
                    859:       {
                    860:       SetThreadPriority (pAlert->hNetAlertThread, THREAD_PRIORITY_HIGHEST) ;
                    861:       }
                    862: 
                    863:    ReleaseDC (hDlg, hDC) ;
                    864: 
                    865:    hWndAlertLegend = DialogControl (hDlg, IDD_ALERTLEGEND) ;
                    866:    UpdateAlertDisplay (hDlg) ;
                    867:    }
                    868: 
                    869: 
                    870: 
                    871: void static OnMeasureItem (HWND hWnd,
                    872:                            LPMEASUREITEMSTRUCT lpMI)
                    873: /*
                    874:    Note:          Since we have an LB_OWNERDRAWFIXED item in the alert
                    875:                   dialog, we get this message *before* the WM_INITDIALOG
                    876:                   message.  Therefore we can't rely on any of the values
                    877:                   set in that message handler.
                    878: */
                    879:    {  // OnMeasureItem
                    880:    HDC            hDC ;
                    881: 
                    882:    hDC = GetDC (hWnd) ;
                    883:    SelectFont (hDC, hFontScales) ;
                    884: 
                    885:    lpMI->itemHeight = FontHeight (hDC, TRUE) + 2 * AlertItemTopMargin () ;
                    886: 
                    887:    ReleaseDC (hWnd, hDC) ;
                    888:    }  // OnMeasureItem
                    889: 
                    890: 
                    891: void static OnDeleteItem (HDLG hDlg,
                    892:                           WPARAM wControlID,
                    893:                           LPDELETEITEMSTRUCT lpDI)
                    894:    {  // OnDeleteItem
                    895:    PALERTENTRY    pAlertEntry ;
                    896: 
                    897:    pAlertEntry = (PALERTENTRY) lpDI->itemData ;
                    898: 
                    899:    MemoryFree (pAlertEntry->lpszParent) ;
                    900:    MemoryFree (pAlertEntry->lpszInstance) ;
                    901: 
                    902:    MemoryFree (pAlertEntry) ;
                    903:    }  // OnDeleteItem
                    904: 
                    905: 
                    906: 
                    907: void static OnSize (HWND hDlg,
                    908:                     int xWidth,
                    909:                     int yHeight)
                    910:    {  // OnSize
                    911:    SizeAlertComponents (hDlg) ;
                    912:    }
                    913: 
                    914: 
                    915: void static OnDestroy (HWND hWnd)
                    916: /*
                    917:    Effect:        Perform any actions necessary when an AlertDisplay window
                    918:                   is being destroyed. In particular, free the instance
                    919:                   data for the log.
                    920: 
                    921:                   Since we really only have one log window and one global
                    922:                   log data structure, we don't free the structure. We do,
                    923:                   however, delete the objects allocated within the structure.
                    924: */
                    925:    {  // OnDestroy
                    926:    PALERT           pAlert ;
                    927: 
                    928:    pAlert = AlertData (hWnd) ;
                    929:    FreeAlertData (pAlert) ;
                    930: 
                    931:    if (pAlert->dwNetAlertThreadID)
                    932:       {
                    933:       CloseHandle (pAlert->hNetAlertThread) ;
                    934:       }
                    935:    }  // OnDestroy
                    936: 
                    937: 
                    938: 
                    939: //==========================================================================//
                    940: //                             Exported Functions                           //
                    941: //==========================================================================//
                    942: 
                    943: 
                    944: BOOL AlertInitializeApplication (void)
                    945:    {  // AlertInitializeApplication
                    946:    return (TRUE) ;
                    947:    }  // AlertInitializeApplication
                    948: 
                    949: 
                    950: int APIENTRY AlertDisplayDlgProc (HWND hDlg,
                    951:                                   unsigned iMessage,
                    952:                                   WPARAM wParam,
                    953:                                   LONG lParam)
                    954: /*
                    955:    Note:          This function must be exported in the application's
                    956:                   linker-definition file, perfmon.def.
                    957: */
                    958:    {  // AlertDisplayDlgProc
                    959: //   HDC            hDC ;
                    960: 
                    961:    switch (iMessage)
                    962:       {
                    963:       case WM_CTLCOLORDLG:
                    964:       case WM_CTLCOLOREDIT:
                    965:       case WM_CTLCOLORBTN:
                    966:       case WM_CTLCOLORSTATIC:
                    967:          return (OnCtlColor (hDlg, (HDC) wParam)) ;
                    968:          break ;
                    969: 
                    970:       case WM_DELETEITEM:
                    971:          OnDeleteItem (hDlg, wParam, (LPDELETEITEMSTRUCT) lParam) ;
                    972:          break ;
                    973: 
                    974:       case WM_DRAWITEM:
                    975:          OnDrawItem (hDlg, (LPDRAWITEMSTRUCT) lParam) ;
                    976:          break ;
                    977: 
                    978:       case WM_INITDIALOG:
                    979:          OnInitDialog (hDlg) ;
                    980:          break ;
                    981: 
                    982:       case WM_LBUTTONDOWN:
                    983:          DoWindowDrag (lParam) ;
                    984:          break ;
                    985: 
                    986:       case WM_LBUTTONDBLCLK:
                    987:          SendMessage (hWndMain, WM_LBUTTONDBLCLK, wParam, lParam) ;
                    988:          break ;
                    989: 
                    990:       case WM_MEASUREITEM:
                    991:          OnMeasureItem (hDlg, (LPMEASUREITEMSTRUCT) lParam) ;
                    992:          break ;
                    993: 
                    994:       case WM_SIZE:
                    995:          OnSize (hDlg, LOWORD (lParam), HIWORD (lParam)) ;
                    996:          break ;
                    997: 
                    998:       case WM_TIMER:
                    999:          AlertTimer (hDlg, FALSE) ;
                   1000:          break ;
                   1001: 
                   1002:       case WM_DESTROY:
                   1003:          OnDestroy (hDlg) ;
                   1004:          return (FALSE) ;
                   1005:          break ;
                   1006: 
                   1007:       default:
                   1008:          return (FALSE) ;
                   1009:       } // switch
                   1010: 
                   1011:    return (TRUE) ;
                   1012:    }  // AlertDisplayDlgProc
                   1013: 
                   1014: 
                   1015: HWND CreateAlertWindow (HWND hWndParent)
                   1016: /*
                   1017:    Effect:        Create the Alert window. This window is a child of
                   1018:                   hWndMain.
                   1019: 
                   1020:    Note:          We dont worry about the size here, as this window
                   1021:                   will be resized whenever the main window is resized.
                   1022: 
                   1023: */
                   1024:    {  // CreateAlertWindow
                   1025:    HWND           hWnd ;
                   1026:    hWnd = CreateDialog (hInstance,
                   1027:                         MAKEINTRESOURCE (idDlgAlertDisplay),
                   1028:                         hWndParent,
                   1029:                         (DLGPROC) AlertDisplayDlgProc) ;
                   1030: 
                   1031:    return (hWnd) ;
                   1032:    }  // CreateAlertWindow
                   1033: 
                   1034: 
                   1035: 
                   1036: void UpdateAlertDisplay (HWND hWnd)
                   1037: /*
                   1038:    Effect:        Set the values for the various controls in the Alert
                   1039:                   display.
                   1040: 
                   1041:    Called By:     OnInitDialog, any other routines that change these
                   1042:                   values.
                   1043: */
                   1044:    {  // UpdateAlertDisplay
                   1045:    PALERT         pAlert ;
                   1046: 
                   1047:    pAlert = AlertData (hWnd) ;
                   1048: 
                   1049:    DialogSetInterval (hWnd, IDD_ALERTINTERVAL, pAlert->iIntervalMSecs) ;
                   1050:    }  // UpdateAlertDisplay
                   1051: 
                   1052: 
                   1053: BOOL AlertInsertLine (HWND hWnd, PLINE pLine)
                   1054:    {
                   1055:    PALERT         pAlert ;
                   1056:    PLINE          pLineEquivalent ;
                   1057: 
                   1058:    pAlert = AlertData (hWnd) ;
                   1059:    pAlert->bModified = TRUE ;
                   1060: 
                   1061:    pLineEquivalent = FindEquivalentLine (pLine, pAlert->pLineFirst) ;
                   1062:    if (pLineEquivalent)
                   1063:       {
                   1064:       LINESTRUCT  tempLine ;
                   1065: 
                   1066:       tempLine = *pLineEquivalent ;
                   1067: 
                   1068:       // copy the new alert line attributes
                   1069:       pLineEquivalent->Visual = pLine->Visual ;
                   1070:       pLineEquivalent->bAlertOver = pLine->bAlertOver ;
                   1071:       pLineEquivalent->eAlertValue = pLine->eAlertValue ;
                   1072:       pLineEquivalent->bEveryTime = pLine->bEveryTime ;
                   1073: 
                   1074:       pLineEquivalent->lpszAlertProgram = pLine->lpszAlertProgram ;
                   1075:       pLine->lpszAlertProgram = tempLine.lpszAlertProgram ;
                   1076: 
                   1077:       pLineEquivalent->hBrush = pLine->hBrush ;
                   1078:       pLine->hBrush = tempLine.hBrush ;
                   1079: 
                   1080: 
                   1081:       return (FALSE) ;
                   1082:       }
                   1083:    else
                   1084:       {
                   1085:       SystemAdd (&pAlert->pSystemFirst, pLine->lnSystemName) ;
                   1086: 
                   1087:       LineAppend (&pAlert->pLineFirst, pLine) ;
                   1088: 
                   1089:       LegendAddItem (hWndAlertLegend, pLine) ;
                   1090: 
                   1091:       if (!bDelayAddAction)
                   1092:          {
                   1093:          SizeAlertComponents (hWndAlert) ;
                   1094:          LegendSetSelection (hWndAlertLegend, 
                   1095:                              LegendNumItems (hWndAlertLegend) - 1) ;
                   1096:          }
                   1097:       }
                   1098: 
                   1099:    if (!bDelayAddAction)
                   1100:       {
                   1101:       if (PlayingBackLog ())
                   1102:          {
                   1103:          PlaybackAlert (hWnd, 0) ;
                   1104:          WindowInvalidate (hWnd) ;
                   1105:          }
                   1106: 
                   1107:       else if (pAlert->iStatus == iPMStatusClosed)
                   1108:          SetAlertTimer (pAlert) ;
                   1109:       }
                   1110: 
                   1111:    return (TRUE) ;
                   1112:    }  // AlertInsertLine
                   1113: 
                   1114: 
                   1115: void AlertAddAction ()
                   1116:    {
                   1117:    PALERT           pAlert ;
                   1118: 
                   1119:    pAlert = AlertData (hWndAlert) ;
                   1120: 
                   1121:    SizeAlertComponents (hWndAlert) ;
                   1122:    LegendSetSelection (hWndAlertLegend,
                   1123:       LegendNumItems (hWndAlertLegend) - 1) ;
                   1124: 
                   1125:    if (PlayingBackLog ())
                   1126:       {
                   1127:       PlaybackAlert (hWndAlert, 0) ;
                   1128:       WindowInvalidate (hWndAlert) ;
                   1129:       }
                   1130:    else if (pAlert->iStatus == iPMStatusClosed)
                   1131:       SetAlertTimer (pAlert) ;
                   1132:    }
                   1133:    
                   1134: void SizeAlertComponents (HWND hDlg)
                   1135:    {  // SizeAlertComponents
                   1136:    RECT           rectClient ;
                   1137:    int            xWidth, yHeight ;
                   1138:    int            yLegendHeight ;
                   1139:    int            yLegendTextHeight ;
                   1140:    int            yLogHeight ;
                   1141:    int            yLogTextHeight ;
                   1142:    int            yIntervalHeight ;
                   1143:    int            xIntervalTextWidth ;
                   1144:    int            StartYPos ;
                   1145: 
                   1146:    GetClientRect (hDlg, &rectClient) ;
                   1147:    xWidth = rectClient.right ;
                   1148:    yHeight = rectClient.bottom ;
                   1149: 
                   1150:    yLegendHeight = LegendHeight (hWndAlertLegend, yHeight) ;
                   1151: 
                   1152:    if (yHeight < 7 * xScrollWidth)
                   1153:       {
                   1154:       // too small, just display the alert logs and hide all other
                   1155:       // items
                   1156:       DialogShow (hDlg, IDD_ALERTLEGEND, FALSE) ;
                   1157:       DialogShow (hDlg, IDD_ALERTLEGENDTEXT, FALSE) ;
                   1158: 
                   1159:       DialogShow (hDlg, IDD_ALERTINTERVAL, FALSE) ;
                   1160:       DialogShow (hDlg, IDD_ALERTINTERVALTEXT, FALSE) ;
                   1161: 
                   1162:       yLogTextHeight = DialogHeight (hDlg, IDD_ALERTLOGTEXT) ;
                   1163: 
                   1164:       if (yHeight - yLogTextHeight > 3 * xScrollWidth)
                   1165:          {
                   1166:          DialogMove (hDlg, IDD_ALERTLOGTEXT,
                   1167:                      xScrollWidth,
                   1168:                      xScrollWidth / 2,
                   1169:                      NOCHANGE, NOCHANGE) ;
                   1170:          yLogTextHeight += xScrollWidth / 2 ;
                   1171:          DialogShow (hDlg, IDD_ALERTLOGTEXT, TRUE) ;
                   1172:          }
                   1173:       else
                   1174:          {
                   1175:          yLogTextHeight = 0 ;
                   1176:          DialogShow (hDlg, IDD_ALERTLOGTEXT, FALSE) ;
                   1177:          }
                   1178:       DialogMove (hDlg, IDD_ALERTLOG,
                   1179:                   xScrollWidth,
                   1180:                   xScrollWidth / 2 + yLogTextHeight,
                   1181:                   xWidth - 2 * xScrollWidth,
                   1182:                   yHeight - xScrollWidth) ;
                   1183:       }
                   1184:    else if (yHeight <= 2 * yLegendHeight + 5 * xScrollWidth)
                   1185:       {
                   1186:       yLegendHeight = min (yLegendHeight,
                   1187:                           (yHeight - xScrollWidth) / 2) ;
                   1188: 
                   1189:       yLogHeight = yHeight - yLegendHeight - xScrollWidth - 2 ;
                   1190: 
                   1191:       DialogShow (hDlg, IDD_ALERTLEGENDTEXT, FALSE) ;
                   1192:       DialogShow (hDlg, IDD_ALERTINTERVAL, FALSE) ;
                   1193:       DialogShow (hDlg, IDD_ALERTINTERVALTEXT, FALSE) ;
                   1194: 
                   1195:       yLogTextHeight = DialogHeight (hDlg, IDD_ALERTLOGTEXT) ;
                   1196:       if (yLogHeight - yLogTextHeight > 3 * xScrollWidth)
                   1197:          {
                   1198:          DialogMove (hDlg, IDD_ALERTLOGTEXT,
                   1199:                      xScrollWidth,
                   1200:                      xScrollWidth / 2,
                   1201:                      NOCHANGE, NOCHANGE) ;
                   1202:          yLogTextHeight += xScrollWidth / 2 ;
                   1203:          DialogShow (hDlg, IDD_ALERTLOGTEXT, TRUE) ;
                   1204:          }
                   1205:       else
                   1206:          {
                   1207:          yLogTextHeight = 0 ;
                   1208:          DialogShow (hDlg, IDD_ALERTLOGTEXT, FALSE) ;
                   1209:          }
                   1210: 
                   1211:       DialogMove (hDlg, IDD_ALERTLOG,
                   1212:                   xScrollWidth,
                   1213:                   xScrollWidth / 2 + yLogTextHeight,
                   1214:                   xWidth - 2 * xScrollWidth,
                   1215:                   yLogHeight - yLogTextHeight) ;
                   1216: 
                   1217:       DialogMove (hDlg, IDD_ALERTLEGEND,
                   1218:                   xScrollWidth,
                   1219:                   yLogHeight + xScrollWidth - 2,
                   1220:                   xWidth - 2 * xScrollWidth,
                   1221:                   yLegendHeight) ;
                   1222: 
                   1223:       DialogShow (hDlg, IDD_ALERTLEGEND, TRUE) ;
                   1224:       }
                   1225:    else
                   1226:       {
                   1227:       DialogMove (hDlg, IDD_ALERTLEGEND,
                   1228:                   xScrollWidth, yHeight - xScrollWidth / 2 - yLegendHeight,
                   1229:                   xWidth - 2  * xScrollWidth,
                   1230:                   yLegendHeight) ;
                   1231:       DialogMove (hDlg, IDD_ALERTLEGENDTEXT,
                   1232:                   xScrollWidth,
                   1233:                   DialogYPos (hDlg, IDD_ALERTLEGEND) - xScrollWidth,
                   1234:                   NOCHANGE, NOCHANGE) ;
                   1235: 
                   1236:       yLegendTextHeight = DialogYPos (hDlg, IDD_ALERTLEGENDTEXT) ;
                   1237: 
                   1238:       yLogTextHeight = DialogHeight (hDlg, IDD_ALERTLOGTEXT) ;
                   1239:       yIntervalHeight = DialogHeight (hDlg, IDD_ALERTINTERVAL) ;
                   1240:       yLogHeight = yLegendTextHeight - 4 * xScrollWidth ;
                   1241: 
                   1242:       if (yLogHeight < 2 * xScrollWidth)
                   1243:          {
                   1244:          yLogHeight = yLegendTextHeight - yLogTextHeight - xScrollWidth ;
                   1245:          }
                   1246:       DialogMove (hDlg, IDD_ALERTLOG,
                   1247:                   xScrollWidth,
                   1248:                   yLegendTextHeight - yLogHeight - xScrollWidth / 2,
                   1249:                   xWidth - 2 * xScrollWidth,
                   1250:                   yLogHeight) ;
                   1251:       DialogMove (hDlg, IDD_ALERTLOGTEXT,
                   1252:                   xScrollWidth,
                   1253:                   yLogTextHeight = DialogYPos (hDlg, IDD_ALERTLOG) - xScrollWidth,
                   1254:                   xWidth - 2 * xScrollWidth, NOCHANGE) ;
                   1255: 
                   1256:       DialogShow (hDlg, IDD_ALERTLEGEND, TRUE) ;
                   1257:       DialogShow (hDlg, IDD_ALERTLEGENDTEXT, TRUE) ;
                   1258:       DialogShow (hDlg, IDD_ALERTLOGTEXT, TRUE) ;
                   1259: 
                   1260: 
                   1261:       if (yLogTextHeight >= yIntervalHeight + xScrollWidth)
                   1262:          {
                   1263:          StartYPos = (yLogTextHeight - yIntervalHeight) / 2 ;
                   1264:          xIntervalTextWidth = DialogWidth (hDlg, IDD_ALERTINTERVALTEXT) ;
                   1265:          DialogMove (hDlg, IDD_ALERTINTERVALTEXT,
                   1266:                      xScrollWidth,
                   1267:                      StartYPos + 1,
                   1268:                      NOCHANGE, NOCHANGE) ;
                   1269:          DialogMove (hDlg, IDD_ALERTINTERVAL,
                   1270:                      xScrollWidth + xIntervalTextWidth + 4,
                   1271:                      StartYPos,
                   1272:                      NOCHANGE, NOCHANGE) ;
                   1273: 
                   1274:          DialogShow (hDlg, IDD_ALERTINTERVAL, TRUE) ;
                   1275:          DialogShow (hDlg, IDD_ALERTINTERVALTEXT, TRUE) ;
                   1276:          }
                   1277:       else
                   1278:          {
                   1279:          DialogShow (hDlg, IDD_ALERTINTERVAL, FALSE) ;
                   1280:          DialogShow (hDlg, IDD_ALERTINTERVALTEXT, FALSE) ;
                   1281:          }
                   1282:       }
                   1283: 
                   1284:    WindowInvalidate (hDlg) ;
                   1285:    }  // SizeAlertComponents
                   1286: 
                   1287: 
                   1288: INT PlaybackAlert (HWND hWndAlert, HANDLE hExportFile)
                   1289:    {  // PlaybackAlert
                   1290:    PALERT         pAlert ;
                   1291:    LOGPOSITION    lp ;
                   1292:    PLOGINDEX      pLogIndex ;
                   1293:    SYSTEMTIME     SystemTime ;
                   1294:    SYSTEMTIME     PreviousSystemTime ;
                   1295:    BOOL           bFirstTime = TRUE ;
                   1296:    INT            ErrCode = 0 ;
                   1297:    int            iDisplayTics ;
                   1298:    DWORD          TimeDiff ;
                   1299: 
                   1300:    pAlert = AlertData (hWndAlert) ;
                   1301: 
                   1302:    if (!pAlert->pLineFirst)
                   1303:       {
                   1304:       // nothing to check
                   1305:       return ErrCode;
                   1306:       }
                   1307: 
                   1308:    lp = PlaybackLog.StartIndexPos ;
                   1309:    iDisplayTics = PlaybackLog.iSelectedTics;
                   1310: 
                   1311:    if (!hExportFile)
                   1312:       {
                   1313:       LBReset (pAlert->hAlertListBox) ;
                   1314:       LBSetRedraw (pAlert->hAlertListBox, FALSE) ;
                   1315:       }
                   1316: 
                   1317:    while (iDisplayTics) {
                   1318: 
                   1319:       pLogIndex = IndexFromPosition (&lp) ;
                   1320:       if (pLogIndex)
                   1321:          SystemTime = pLogIndex->SystemTime ;
                   1322:       else
                   1323:          GetLocalTime (&SystemTime) ;
                   1324:       
                   1325:       if (!bFirstTime)
                   1326:          {
                   1327:          // check if it is time to do the alert checking
                   1328:          TimeDiff = (DWORD) SystemTimeDifference (&PreviousSystemTime, &SystemTime) ;
                   1329:          if (TimeDiff * 1000 >= pAlert->iIntervalMSecs)
                   1330:             {
                   1331:             PlaybackLines (pAlert->pSystemFirst,
                   1332:                            pAlert->pLineFirst,
                   1333:                            lp.iPosition) ;
                   1334:             ErrCode = CheckAlerts (hWndAlert,
                   1335:                             pAlert->hAlertListBox,
                   1336:                             &SystemTime,
                   1337:                             pAlert->pLineFirst,
                   1338:                             hExportFile) ;
                   1339:             if (ErrCode)
                   1340:                {
                   1341:                break ;
                   1342:                }
                   1343: 
                   1344:             PreviousSystemTime = SystemTime ;
                   1345:             }
                   1346:          }
                   1347:       else
                   1348:          {
                   1349:          // setup the data for the first time
                   1350:          bFirstTime = FALSE ;
                   1351:          PreviousSystemTime = SystemTime ;
                   1352:          PlaybackLines (pAlert->pSystemFirst,
                   1353:                         pAlert->pLineFirst,
                   1354:                         lp.iPosition) ;
                   1355:          }
                   1356: 
                   1357:       if (!NextIndexPosition (&lp, FALSE))  
                   1358:          break;
                   1359: 
                   1360:       iDisplayTics-- ;
                   1361:       }
                   1362: 
                   1363:    if (!hExportFile)
                   1364:       {
                   1365:       LBSetRedraw (pAlert->hAlertListBox, TRUE) ;
                   1366:       }
                   1367: 
                   1368:    return (ErrCode) ;
                   1369:    }  // PlaybackAlert
                   1370: 
                   1371: 
                   1372: #if 0
                   1373: PLINESTRUCT CurrentAlertLine (HWND hWndAlert)
                   1374:    {  // CurrentAlertLine
                   1375:    UNREFERENCED_PARAMETER (hWndAlert) ;
                   1376: 
                   1377:    return (LegendCurrentLine (hWndAlertLegend)) ;
                   1378:    }  // CurrentAlertLine
                   1379: #endif
                   1380: 
                   1381: BOOL AddAlert (HWND hWndParent)
                   1382:    {
                   1383:    PALERT         pAlert ;
                   1384: 
                   1385:    pAlert = AlertData (hWndAlert) ;
                   1386: 
                   1387:    return (AddLine (hWndParent,
                   1388:                     &(pAlert->pSystemFirst),
                   1389:                     &(pAlert->Visual),
                   1390:                     LineTypeAlert)) ;
                   1391:    }
                   1392: 
                   1393: 
                   1394: 
                   1395: BOOL EditAlert (HWND hWndParent)
                   1396:    {  // EditAlert
                   1397:    PALERT        pAlert ;
                   1398: 
                   1399:    pAlert = AlertData (hWndAlert) ;
                   1400: 
                   1401:    return (EditLine (hWndParent,
                   1402:                      &(pAlert->pSystemFirst),
                   1403:                      CurrentAlertLine (hWndAlert),
                   1404:                      LineTypeAlert)) ;
                   1405:    }  // EditAlert
                   1406: 
                   1407: // RemoveLineFromAlertListBox is called when we are deleting a line 
                   1408: // while monitoring current activity.  We have to clear all the alert
                   1409: // entries of this line because we are already doing this when 
                   1410: // playing back from log.  Moreover, we are using the line structure
                   1411: // while drawing the item.
                   1412: //
                   1413: void RemoveLineFromAlertListBox (PALERT pAlert, PLINE pLine)
                   1414:    {
                   1415:    int            iIndex ;
                   1416:    int            iNumOfAlerts ;
                   1417:    PALERTENTRY    pAlertEntry ;
                   1418: 
                   1419:    iNumOfAlerts = LBNumItems (pAlert->hAlertListBox) ;
                   1420: 
                   1421:    if (iNumOfAlerts == 0 || iNumOfAlerts == (int) LB_ERR)
                   1422:       {
                   1423:       return ;
                   1424:       }
                   1425: 
                   1426:    LBSetRedraw (pAlert->hAlertListBox, FALSE) ;
                   1427: 
                   1428:    // go thru the listbox from bottom to top
                   1429:    for (iIndex = iNumOfAlerts - 1; iIndex >= 0; iIndex-- )
                   1430:       {
                   1431:       pAlertEntry = (PALERTENTRY) LBData (pAlert->hAlertListBox, iIndex) ;
                   1432:       if (pAlertEntry != (PALERTENTRY) NULL && pAlertEntry)
                   1433:          {
                   1434:          if (pAlertEntry->pLine == pLine)
                   1435:             {
                   1436:             // remove it from the alert listbox.
                   1437:             LBDelete (pAlert->hAlertListBox, iIndex) ;
                   1438:             }
                   1439:          }
                   1440:       }
                   1441:    LBSetRedraw (pAlert->hAlertListBox, TRUE) ;
                   1442:    }
                   1443: 
                   1444: BOOL AlertDeleteLine (HWND hWndAlert,
                   1445:                       PLINE pLine)
                   1446: /*
                   1447:    Effect:        Delete the line pLine from the alerts associated with
                   1448:                   window hWnd.  Return whether the line could be deleted.
                   1449: */
                   1450:    {  // DeleteAlert
                   1451:    PALERT         pAlert ;
                   1452: 
                   1453:    pAlert = AlertData (hWndAlert) ;
                   1454:    pAlert->bModified = TRUE ;
                   1455: 
                   1456:    LineRemove (&pAlert->pLineFirst, pLine) ;
                   1457:    LegendDeleteItem (hWndAlertLegend, pLine) ;
                   1458: 
                   1459:    if (!pAlert->pLineFirst)
                   1460:       {
                   1461:       // no need to collect data
                   1462:       ClearAlertTimer (pAlert) ;
                   1463: 
                   1464:       // clear legend
                   1465:       ClearLegend (hWndAlertLegend) ;
                   1466: 
                   1467:       // reset visual data
                   1468:       pAlert->Visual.iColorIndex = 0 ;
                   1469:       pAlert->Visual.iWidthIndex = 0 ;
                   1470:       pAlert->Visual.iStyleIndex = 0 ;
                   1471:       }
                   1472:    else
                   1473:       {
                   1474:       BuildNewValueListForAlert () ;
                   1475:       }
                   1476: 
                   1477:    if (!PlayingBackLog())
                   1478:       {
                   1479:       // delete any alert entry for this line
                   1480:       RemoveLineFromAlertListBox (pAlert, pLine) ;
                   1481:       }
                   1482: 
                   1483:    SizeAlertComponents (hWndAlert) ;
                   1484: 
                   1485:    if (PlayingBackLog ())
                   1486:       {
                   1487:       PlaybackAlert (hWndAlert, 0) ;
                   1488:       WindowInvalidate (hWndAlert) ;
                   1489:       }
                   1490: 
                   1491:    return (TRUE) ;
                   1492:    }  // DeleteAlert
                   1493: 
                   1494: 
                   1495: 
                   1496: BOOL ToggleAlertRefresh (HWND hWnd)
                   1497:    {  // ToggleAlertRefresh
                   1498:    PALERT        pAlert ;
                   1499: 
                   1500:    pAlert = AlertData (hWnd) ;
                   1501: 
                   1502:    if (pAlert->bManualRefresh)
                   1503:       SetAlertTimer (pAlert) ;
                   1504:    else
                   1505:       ClearAlertTimer (pAlert) ;
                   1506: 
                   1507:    pAlert->bManualRefresh = !pAlert->bManualRefresh ;
                   1508:    return (pAlert->bManualRefresh) ;
                   1509:    }  // ToggleAlertRefresh
                   1510: 
                   1511: BOOL AlertRefresh (HWND hWnd)
                   1512:    {  // ToggleAlertRefresh
                   1513:    PALERT        pAlert ;
                   1514: 
                   1515:    pAlert = AlertData (hWnd) ;
                   1516: 
                   1517:    return (pAlert->bManualRefresh) ;
                   1518:    }  // AlertRefresh
                   1519: 
                   1520: 
                   1521: void AlertTimer (HWND hWnd, BOOL bForce)
                   1522: /*
                   1523:    Effect:        Perform all actions neccesary when an alert timer tick
                   1524:                   or manual refresh occurs. In particular, get the current
                   1525:                   values for each line in the alert window, and compare
                   1526:                   the value against the alert conditions. For each alert
                   1527:                   that may have occured, call SignalAlert.
                   1528: 
                   1529:    Called By:     AlertWndProc, in response to a WM_TIMER message.
                   1530:                   OnCommand, in response to a IDM_REFRESHALERT notification.
                   1531: */
                   1532:    {  // AlertTimer
                   1533:    PALERT         pAlert ;
                   1534:    SYSTEMTIME     SystemTime ;
                   1535: 
                   1536:    pAlert = AlertData (hWnd) ;
                   1537: 
                   1538:    if (PlayingBackLog ())
                   1539:       return ;
                   1540: 
                   1541:    if (bForce || !pAlert->bManualRefresh)
                   1542:       {  // if
                   1543:       UpdateLines (&(pAlert->pSystemFirst), pAlert->pLineFirst) ;
                   1544:       GetLocalTime (&SystemTime) ;
                   1545:       CheckAlerts (hWnd,
                   1546:                    pAlert->hAlertListBox,
                   1547:                    &SystemTime,
                   1548:                    pAlert->pLineFirst,
                   1549:                    FALSE) ;
                   1550:       }  // if
                   1551:    }  // AlertTimer
                   1552: 
                   1553: 
                   1554: 
                   1555: BOOL OpenAlertVer1 (HANDLE hFile,
                   1556:                     DISKALERT *pDiskAlert,
                   1557:                     PALERT pAlert,
                   1558:                     DWORD dwMinorVersion)
                   1559:                   
                   1560:    {  // OpenAlertVer1
                   1561:    bDelayAddAction = TRUE ;
                   1562:    pAlert->Visual = pDiskAlert->Visual ;
                   1563:    pAlert->iIntervalMSecs = pDiskAlert->dwIntervalSecs ;
                   1564:    if (dwMinorVersion < 3)
                   1565:       {
                   1566:       pAlert->iIntervalMSecs *= 1000 ;
                   1567:       }
                   1568: 
                   1569:    pAlert->bNetworkAlert = pDiskAlert->bNetworkAlert ;
                   1570:    pAlert->bSwitchToAlert = pDiskAlert->bSwitchToAlert ;
                   1571:    pAlert->bManualRefresh = pDiskAlert->bManualRefresh ;
                   1572: 
                   1573:    if (dwMinorVersion >= 2)
                   1574:       {
                   1575:       lstrcpy (pAlert->MessageName, pDiskAlert->MessageName) ;
                   1576:       }
                   1577: 
                   1578:    ReadLines (hFile, pDiskAlert->dwNumLines,
                   1579:                &(pAlert->pSystemFirst), &(pAlert->pLineFirst), IDM_VIEWALERT) ;
                   1580: 
                   1581:    bDelayAddAction = FALSE ;
                   1582: 
                   1583:    AlertAddAction () ;
                   1584: 
                   1585:    return (TRUE) ;
                   1586:    }  // OpenAlertVer1
                   1587: 
                   1588: 
                   1589: 
                   1590: BOOL OpenAlert (HWND hWndAlert,
                   1591:                 HANDLE hFile,
                   1592:                 DWORD dwMajorVersion,
                   1593:                 DWORD dwMinorVersion,
                   1594:                 BOOL bAlertFile)
                   1595:    {  // OpenAlert
                   1596:    PALERT         pAlert ;
                   1597:    DISKALERT      DiskAlert ;
                   1598:    BOOL           bSuccess = TRUE ;
                   1599: 
                   1600:    pAlert = AlertData (hWndAlert) ;
                   1601:    if (!pAlert)
                   1602:       {
                   1603:       bSuccess = FALSE ;
                   1604:       goto Exit0 ;
                   1605:       }
                   1606: 
                   1607:    if (!FileRead (hFile, &DiskAlert, sizeof (DISKALERT)))
                   1608:       {
                   1609:       bSuccess = FALSE ;
                   1610:       goto Exit0 ;
                   1611:       }
                   1612: 
                   1613: 
                   1614:    switch (dwMajorVersion)
                   1615:       {
                   1616:       case (1):
                   1617: 
                   1618:          SetHourglassCursor() ;
                   1619: 
                   1620:          ResetAlertView (hWndAlert) ;
                   1621: 
                   1622:          OpenAlertVer1 (hFile, &DiskAlert, pAlert, dwMinorVersion) ;
                   1623: 
                   1624:          // change to alert view if we are opening a 
                   1625:          // alert file
                   1626:          if (bAlertFile && iPerfmonView != IDM_VIEWALERT)
                   1627:             {
                   1628:             SendMessage (hWndMain, WM_COMMAND, (LONG)IDM_VIEWALERT, 0L) ;
                   1629:             }
                   1630: 
                   1631:          if (iPerfmonView == IDM_VIEWALERT)
                   1632:             {
                   1633:             SetPerfmonOptions (&DiskAlert.perfmonOptions) ;
                   1634:             }
                   1635:          UpdateAlertDisplay (hWndAlert) ;
                   1636: 
                   1637:          SetArrowCursor() ;
                   1638: 
                   1639:          break ;
                   1640:       }  // switch
                   1641: 
                   1642: Exit0:
                   1643: 
                   1644:    if (bAlertFile)
                   1645:       {
                   1646:       CloseHandle (hFile) ;
                   1647:       }
                   1648: 
                   1649:    return (bSuccess) ;
                   1650:    }  // OpenAlert
                   1651: 
                   1652: 
                   1653: void ResetAlertView (HWND hWndAlert)
                   1654:    {  
                   1655:    PALERT         pAlert ;
                   1656: 
                   1657:    pAlert = AlertData (hWndAlert) ;
                   1658:    if (!pAlert)
                   1659:       return ;
                   1660: 
                   1661:    ChangeSaveFileName (NULL, IDM_VIEWALERT) ;
                   1662: 
                   1663:    if (pAlert->pSystemFirst)
                   1664:       {
                   1665:       ResetAlert (hWndAlert) ;
                   1666:       }
                   1667:    }  // ResetAlertView
                   1668: 
                   1669: void ResetAlert (HWND hWndAlert)
                   1670:    {  // ResetAlert
                   1671:    PALERT         pAlert ;
                   1672: 
                   1673: 
                   1674:    pAlert = AlertData (hWndAlert) ;
                   1675:    if (!pAlert)
                   1676:       return ;
                   1677: 
                   1678:    ClearAlertTimer (pAlert) ;
                   1679: 
                   1680:    ClearLegend (hWndAlertLegend) ;
                   1681:    if (pAlert->pLineFirst)
                   1682:       {
                   1683:       FreeLines (pAlert->pLineFirst) ;
                   1684:       pAlert->pLineFirst = NULL ;
                   1685:       }
                   1686: 
                   1687:    if (pAlert->pSystemFirst)
                   1688:       {
                   1689:       FreeSystems (pAlert->pSystemFirst) ;
                   1690:       pAlert->pSystemFirst = NULL ;
                   1691:       }
                   1692: 
                   1693:    pAlert->bModified = FALSE ;
                   1694: 
                   1695:    // reset visual data
                   1696:    pAlert->Visual.iColorIndex = 0 ;
                   1697:    pAlert->Visual.iWidthIndex = 0 ;
                   1698:    pAlert->Visual.iStyleIndex = 0 ;
                   1699: 
                   1700:    iUnviewedAlerts = 0 ;
                   1701:    if (iPerfmonView != IDM_VIEWALERT)
                   1702:       {
                   1703:       StatusUpdateIcons (hWndStatus) ;
                   1704:       }
                   1705: 
                   1706:    // remove the horiz. scrollbar
                   1707:    pAlert->xTextExtent = 0 ;
                   1708:    LBSetHorzExtent (pAlert->hAlertListBox, pAlert->xTextExtent) ;
                   1709: 
                   1710:    LBReset (pAlert->hAlertListBox) ;
                   1711:    SizeAlertComponents (hWndAlert) ;
                   1712: 
                   1713:    }  // ResetAlert
                   1714:    
                   1715: 
                   1716: 
                   1717: BOOL QuerySaveAlert (HWND hWndParent, HWND hWndAlert)
                   1718:    {
                   1719:    return (TRUE) ;
                   1720:    }
                   1721: 
                   1722: void ClearAlertDisplay (HWND hWnd)
                   1723:    {
                   1724:    PALERT         pAlert ;
                   1725: 
                   1726:    pAlert = AlertData (hWnd) ;
                   1727: 
                   1728:    // remove the horiz. scrollbar
                   1729:    pAlert->xTextExtent = 0 ;
                   1730:    LBSetHorzExtent (pAlert->hAlertListBox, pAlert->xTextExtent) ;
                   1731: 
                   1732:    LBReset (pAlert->hAlertListBox) ;
                   1733:    }
                   1734: 
                   1735: BOOL SaveAlert (HWND hWndAlert, HANDLE hInputFile, BOOL bGetFileName)
                   1736:    {
                   1737:    PALERT         pAlert ;
                   1738:    PLINE          pLine ;
                   1739:    HANDLE         hFile ;
                   1740:    DISKALERT      DiskAlert ;
                   1741:    PERFFILEHEADER FileHeader ;
                   1742:    TCHAR          szFileName [256] ;
                   1743:    BOOL           newFileName = FALSE ;
                   1744: 
                   1745:    if (hInputFile)
                   1746:       {
                   1747:       // use the input file handle if it is available
                   1748:       // this is the case for saving workspace data
                   1749:       hFile = hInputFile ;
                   1750:       }
                   1751:    else
                   1752:       {
                   1753:       if (pAlertFullFileName)
                   1754:          {
                   1755:          lstrcpy (szFileName, pAlertFullFileName) ;
                   1756:          }
                   1757:       if (bGetFileName || pAlertFullFileName == NULL)
                   1758:          {
                   1759:          if (!FileGetName (hWndAlert, IDS_ALERTFILE, szFileName))
                   1760:             {
                   1761:             return (FALSE) ;
                   1762:             }
                   1763:          newFileName = TRUE ;
                   1764:          }
                   1765: 
                   1766:       hFile = FileHandleCreate (szFileName) ;
                   1767: 
                   1768:       if (hFile && newFileName)
                   1769:          {
                   1770:          ChangeSaveFileName (szFileName, IDM_VIEWALERT) ;
                   1771:          }
                   1772:       else if (!hFile)
                   1773:          {
                   1774:          DlgErrorBox (hWndAlert, ERR_CANT_OPEN, szFileName) ;
                   1775:          }
                   1776:       }
                   1777: 
                   1778:    if (!hFile)
                   1779:       return (FALSE) ;
                   1780: 
                   1781:    pAlert = AlertData (hWndAlert) ;
                   1782:    if (!pAlert)
                   1783:       {
                   1784:       if (!hInputFile)
                   1785:          {
                   1786:          CloseHandle (hFile) ;
                   1787:          }
                   1788:       return (FALSE) ;
                   1789:       }
                   1790: 
                   1791:    if (!hInputFile)
                   1792:       {
                   1793:       memset (&FileHeader, 0, sizeof (FileHeader)) ;
                   1794:       lstrcpy (FileHeader.szSignature, szPerfAlertSignature) ;
                   1795:       FileHeader.dwMajorVersion = AlertMajorVersion ;
                   1796:       FileHeader.dwMinorVersion = AlertMinorVersion ;
                   1797:    
                   1798:       if (!FileWrite (hFile, &FileHeader, sizeof (PERFFILEHEADER)))
                   1799:          {
                   1800:          goto Exit0 ;
                   1801:          }
                   1802:       }
                   1803: 
                   1804:    DiskAlert.Visual = pAlert->Visual ;
                   1805:    DiskAlert.dwIntervalSecs = pAlert->iIntervalMSecs ;
                   1806:    DiskAlert.dwNumLines = NumLines (pAlert->pLineFirst) ;
                   1807:    DiskAlert.bNetworkAlert = pAlert->bNetworkAlert ;
                   1808:    DiskAlert.bSwitchToAlert = pAlert->bSwitchToAlert ;
                   1809:    DiskAlert.bManualRefresh = pAlert->bManualRefresh ;
                   1810:    DiskAlert.perfmonOptions = Options ;
                   1811:    lstrcpy (DiskAlert.MessageName, pAlert->MessageName) ;
                   1812:    if (!FileWrite (hFile, &DiskAlert, sizeof (DISKALERT)))
                   1813:       {
                   1814:       goto Exit0 ;
                   1815:       }
                   1816: 
                   1817:    for (pLine = pAlert->pLineFirst ;
                   1818:         pLine ;
                   1819:         pLine = pLine->pLineNext)
                   1820:       {  // for
                   1821:       if (!WriteLine (pLine, hFile))
                   1822:          {
                   1823:          goto Exit0 ;
                   1824:          }
                   1825:       }  // for
                   1826: 
                   1827:    if (!hInputFile)
                   1828:       {
                   1829:       CloseHandle (hFile) ;
                   1830:       }
                   1831: 
                   1832:    return (TRUE) ;
                   1833: 
                   1834: Exit0:
                   1835:    if (!hInputFile)
                   1836:       {
                   1837:       CloseHandle (hFile) ;
                   1838: 
                   1839:       // only need to report error if not workspace 
                   1840:       DlgErrorBox (hWndAlert, ERR_SETTING_FILE, szFileName) ;
                   1841:       }
                   1842:    return (FALSE) ;
                   1843:    }
                   1844: 
                   1845: 
                   1846: BOOL ExportAlertEntry (HANDLE hFile, PALERTENTRY pAlertEntry)
                   1847: {
                   1848:    TCHAR          UnicodeBuff [LongTextLen] ;
                   1849:    CHAR           TempBuff [LongTextLen] ;
                   1850:    int            StringLen ;
                   1851:    PLINE          pLine ;
                   1852: 
                   1853:    pLine = pAlertEntry->pLine ;
                   1854: 
                   1855:    // export the alert date-time
                   1856:    
                   1857:    strcpy (TempBuff, LineEndStr) ;
                   1858:    StringLen = strlen (TempBuff) ;
                   1859:    SystemTimeDateString (&(pAlertEntry->SystemTime), UnicodeBuff) ;
                   1860:    ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
                   1861: 
                   1862:    strcat (TempBuff, pDelimiter) ;
                   1863:    SystemTimeTimeString (&(pAlertEntry->SystemTime), UnicodeBuff) ;
                   1864:    StringLen = strlen (TempBuff) ;
                   1865:    ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
                   1866:    strcat (TempBuff, pDelimiter) ;
                   1867:    if (!FileWrite (hFile, TempBuff, strlen(TempBuff)))
                   1868:       {
                   1869:       goto Exit0 ;
                   1870:       }
                   1871: 
                   1872:    // export alert value and trigger condition
                   1873:    
                   1874:    TSPRINTF (UnicodeBuff, szNumberFormat, pAlertEntry->eValue) ;
                   1875:    ConvertUnicodeStr (TempBuff, UnicodeBuff) ;
                   1876:    strcat (TempBuff, pDelimiter) ;
                   1877:    StringLen = strlen (TempBuff) ;
                   1878:    TempBuff[StringLen] = pAlertEntry->bOver ? '>' : '<' ;
                   1879:    StringLen++ ;
                   1880:    TSPRINTF (UnicodeBuff, szNumberFormat, pAlertEntry->eAlertValue) ;
                   1881:    ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
                   1882:    strcat (TempBuff, pDelimiter) ;
                   1883:    if (!FileWrite (hFile, TempBuff, strlen(TempBuff)))
                   1884:       {
                   1885:       goto Exit0 ;
                   1886:       }
                   1887: 
                   1888:    // export Counter, Instance, & Parent names
                   1889:    
                   1890:    ConvertUnicodeStr (TempBuff, pLine->lnCounterName) ;
                   1891:    strcat (TempBuff, pDelimiter) ;
                   1892:    StringLen = strlen (TempBuff) ;
                   1893: 
                   1894:    if (!(strempty(pAlertEntry->lpszInstance)))
                   1895:       {
                   1896:       ConvertUnicodeStr (&TempBuff[StringLen], pAlertEntry->lpszInstance) ;
                   1897:       }
                   1898: 
                   1899:    strcat (TempBuff, pDelimiter) ;
                   1900:    
                   1901:    if (!(strempty(pAlertEntry->lpszParent)))
                   1902:       {
                   1903:       ConvertUnicodeStr (TempBuff, pAlertEntry->lpszParent) ;
                   1904:       }
                   1905:    strcat (TempBuff, pDelimiter) ;
                   1906:    
                   1907:    if (!FileWrite (hFile, TempBuff, strlen(TempBuff)))
                   1908:       {
                   1909:       goto Exit0 ;
                   1910:       }
                   1911: 
                   1912:    // export object, & computer names
                   1913:    
                   1914:    ConvertUnicodeStr (TempBuff, pLine->lnObjectName) ;
                   1915:    strcat (TempBuff, pDelimiter) ;
                   1916:    StringLen = strlen (TempBuff) ;
                   1917:    ConvertUnicodeStr (&TempBuff[StringLen], pLine->lnSystemName) ;
                   1918:    if (!FileWrite (hFile, TempBuff, strlen(TempBuff)))
                   1919:       {
                   1920:       goto Exit0 ;
                   1921:       }
                   1922: 
                   1923: 
                   1924:    return (TRUE) ;
                   1925: 
                   1926: Exit0:
                   1927:    return (FALSE) ;
                   1928: 
                   1929: }  // ExportAlertEntry
                   1930: 
                   1931: INT ExportAlertLine (PLINE pLine, FLOAT eValue, SYSTEMTIME *pSystemTime, HANDLE hExportFile)
                   1932: {
                   1933:    ALERTENTRY     AlertEntry ;
                   1934:    TCHAR          szInstance [256] ;
                   1935:    TCHAR          szParent [256] ;
                   1936:    INT            ErrCode = 0 ;
                   1937: 
                   1938:    AlertEntry.SystemTime = *pSystemTime ;
                   1939:    AlertEntry.pLine= pLine ;
                   1940:    AlertEntry.eValue = eValue ;
                   1941:    AlertEntry.bOver = pLine->bAlertOver ;
                   1942:    AlertEntry.eAlertValue = pLine->eAlertValue ;
                   1943: 
                   1944: 
                   1945:    //=============================//
                   1946:    // Determine Instance, Parent  //
                   1947:    //=============================//
                   1948: 
                   1949:    // It's possible that there will be no instance, therefore
                   1950:    // the lnInstanceName would be NULL.
                   1951: 
                   1952:    if (pLine->lnObject.NumInstances > 0)
                   1953:       {
                   1954:       // Test for the parent object instance name title index.
                   1955:       // If there is one, it implies that there will be a valid
                   1956:       // Parent Object Name and a valid Parent Object Instance Name.
                   1957: 
                   1958:       // If the Parent Object title index is 0 then
                   1959:       // just display the instance name.
                   1960: 
                   1961:       lstrcpy (szInstance, pLine->lnInstanceName) ;
                   1962:       if (pLine->lnInstanceDef.ParentObjectTitleIndex && pLine->lnPINName)
                   1963:          {
                   1964:          // Get the Parent Object Name.
                   1965:          lstrcpy (szParent, pLine->lnPINName) ;
                   1966:          }
                   1967:       else
                   1968:          {
                   1969:          szParent[0] = TEXT(' ') ;
                   1970:          szParent[1] = TEXT('\0') ;
                   1971:          }
                   1972:       }
                   1973:    else
                   1974:       {
                   1975:       szInstance[0] = TEXT(' ') ;
                   1976:       szInstance[1] = TEXT('\0') ;
                   1977:       szParent[0] = TEXT(' ') ;
                   1978:       szParent[1] = TEXT('\0') ;
                   1979:       }
                   1980: 
                   1981:    AlertEntry.lpszInstance = szInstance ;
                   1982:    AlertEntry.lpszParent = szParent ;
                   1983: 
                   1984:    if (!ExportAlertEntry (hExportFile, &AlertEntry))
                   1985:       {
                   1986:       ErrCode = ERR_EXPORT_FILE ;
                   1987:       }
                   1988: 
                   1989:    return ErrCode ;
                   1990:  }
                   1991: 
                   1992: 
                   1993: BOOL ExportAlertLabels (HANDLE hFile)
                   1994: {
                   1995:    TCHAR          UnicodeBuff [MiscTextLen] ;
                   1996:    CHAR           TempBuff [LongTextLen] ;
                   1997:    int            StringLen ;
                   1998: 
                   1999:    strcpy (TempBuff, LineEndStr) ;
                   2000:    StringLen = strlen (TempBuff) ;
                   2001:    StringLoad (IDS_EXPORT_DATE, UnicodeBuff) ;
                   2002:    ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
                   2003:    strcat (TempBuff, pDelimiter) ;
                   2004:    StringLen = strlen (TempBuff) ;
                   2005: 
                   2006:    StringLoad (IDS_EXPORT_TIME, UnicodeBuff) ;
                   2007:    ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
                   2008:    strcat (TempBuff, pDelimiter) ;
                   2009:    StringLen = strlen (TempBuff) ;
                   2010: 
                   2011:    StringLoad (IDS_LABELVALUE, UnicodeBuff) ;
                   2012:    ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
                   2013:    strcat (TempBuff, pDelimiter) ;
                   2014:    StringLen = strlen (TempBuff) ;
                   2015: 
                   2016:    StringLoad (IDS_ALERT_TRIGGER, UnicodeBuff) ;
                   2017:    ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
                   2018:    strcat (TempBuff, pDelimiter) ;
                   2019: 
                   2020:    if (!FileWrite (hFile, TempBuff, strlen(TempBuff)))
                   2021:       {
                   2022:       goto Exit0 ;
                   2023:       }
                   2024: 
                   2025:    StringLoad (IDS_COUNTERNAME, UnicodeBuff) ;
                   2026:    ConvertUnicodeStr (TempBuff, UnicodeBuff) ;
                   2027:    strcat (TempBuff, pDelimiter) ;
                   2028:    StringLen = strlen (TempBuff) ;
                   2029: 
                   2030:    StringLoad (IDS_INSTNAME, UnicodeBuff) ;
                   2031:    ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
                   2032:    strcat (TempBuff, pDelimiter) ;
                   2033:    StringLen = strlen (TempBuff) ;
                   2034: 
                   2035:    StringLoad (IDS_PARENT, UnicodeBuff) ;
                   2036:    ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
                   2037:    strcat (TempBuff, pDelimiter) ;
                   2038:    StringLen = strlen (TempBuff) ;
                   2039: 
                   2040:    StringLoad (IDS_OBJNAME, UnicodeBuff) ;
                   2041:    ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
                   2042:    strcat (TempBuff, pDelimiter) ;
                   2043:    StringLen = strlen (TempBuff) ;
                   2044: 
                   2045:    StringLoad (IDS_LABELSYSTEM, UnicodeBuff) ;
                   2046:    ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
                   2047: 
                   2048:    if (!FileWrite (hFile, TempBuff, strlen(TempBuff)))
                   2049:       {
                   2050:       goto Exit0 ;
                   2051:       }
                   2052: 
                   2053:    return (TRUE) ;
                   2054: 
                   2055: Exit0:
                   2056:    return (FALSE) ;
                   2057: 
                   2058: }  // ExportAlertLabels
                   2059: 
                   2060: 
                   2061: void ExportAlert (void)
                   2062: {
                   2063:    PALERT         pAlert ;
                   2064:    HANDLE         hFile = 0 ;
                   2065:    HWND           hWndAlerts ;
                   2066:    PALERTENTRY    pAlertEntry ;
                   2067:    int            AlertTotal ;
                   2068:    int            iIndex ;
                   2069:    LPTSTR         pFileName = NULL ;
                   2070:    INT            ErrCode = 0 ;
                   2071: 
                   2072:    if (!(pAlert = AlertData (hWndAlert)))
                   2073:       {
                   2074:       return ;
                   2075:       }
                   2076: 
                   2077:    // see if there is anything to export..
                   2078:    if (!(pAlert->pLineFirst))
                   2079:       {
                   2080:       return ;
                   2081:       }
                   2082: 
                   2083:    if (!(hWndAlerts = pAlert->hAlertListBox))
                   2084:       {
                   2085:       return ;
                   2086:       }
                   2087: 
                   2088:    AlertTotal = LBNumItems (hWndAlerts) ;
                   2089:    if (AlertTotal == LB_ERR || AlertTotal == 0)
                   2090:       {
                   2091:       return ;
                   2092:       }
                   2093: 
                   2094:    SetHourglassCursor() ;
                   2095:    
                   2096:    if (ErrCode = ExportFileOpen (hWndAlert, &hFile, pAlert->iIntervalMSecs, &pFileName))
                   2097:       {
                   2098:       goto Exit0 ;
                   2099:       }
                   2100: 
                   2101:    if (!pFileName)
                   2102:       {
                   2103:       // the case when user cancel.
                   2104:       goto Exit0 ;
                   2105:       }
                   2106: 
                   2107:    // export the column labels
                   2108:    if (!ExportAlertLabels (hFile))
                   2109:       {
                   2110:       ErrCode = ERR_EXPORT_FILE ;
                   2111:       goto Exit0 ;
                   2112:       }
                   2113:    if (AlertTotal < ALERTLOGMAXITEMS || !PlayingBackLog())
                   2114:       {
                   2115:       for (iIndex = 0 ; iIndex < AlertTotal ; iIndex++)
                   2116:          {
                   2117:          // get the alert data
                   2118:          pAlertEntry = (PALERTENTRY) LBData (hWndAlerts, iIndex) ;
                   2119: 
                   2120:          if (!pAlertEntry || pAlertEntry == (PALERTENTRY)LB_ERR)
                   2121:             {
                   2122:             // skip this entry if we hit an error
                   2123:             continue ;
                   2124:             }
                   2125:          
                   2126:          // export the alert line
                   2127:          if (!ExportAlertEntry (hFile, pAlertEntry))
                   2128:             {
                   2129:             ErrCode = ERR_EXPORT_FILE ;
                   2130:             break ;
                   2131:             }
                   2132:          }
                   2133:       }
                   2134:    else
                   2135:       {
                   2136:       // we are playingback log and that the listbox does not
                   2137:       // contain all the alerts.  In this case, have to walk the
                   2138:       // log file to re-generate all the alerts.
                   2139:       ErrCode = PlaybackAlert (hWndAlert, hFile) ;
                   2140:       }
                   2141: 
                   2142: Exit0:
                   2143: 
                   2144:    SetArrowCursor() ;
                   2145: 
                   2146:    if (hFile)
                   2147:       {
                   2148:       CloseHandle (hFile) ;
                   2149:       }
                   2150: 
                   2151:    if (pFileName)
                   2152:       {
                   2153:       if (ErrCode)
                   2154:          {
                   2155:          DlgErrorBox (hWndAlert, ErrCode, pFileName) ;
                   2156:          }
                   2157: 
                   2158:       MemoryFree (pFileName) ;
                   2159:       }
                   2160: 
                   2161: }  // ExportAlert
                   2162: 
                   2163: 
                   2164: BOOL
                   2165: BuildNewValueListForAlert (
                   2166: )
                   2167: {
                   2168:     PALERT pAlert;
                   2169: 
                   2170:     pAlert = AlertData (hWndAlert) ;
                   2171:     
                   2172:     return BuildValueListForSystems (
                   2173:         pAlert->pSystemFirst,
                   2174:         pAlert->pLineFirst);
                   2175: 
                   2176: }
                   2177: 
                   2178: 
                   2179: 
                   2180: 

unix.superglobalmegacorp.com

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