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.

515 lines
13 KiB

  1. /*++
  2. Copyright (C) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. timerng.cpp
  5. Abstract:
  6. <abstract>
  7. --*/
  8. //==========================================================================//
  9. // Includes //
  10. //==========================================================================//
  11. #include <assert.h>
  12. #include <windows.h>
  13. #include "winhelpr.h"
  14. #include "utils.h"
  15. #include "timerng.h"
  16. #include "globals.h"
  17. #define INTRVBAR_RANGE 1000
  18. #define MAX_TIME_CHARS 20
  19. #define MAX_DATE_CHARS 20
  20. TCHAR szTimeRangeClass[] = TEXT("TimeRange");
  21. INT
  22. CTimeRange::MaxTimeWidth (
  23. HDC hDC
  24. )
  25. /*
  26. Effect: Return a reasonable maximum number of pixels to hold
  27. expected time and date strings.
  28. To Do: When we use the alleged local-date and local-time display
  29. functions, we will modify this routine to use them.
  30. */
  31. {
  32. return (max (TextWidth (hDC, TEXT(" 99 XXX 99 ")),
  33. TextWidth (hDC, TEXT(" 99:99:99.9 PM ")))) ;
  34. }
  35. void
  36. CTimeRange::DrawBeginEnd (
  37. HDC hDC
  38. )
  39. {
  40. TCHAR szDate [MAX_TIME_CHARS] ;
  41. TCHAR szTime [MAX_DATE_CHARS] ;
  42. SetTextAlign (hDC, TA_TOP) ;
  43. SelectFont (hDC, m_hFont) ;
  44. SetBkColor(hDC, GetSysColor(COLOR_3DFACE));
  45. SetTextColor(hDC, GetSysColor(COLOR_BTNTEXT));
  46. // Draw the begin time
  47. FormatDateTime(m_llBegin, szTime, szDate);
  48. SetTextAlign (hDC, TA_RIGHT) ;
  49. TextOut (hDC, m_xBegin, 0, szDate, lstrlen (szDate)) ;
  50. TextOut (hDC, m_xBegin, m_yFontHeight, szTime, lstrlen (szTime)) ;
  51. // Draw the end time
  52. FormatDateTime(m_llEnd, szTime, szDate);
  53. SetTextAlign (hDC, TA_LEFT) ;
  54. TextOut (hDC, m_xEnd, 0, szDate, lstrlen (szDate)) ;
  55. TextOut (hDC, m_xEnd, m_yFontHeight, szTime, lstrlen (szTime)) ;
  56. }
  57. void
  58. CTimeRange::DrawStartStop (
  59. HDC hDC
  60. )
  61. /*
  62. Effect: Draw the start and stop date/times on the bottom of the
  63. timeline. Draw the start date/time right justified at the
  64. outer edge of the start point and the stop date/time left
  65. justified with the outer edge of the stop point.
  66. Erase previous start and stop date/times in the process.
  67. */
  68. {
  69. RECT rectDate ;
  70. RECT rectTime ;
  71. RECT rectOpaque ;
  72. TCHAR szTime [MAX_TIME_CHARS] ;
  73. TCHAR szDate [MAX_DATE_CHARS] ;
  74. INT xStart ;
  75. INT xStop ;
  76. INT iStart ;
  77. INT iStop ;
  78. INT xDateTimeWidth ;
  79. SelectFont (hDC, m_hFont) ;
  80. SetTextAlign (hDC, TA_TOP) ;
  81. SetBkColor(hDC, GetSysColor(COLOR_3DFACE));
  82. SetTextColor(hDC, GetSysColor(COLOR_BTNTEXT));
  83. //=============================//
  84. // Get Start Information //
  85. //=============================//
  86. xStart = m_xBegin + m_pIntrvBar->XStart();
  87. iStart = m_pIntrvBar->Start() ;
  88. m_llStart = m_llBegin + ((m_llEnd - m_llBegin) * iStart) / INTRVBAR_RANGE;
  89. FormatDateTime(m_llStart, szTime, szDate);
  90. xDateTimeWidth = max (TextWidth (hDC, szDate),
  91. TextWidth (hDC, szTime)) ;
  92. //=============================//
  93. // Write Start Date //
  94. //=============================//
  95. rectDate.left = xStart - xDateTimeWidth ;
  96. rectDate.top = m_rectStartDate.top ;
  97. rectDate.right = xStart ;
  98. rectDate.bottom = m_rectStartDate.bottom ;
  99. SetTextAlign (hDC, TA_RIGHT) ;
  100. UnionRect (&rectOpaque, &m_rectStartDate, &rectDate) ;
  101. ExtTextOut (hDC,
  102. rectDate.right, rectDate.top,
  103. ETO_OPAQUE,
  104. &rectOpaque,
  105. szDate, lstrlen (szDate),
  106. NULL) ;
  107. m_rectStartDate = rectDate ;
  108. //=============================//
  109. // Write Start Time //
  110. //=============================//
  111. rectTime.left = rectDate.left ;
  112. rectTime.top = m_rectStartTime.top ;
  113. rectTime.right = rectDate.right ;
  114. rectTime.bottom = m_rectStartTime.bottom ;
  115. UnionRect (&rectOpaque, &m_rectStartTime, &rectTime) ;
  116. ExtTextOut (hDC,
  117. rectTime.right, rectTime.top,
  118. ETO_OPAQUE,
  119. &rectOpaque,
  120. szTime, lstrlen (szTime),
  121. NULL) ;
  122. m_rectStartTime = rectTime ;
  123. //=============================//
  124. // Get Stop Information //
  125. //=============================//
  126. xStop = m_xBegin + m_pIntrvBar->XStop() ;
  127. iStop = m_pIntrvBar->Stop () ;
  128. m_llStop = m_llBegin + ((m_llEnd - m_llBegin) * iStop) / INTRVBAR_RANGE;
  129. FormatDateTime(m_llStop, szTime, szDate);
  130. xDateTimeWidth = max (TextWidth (hDC, szDate),
  131. TextWidth (hDC, szTime)) ;
  132. //=============================//
  133. // Write Stop Date //
  134. //=============================//
  135. rectDate.left = xStop ;
  136. rectDate.top = m_rectStopDate.top ;
  137. rectDate.right = xStop + xDateTimeWidth ;
  138. rectDate.bottom = m_rectStopDate.bottom ;
  139. SetTextAlign (hDC, TA_LEFT) ;
  140. UnionRect (&rectOpaque, &m_rectStopDate, &rectDate) ;
  141. ExtTextOut (hDC,
  142. rectDate.left, rectDate.top,
  143. ETO_OPAQUE,
  144. &rectOpaque,
  145. szDate, lstrlen (szDate),
  146. NULL) ;
  147. m_rectStopDate = rectDate ;
  148. //=============================//
  149. // Write Stop Time //
  150. //=============================//
  151. rectTime.left = rectDate.left ;
  152. rectTime.top = m_rectStopTime.top ;
  153. rectTime.right = rectDate.right ;
  154. rectTime.bottom = m_rectStopTime.bottom ;
  155. UnionRect (&rectOpaque, &m_rectStopTime, &rectTime) ;
  156. ExtTextOut (hDC,
  157. rectTime.left, rectTime.top,
  158. ETO_OPAQUE,
  159. &rectOpaque,
  160. szTime, lstrlen (szTime),
  161. NULL) ;
  162. m_rectStopTime = rectTime ;
  163. }
  164. //==========================================================================//
  165. // Message Handlers //
  166. //==========================================================================//
  167. CTimeRange::CTimeRange (
  168. HWND hWnd )
  169. {
  170. HDC hDC ;
  171. // Caller checks for NULL hwnd before calling this procedure
  172. assert ( NULL != hWnd );
  173. m_hWnd = hWnd ;
  174. SetWindowLongPtr(hWnd, 0, (INT_PTR)this);
  175. m_hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT) ;
  176. hDC = GetDC (hWnd) ;
  177. if (hDC) {
  178. if ( NULL != m_hFont ) {
  179. SelectFont (hDC, m_hFont) ;
  180. }
  181. m_yFontHeight = FontHeight (hDC, TRUE) ;
  182. m_xMaxTimeWidth = MaxTimeWidth (hDC) ;
  183. ReleaseDC (hWnd, hDC) ;
  184. } else {
  185. m_yFontHeight = 0;
  186. m_xMaxTimeWidth = 0;
  187. }
  188. m_pIntrvBar = NULL;
  189. }
  190. CTimeRange::~CTimeRange (
  191. void
  192. )
  193. {
  194. if (m_pIntrvBar != NULL) {
  195. delete m_pIntrvBar;
  196. m_pIntrvBar = NULL;
  197. }
  198. }
  199. BOOL
  200. CTimeRange::Init(
  201. void
  202. )
  203. {
  204. RECT rc;
  205. m_pIntrvBar = new CIntervalBar();
  206. if (m_pIntrvBar != NULL) {
  207. if (m_pIntrvBar->Init(m_hWnd)) {
  208. // Size now because we didn't exist when the window
  209. // got the initial WM_SIZE message
  210. GetWindowRect(m_hWnd, &rc);
  211. OnSize(rc.right - rc.left, rc.bottom - rc.top);
  212. m_pIntrvBar->SetRange(0, INTRVBAR_RANGE);
  213. }
  214. else {
  215. delete m_pIntrvBar;
  216. m_pIntrvBar = NULL;
  217. }
  218. }
  219. return ( NULL != m_pIntrvBar );
  220. }
  221. void
  222. CTimeRange::OnSize (
  223. INT xWidth,
  224. INT yHeight
  225. )
  226. /*
  227. Effect: Perform all actions needed when the size of the timeline
  228. hWnd has changed. In particular, determine the appropriate
  229. size for the ILine window and set the rectangles for the
  230. top and bottom displays.
  231. */
  232. {
  233. INT yLine ;
  234. INT yDate, yTime ;
  235. INT xEnd ;
  236. xEnd = xWidth - m_xMaxTimeWidth ;
  237. yLine = m_yFontHeight ;
  238. yDate = yHeight - 2 * yLine ;
  239. yTime = yHeight - yLine ;
  240. SetRect (&m_rectStartDate, 0, yDate, 0, yDate + yLine) ;
  241. SetRect (&m_rectStartTime, 0, yTime, 0, yTime + yLine) ;
  242. SetRect (&m_rectStopDate, xEnd, yDate, xEnd, yDate + yLine) ;
  243. SetRect (&m_rectStopTime, xEnd, yTime, xEnd, yTime + yLine) ;
  244. MoveWindow (m_pIntrvBar->Window(),
  245. m_xMaxTimeWidth, 2 * m_yFontHeight,
  246. xWidth - 2 * m_xMaxTimeWidth,
  247. yHeight - 4 * m_yFontHeight,
  248. FALSE) ;
  249. m_xBegin = m_xMaxTimeWidth ;
  250. m_xEnd = xWidth - m_xMaxTimeWidth ;
  251. }
  252. //==========================================================================//
  253. // Exported Functions //
  254. //==========================================================================//
  255. LRESULT APIENTRY TimeRangeWndProc (
  256. HWND hWnd,
  257. UINT uiMsg,
  258. WPARAM wParam,
  259. LPARAM lParam
  260. )
  261. /*
  262. Note: This function must be declared in the application's
  263. linker-definition file, perfmon.def file.
  264. */
  265. {
  266. BOOL bCallDefWindowProc ;
  267. LRESULT lrsltReturnValue ;
  268. PCTimeRange pTimeRange = (PCTimeRange) GetWindowLongPtr(hWnd, 0);;
  269. bCallDefWindowProc = FALSE ;
  270. lrsltReturnValue = 0L ;
  271. if (pTimeRange) {
  272. switch ( uiMsg ) {
  273. case WM_SETFOCUS:
  274. return 0 ;
  275. case WM_KILLFOCUS:
  276. return 0 ;
  277. case WM_ENABLE:
  278. WindowInvalidate(hWnd);
  279. EnableWindow(pTimeRange->m_pIntrvBar->Window(), (BOOL)wParam);
  280. break;
  281. case WM_COMMAND:
  282. {
  283. HDC hDC;
  284. hDC = GetDC (hWnd) ;
  285. if (hDC) {
  286. pTimeRange->DrawStartStop (hDC) ;
  287. ReleaseDC (hWnd, hDC) ;
  288. }
  289. SendMessage(
  290. WindowParent(hWnd),
  291. WM_COMMAND, (WPARAM)WindowID(hWnd), (LPARAM)hWnd);
  292. }
  293. break ;
  294. case WM_PAINT:
  295. {
  296. HDC hDC ;
  297. PAINTSTRUCT ps ;
  298. hDC = BeginPaint (hWnd, &ps) ;
  299. if (hDC) {
  300. if (IsWindowEnabled(hWnd)) {
  301. pTimeRange->DrawBeginEnd (hDC) ;
  302. pTimeRange->DrawStartStop (hDC) ;
  303. }
  304. EndPaint (hWnd, &ps) ;
  305. }
  306. }
  307. break ;
  308. case WM_SIZE:
  309. pTimeRange->OnSize (LOWORD (lParam), HIWORD (lParam)) ;
  310. break ;
  311. default:
  312. bCallDefWindowProc = TRUE ;
  313. }
  314. }
  315. else {
  316. bCallDefWindowProc = TRUE;
  317. }
  318. if (bCallDefWindowProc)
  319. lrsltReturnValue = DefWindowProc (hWnd, uiMsg, wParam, lParam) ;
  320. return (lrsltReturnValue) ;
  321. }
  322. BOOL RegisterTimeRangeClass (
  323. void
  324. )
  325. {
  326. #define dwTimeRangeClassStyle (CS_HREDRAW | CS_VREDRAW)
  327. BEGIN_CRITICAL_SECTION
  328. // Register window class once
  329. if (pstrRegisteredClasses[TIMERANGE_WNDCLASS] == NULL) {
  330. WNDCLASS wc ;
  331. wc.style = dwTimeRangeClassStyle ;
  332. wc.lpfnWndProc = (WNDPROC)TimeRangeWndProc ;
  333. wc.cbClsExtra = 0 ;
  334. wc.cbWndExtra = sizeof(PCTimeRange);
  335. wc.hInstance = g_hInstance ;
  336. wc.hIcon = NULL ;
  337. wc.hCursor = LoadCursor (NULL, IDC_ARROW) ;
  338. wc.hbrBackground = (HBRUSH) (COLOR_3DFACE + 1) ;
  339. wc.lpszMenuName = NULL ;
  340. wc.lpszClassName = szTimeRangeClass ;
  341. if (RegisterClass (&wc)) {
  342. pstrRegisteredClasses[TIMERANGE_WNDCLASS] = szTimeRangeClass;
  343. }
  344. }
  345. END_CRITICAL_SECTION
  346. return (pstrRegisteredClasses[LEGEND_WNDCLASS] != NULL);
  347. }
  348. void
  349. CTimeRange::SetBeginEnd (
  350. LONGLONG llBegin,
  351. LONGLONG llEnd
  352. )
  353. {
  354. HDC hDC;
  355. m_llBegin = llBegin;
  356. m_llEnd = llEnd;
  357. hDC = GetDC (m_hWnd) ;
  358. if (hDC) {
  359. DrawBeginEnd (hDC) ;
  360. ReleaseDC (m_hWnd, hDC) ;
  361. }
  362. }
  363. void
  364. CTimeRange::SetStartStop (
  365. LONGLONG llStart,
  366. LONGLONG llStop
  367. )
  368. {
  369. INT iStart;
  370. INT iStop;
  371. HDC hDC;
  372. LONGLONG llBeginToEnd;
  373. if (llStart < m_llBegin)
  374. llStart = m_llBegin;
  375. if (llStop > m_llEnd)
  376. llStop = m_llEnd;
  377. m_llStart = llStart;
  378. m_llStop = llStop;
  379. llBeginToEnd = m_llEnd - m_llBegin;
  380. if ( 0 != llBeginToEnd ) {
  381. iStart = (INT)(((llStart - m_llBegin) * INTRVBAR_RANGE) / llBeginToEnd);
  382. iStop = (INT)(((llStop - m_llBegin) * INTRVBAR_RANGE) / llBeginToEnd);
  383. } else {
  384. iStart = 0;
  385. iStop = 0;
  386. }
  387. m_pIntrvBar->SetStart(iStart);
  388. m_pIntrvBar->SetStop(iStop);
  389. hDC = GetDC (m_hWnd) ;
  390. if (hDC) {
  391. DrawStartStop (hDC) ;
  392. ReleaseDC (m_hWnd, hDC) ;
  393. }
  394. }