|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.