Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

752 lines
19 KiB

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