|
|
1.1 root 1:
2:
3:
4: //==========================================================================//
5: // Includes //
6: //==========================================================================//
7:
8:
9: #include "perfmon.h"
10: #include "intrline.h"
11: #include "pmemory.h" // for MemoryXXX (mallloc-type) routines
12: #include "timeline.h"
13: #include "perfmops.h" // for SystemTimeDateString, et al.
14: #include "utils.h"
15: #include "grafdata.h" // for GraphData
16:
17: //==========================================================================//
18: // Typedefs //
19: //==========================================================================//
20:
21: typedef struct CHARTDATAPOINTSTRUCT
22: {
23: int iLogIndex ;
24: int xDispDataPoint ;
25: } CHARTDATAPOINT, *PCHARTDATAPOINT ;
26:
27: typedef struct TLINESTRUCT
28: { // TLINE
29: HWND hWndILine ;
30: HFONT hFont ;
31:
32: SYSTEMTIME SystemTimeBegin ;
33: SYSTEMTIME SystemTimeEnd ;
34:
35: int yFontHeight ;
36: int xMaxTimeWidth ;
37: int xBegin ;
38: int xEnd ;
39:
40: RECT rectStartDate ;
41: RECT rectStartTime ;
42: RECT rectStopDate ;
43: RECT rectStopTime ;
44:
45: PCHARTDATAPOINT pChartDataPoint ;
46: int iCurrentStartPos ;
47: int iCurrentStopPos ;
48: } TLINE ;
49:
50: typedef TLINE *PTLINE ;
51:
52: void PlaybackChartDataPoint (PCHARTDATAPOINT pChartDataPoint) ;
53:
54:
55: //==========================================================================//
56: // Constants //
57: //==========================================================================//
58:
59:
60: #define dwTLineClassStyle (CS_HREDRAW | CS_VREDRAW)
61: #define iTLineClassExtra (0)
62: #define iTLineWindowExtra (sizeof (PTLINE))
63: #define dwTLineWindowStyle (WS_CHILD | WS_VISIBLE)
64:
65: HWND hTLineWnd ;
66: BOOL TLineWindowUp ;
67:
68:
69:
70: PTLINE TLData (HWND hWndTL)
71: {
72: return ((PTLINE) GetWindowLong (hWndTL, 0)) ;
73: }
74:
75:
76: PTLINE AllocateTLData (HWND hWndTL)
77: {
78: PTLINE pTLine ;
79: PGRAPHSTRUCT pGraph ;
80:
81: pGraph = GraphData (hWndGraph) ;
82:
83: pTLine = MemoryAllocate (sizeof (TLINE)) ;
84:
85:
86: // see if we have to draw the timeline
87: if (pGraph &&
88: iPerfmonView == IDM_VIEWCHART &&
89: pGraph->pLineFirst &&
90: pGraph->gOptions.iGraphOrHistogram == LINE_GRAPH)
91: {
92: pTLine->pChartDataPoint =
93: MemoryAllocate (sizeof(CHARTDATAPOINT) *
94: (pGraph->gTimeLine.iValidValues+1)) ;
95:
96:
97: if (pTLine->pChartDataPoint != NULL)
98: {
99: PlaybackChartDataPoint (pTLine->pChartDataPoint) ;
100: }
101: }
102:
103: SetWindowLong (hWndTL, 0, (LONG) pTLine) ;
104:
105: return (pTLine) ;
106: }
107:
108:
109: int MaxTimeWidth (HDC hDC,
110: PTLINE pTLine)
111: /*
112: Effect: Return a reasonable maximum number of pixels to hold
113: expected time and date strings.
114:
115: To Do: When we use the alleged local-date and local-time display
116: functions, we will modify this routine to use them.
117: */
118: { // MaxTimeWidth
119: return (max (TextWidth (hDC, TEXT(" 99 XXX 99 ")),
120: TextWidth (hDC, TEXT(" 99:99:99.9 PM ")))) ;
121: } // MaxTimeWidth
122:
123:
124: void TLGetSystemTimeN (HWND hWnd,
125: int iInterval,
126: SYSTEMTIME *pSystemTime)
127: { // TLGetSystemTimeN
128: SendMessage (WindowParent (hWnd),
129: TL_INTERVAL,
130: iInterval, (LPARAM) pSystemTime) ;
131: } // TLGetSystemTimeN
132:
133:
134:
135: void static TLDrawBeginEnd (HDC hDC,
136: PTLINE pTLine)
137: {
138: TCHAR szDate [20] ;
139: TCHAR szTime [20] ;
140:
141: SetTextAlign (hDC, TA_TOP) ;
142: SelectFont (hDC, pTLine->hFont) ;
143:
144: // Draw the begin time
145:
146: SystemTimeDateString (&(pTLine->SystemTimeBegin), szDate) ;
147: SystemTimeTimeString (&(pTLine->SystemTimeBegin), szTime) ;
148:
149: SetTextAlign (hDC, TA_RIGHT) ;
150: TextOut (hDC, pTLine->xBegin, 0,
151: szDate, lstrlen (szDate)) ;
152: TextOut (hDC, pTLine->xBegin, pTLine->yFontHeight,
153: szTime, lstrlen (szTime)) ;
154:
155: // Draw The end time
156:
157: SystemTimeDateString (&(pTLine->SystemTimeEnd), szDate) ;
158: SystemTimeTimeString (&(pTLine->SystemTimeEnd), szTime) ;
159:
160: SetTextAlign (hDC, TA_LEFT) ;
161: TextOut (hDC, pTLine->xEnd, 0,
162: szDate, lstrlen (szDate)) ;
163: TextOut (hDC,
164: pTLine->xEnd,
165: pTLine->yFontHeight,
166: szTime, lstrlen (szTime)) ;
167: }
168:
169: void TLineRedraw (HDC hGraphDC, PGRAPHSTRUCT pGraph)
170: {
171: PTLINE pTLine ;
172:
173: if (!hTLineWnd)
174: {
175: return ;
176: }
177:
178: pTLine = TLData (hTLineWnd) ;
179: if (pTLine == NULL)
180: {
181: return ;
182: }
183:
184: if (pTLine->iCurrentStartPos)
185: {
186: // redraw start line
187: PatBlt (hGraphDC, pTLine->iCurrentStartPos, pGraph->rectData.top,
188: 1, pGraph->rectData.bottom - pGraph->rectData.top + 1,
189: DSTINVERT) ;
190: }
191:
192: if (pTLine->iCurrentStopPos)
193: {
194: // redraw stop line
195: PatBlt (hGraphDC, pTLine->iCurrentStopPos, pGraph->rectData.top,
196: 1, pGraph->rectData.bottom - pGraph->rectData.top+ 1,
197: DSTINVERT) ;
198: }
199: } // TLineRedraw
200:
201: void DrawOneTimeIndicator (PTLINE pTLine,
202: PGRAPHSTRUCT pGraph,
203: HDC hGraphDC,
204: int iPos,
205: int *pCurrentPos)
206: {
207: int xPos ;
208: PCHARTDATAPOINT pDataPoint ;
209:
210: // check if it is within current selected range
211: if (iPos >= PlaybackLog.StartIndexPos.iPosition &&
212: iPos <= PlaybackLog.StopIndexPos.iPosition)
213: {
214:
215: xPos = 0 ;
216: pDataPoint = pTLine->pChartDataPoint ;
217:
218: // check for the x position of this Log Index
219: while (pDataPoint->iLogIndex != 0)
220: {
221: if (iPos >= pDataPoint->iLogIndex)
222: {
223: if ((pDataPoint+1)->iLogIndex == 0)
224: {
225: // we have reached the end
226: xPos = pDataPoint->xDispDataPoint ;
227: break ;
228: }
229: else if (iPos <= (pDataPoint+1)->iLogIndex)
230: {
231: // we have found the Log index
232: xPos = (pDataPoint+1)->xDispDataPoint ;
233: break ;
234: }
235: }
236: else
237: {
238: // no need to continue if iPos is smaller than the
239: // first Log index on the chart
240: break ;
241: }
242:
243: pDataPoint++ ;
244: }
245:
246: if (xPos != *pCurrentPos)
247: {
248: if (*pCurrentPos)
249: {
250: // erase the old line
251: PatBlt (hGraphDC, *pCurrentPos, pGraph->rectData.top,
252: 1, pGraph->rectData.bottom - pGraph->rectData.top + 1,
253: DSTINVERT) ;
254: }
255:
256: // draw the new line
257: *pCurrentPos = xPos ;
258:
259: if (xPos > 0)
260: {
261: PatBlt (hGraphDC, xPos, pGraph->rectData.top,
262: 1, pGraph->rectData.bottom - pGraph->rectData.top + 1,
263: DSTINVERT) ;
264: }
265: }
266: }
267: else
268: {
269: if (*pCurrentPos)
270: {
271: // erase the old line
272: PatBlt (hGraphDC, *pCurrentPos, pGraph->rectData.top,
273: 1, pGraph->rectData.bottom - pGraph->rectData.top + 1,
274: DSTINVERT) ;
275: }
276:
277: *pCurrentPos = 0 ;
278: }
279: } // DrawOneTimeIndicator
280:
281: void DrawTimeIndicators (PTLINE pTLine, int iStart, int iStop)
282: {
283:
284: HDC hGraphDC ;
285: PGRAPHSTRUCT pGraph ;
286:
287: pGraph = GraphData (hWndGraph) ;
288: hGraphDC = GetDC (hWndGraph) ;
289: if (!hGraphDC || !pGraph)
290: {
291: return ;
292: }
293:
294: DrawOneTimeIndicator (pTLine, pGraph, hGraphDC, iStart, &pTLine->iCurrentStartPos) ;
295: DrawOneTimeIndicator (pTLine, pGraph, hGraphDC, iStop, &pTLine->iCurrentStopPos) ;
296:
297: ReleaseDC (hWndGraph, hGraphDC) ;
298: }
299:
300: void static TLDrawStartStop (HWND hWnd,
301: HDC hDC,
302: PTLINE pTLine)
303: /*
304: Effect: Draw the start and stop date/times on the bottom of the
305: timeline. Draw the start date/time right justified at the
306: outer edge of the start point and the stop date/time left
307: justified with the outer edge of the stop point.
308:
309: Erase previous start and stop date/times in the process.
310: */
311: { // TLDrawStartStop
312: RECT rectDate ;
313: RECT rectTime ;
314: RECT rectOpaque ;
315:
316: TCHAR szDate [30] ;
317: TCHAR szTime [30] ;
318:
319: int xStart ;
320: int xStop ;
321:
322: int iStart ;
323: int iStop ;
324:
325: SYSTEMTIME SystemTimeStart ;
326: SYSTEMTIME SystemTimeStop ;
327:
328: int xDateTimeWidth ;
329:
330:
331: SelectFont (hDC, pTLine->hFont) ;
332: SetTextAlign (hDC, TA_TOP) ;
333:
334: //=============================//
335: // Get Start Information //
336: //=============================//
337:
338: xStart = pTLine->xBegin + ILineXStart (pTLine->hWndILine) ;
339:
340: iStart = ILineStart (pTLine->hWndILine) ;
341: TLGetSystemTimeN (hWnd, iStart, &SystemTimeStart) ;
342: SystemTimeDateString (&SystemTimeStart, szDate) ;
343: SystemTimeTimeString (&SystemTimeStart, szTime) ;
344:
345: xDateTimeWidth = max (TextWidth (hDC, szDate),
346: TextWidth (hDC, szTime)) ;
347:
348: //=============================//
349: // Write Start Date //
350: //=============================//
351:
352: rectDate.left = xStart - xDateTimeWidth ;
353: rectDate.top = pTLine->rectStartDate.top ;
354: rectDate.right = xStart ;
355: rectDate.bottom = pTLine->rectStartDate.bottom ;
356:
357: SetTextAlign (hDC, TA_RIGHT) ;
358: UnionRect (&rectOpaque, &pTLine->rectStartDate, &rectDate) ;
359:
360: ExtTextOut (hDC,
361: rectDate.right, rectDate.top,
362: ETO_OPAQUE,
363: &rectOpaque,
364: szDate, lstrlen (szDate),
365: NULL) ;
366: pTLine->rectStartDate = rectDate ;
367:
368: //=============================//
369: // Write Start Time //
370: //=============================//
371:
372: rectTime.left = rectDate.left ;
373: rectTime.top = pTLine->rectStartTime.top ;
374: rectTime.right = rectDate.right ;
375: rectTime.bottom = pTLine->rectStartTime.bottom ;
376:
377: UnionRect (&rectOpaque, &pTLine->rectStartTime, &rectTime) ;
378:
379: ExtTextOut (hDC,
380: rectTime.right, rectTime.top,
381: ETO_OPAQUE,
382: &rectOpaque,
383: szTime, lstrlen (szTime),
384: NULL) ;
385: pTLine->rectStartTime = rectTime ;
386:
387:
388: //=============================//
389: // Get Stop Information //
390: //=============================//
391:
392: xStop = pTLine->xBegin + ILineXStop (pTLine->hWndILine) ;
393:
394: iStop = ILineStop (pTLine->hWndILine) ;
395: TLGetSystemTimeN (hWnd, iStop, &SystemTimeStop) ;
396: SystemTimeDateString (&SystemTimeStop, szDate) ;
397: SystemTimeTimeString (&SystemTimeStop, szTime) ;
398:
399: xDateTimeWidth = max (TextWidth (hDC, szDate),
400: TextWidth (hDC, szTime)) ;
401:
402: //=============================//
403: // Write Stop Date //
404: //=============================//
405:
406: rectDate.left = xStop ;
407: rectDate.top = pTLine->rectStopDate.top ;
408: rectDate.right = xStop + xDateTimeWidth ;
409: rectDate.bottom = pTLine->rectStopDate.bottom ;
410:
411: SetTextAlign (hDC, TA_LEFT) ;
412: UnionRect (&rectOpaque, &pTLine->rectStopDate, &rectDate) ;
413:
414: ExtTextOut (hDC,
415: rectDate.left, rectDate.top,
416: ETO_OPAQUE,
417: &rectOpaque,
418: szDate, lstrlen (szDate),
419: NULL) ;
420: pTLine->rectStopDate = rectDate ;
421:
422: //=============================//
423: // Write Stop Time //
424: //=============================//
425:
426: rectTime.left = rectDate.left ;
427: rectTime.top = pTLine->rectStopTime.top ;
428: rectTime.right = rectDate.right ;
429: rectTime.bottom = pTLine->rectStopTime.bottom ;
430:
431: UnionRect (&rectOpaque, &pTLine->rectStopTime, &rectTime) ;
432:
433: ExtTextOut (hDC,
434: rectTime.left, rectTime.top,
435: ETO_OPAQUE,
436: &rectOpaque,
437: szTime, lstrlen (szTime),
438: NULL) ;
439: pTLine->rectStopTime = rectTime ;
440:
441: if (pTLine->pChartDataPoint)
442: {
443: DrawTimeIndicators (pTLine, iStart, iStop) ;
444: }
445: } // TLDrawStartStop
446:
447:
448:
449: //==========================================================================//
450: // Message Handlers //
451: //==========================================================================//
452:
453:
454:
455: void static OnCreate (HWND hWnd)
456: { // OnCreate
457: PTLINE pTLine ;
458: HDC hDC ;
459:
460: pTLine = AllocateTLData (hWnd) ;
461:
462: pTLine->hFont = hFontScales ;
463:
464: hDC = GetDC (hWnd) ;
465: SelectFont (hDC, hFontScales) ;
466:
467: pTLine->yFontHeight = FontHeight (hDC, TRUE) ;
468: pTLine->xMaxTimeWidth = MaxTimeWidth (hDC, pTLine) ;
469:
470: ReleaseDC (hWnd, hDC) ;
471:
472: hTLineWnd = hWnd ;
473: TLineWindowUp = TRUE ;
474:
475: pTLine->hWndILine =
476: CreateWindow (szILineClass, // class
477: NULL, // caption
478: (WS_VISIBLE | WS_CHILD), // window style
479: 0, 0, // position
480: 0, 0, // size
481: hWnd, // parent window
482: NULL, // menu
483: hInstance, // program instance
484: NULL) ; // user-supplied data
485: } // OnCreate
486:
487:
488: void static OnDestroy (HWND hWnd)
489: {
490: PTLINE pTLine ;
491:
492: pTLine = TLData (hWnd) ;
493:
494: if (pTLine->pChartDataPoint)
495: {
496: MemoryFree (pTLine->pChartDataPoint) ;
497: }
498:
499: MemoryFree (pTLine) ;
500:
501: hTLineWnd = 0 ;
502: TLineWindowUp = FALSE ;
503:
504: }
505:
506:
507: void static OnSize (HWND hWnd,
508: int xWidth,
509: int yHeight)
510: /*
511: Effect: Perform all actions needed when the size of the timeline
512: hWnd has changed. In particular, determine the appropriate
513: size for the ILine window and set the rectangles for the
514: top and bottom displays.
515: */
516: { // OnSize
517: PTLINE pTLine ;
518: int yLine ;
519: int yDate, yTime ;
520: int xEnd ;
521:
522: pTLine = TLData (hWnd) ;
523:
524: xEnd = xWidth - pTLine->xMaxTimeWidth ;
525: yLine = pTLine->yFontHeight ;
526: yDate = yHeight - 2 * yLine ;
527: yTime = yHeight - yLine ;
528:
529:
530: SetRect (&pTLine->rectStartDate,
531: 0, yDate, 0, yDate + yLine) ;
532:
533: SetRect (&pTLine->rectStartTime,
534: 0, yTime, 0, yTime + yLine) ;
535:
536: SetRect (&pTLine->rectStopDate,
537: xEnd, yDate, xEnd, yDate + yLine) ;
538:
539: SetRect (&pTLine->rectStopTime,
540: xEnd, yTime, xEnd, yTime + yLine) ;
541:
542: MoveWindow (pTLine->hWndILine,
543: pTLine->xMaxTimeWidth, 2 * pTLine->yFontHeight,
544: xWidth - 2 * pTLine->xMaxTimeWidth,
545: yHeight - 4 * pTLine->yFontHeight,
546: FALSE) ;
547:
548: pTLine->xBegin = pTLine->xMaxTimeWidth ;
549: pTLine->xEnd = xWidth - pTLine->xMaxTimeWidth ;
550: } // OnSize
551:
552:
553: void static OnPaint (HWND hWnd)
554: {
555: HDC hDC ;
556: PAINTSTRUCT ps ;
557: PTLINE pTLine ;
558:
559: hDC = BeginPaint (hWnd, &ps) ;
560:
561: pTLine = TLData (hWnd) ;
562: TLDrawBeginEnd (hDC, pTLine) ;
563: TLDrawStartStop (hWnd, hDC, pTLine) ;
564:
565: EndPaint (hWnd, &ps) ;
566: }
567:
568:
569: void static OnILineChanged (HWND hWnd)
570: {
571: HDC hDC ;
572: PTLINE pTLine ;
573:
574: pTLine = TLData (hWnd) ;
575:
576: hDC = GetDC (hWnd) ;
577: TLDrawStartStop (hWnd, hDC, pTLine) ;
578: ReleaseDC (hWnd, hDC) ;
579: }
580:
581:
582: //==========================================================================//
583: // Exported Functions //
584: //==========================================================================//
585:
586:
587: LONG FAR PASCAL TLineWndProc (HWND hWnd,
588: unsigned msg,
589: WPARAM wParam,
590: LONG lParam)
591: /*
592: Note: This function must be declared in the application's
593: linker-definition file, perfmon.def file.
594: */
595: { // TLineWndProc
596: BOOL bCallDefWindowProc ;
597: LONG lReturnValue ;
598:
599: bCallDefWindowProc = FALSE ;
600: lReturnValue = 0L ;
601:
602: switch (msg)
603: { // switch
604: case WM_COMMAND:
605: OnILineChanged (hWnd) ;
606: break ;
607:
608: case WM_CREATE:
609: OnCreate (hWnd) ;
610: break ;
611:
612: case WM_DESTROY:
613: OnDestroy (hWnd) ;
614: break ;
615:
616: case WM_PAINT:
617: OnPaint (hWnd) ;
618: break ;
619:
620: case WM_SIZE:
621: OnSize (hWnd, LOWORD (lParam), HIWORD (lParam)) ;
622: break ;
623:
624: default:
625: bCallDefWindowProc = TRUE ;
626: } // switch
627:
628: if (bCallDefWindowProc)
629: lReturnValue = DefWindowProc (hWnd, msg, wParam, lParam) ;
630:
631: return (lReturnValue) ;
632: } // TLineWndProc
633:
634:
635:
636: BOOL TLineInitializeApplication (void)
637: /*
638: Effect: Perform all initializations required before an application
639: can create an IntervalLine. In particular, register the
640: IntervalLine window class.
641:
642: Called By: The application, in its InitializeApplication routine.
643:
644: Returns: Whether the class could be registered.
645: */
646: { // TLineInitializeApplication
647: WNDCLASS wc ;
648:
649: wc.style = dwTLineClassStyle ;
650: wc.lpfnWndProc = TLineWndProc ;
651: wc.cbClsExtra = iTLineClassExtra ;
652: wc.cbWndExtra = iTLineWindowExtra ;
653: wc.hInstance = hInstance ;
654: wc.hIcon = NULL ;
655: wc.hCursor = LoadCursor (NULL, IDC_ARROW) ;
656: wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1) ;
657: wc.lpszMenuName = NULL ;
658: wc.lpszClassName = szTLineClass ;
659:
660: return (RegisterClass (&wc)) ;
661: } // TLineInitializeApplication
662:
663:
664: void TLineSetRange (HWND hWnd,
665: int iBegin,
666: int iEnd)
667: {
668: PTLINE pTLine ;
669:
670: pTLine = TLData (hWnd) ;
671:
672: ILineSetRange (pTLine->hWndILine, iBegin, iEnd) ;
673: TLGetSystemTimeN (hWnd, iBegin, &pTLine->SystemTimeBegin) ;
674: TLGetSystemTimeN (hWnd, iEnd, &pTLine->SystemTimeEnd) ;
675: }
676:
677:
678: void TLineSetStart (HWND hWnd,
679: int iStart)
680: {
681: PTLINE pTLine ;
682:
683: pTLine = TLData (hWnd) ;
684: ILineSetStart (pTLine->hWndILine, iStart) ;
685: }
686:
687:
688: void TLineSetStop (HWND hWnd,
689: int iStop)
690: {
691: PTLINE pTLine ;
692:
693: pTLine = TLData (hWnd) ;
694: ILineSetStop (pTLine->hWndILine, iStop) ;
695: }
696:
697:
698: int TLineStart (HWND hWnd)
699: {
700: PTLINE pTLine ;
701:
702: pTLine = TLData (hWnd) ;
703:
704: return (ILineStart (pTLine->hWndILine)) ;
705: }
706:
707:
708: int TLineStop (HWND hWnd)
709: {
710: PTLINE pTLine ;
711:
712: pTLine = TLData (hWnd) ;
713:
714: return (ILineStop (pTLine->hWndILine)) ;
715: }
716:
717:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.