Leaked source code of windows server 2003
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.

1116 lines
23 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. Draw.c
  5. Abstract:
  6. Win32 application to display performance statictics. This routine implements
  7. graphics output for display windows.
  8. Author:
  9. Mark Enstrom (marke)
  10. Environment:
  11. Win32
  12. Revision History:
  13. 10-07-92 Initial version
  14. --*/
  15. //
  16. // set variable to define global variables
  17. //
  18. #include <nt.h>
  19. #include <ntrtl.h>
  20. #include <nturtl.h>
  21. #include <windows.h>
  22. #include <math.h>
  23. #include <errno.h>
  24. #include "vdmperf.h"
  25. extern DISPLAY_ITEM PerfDataList[SAVE_SUBJECTS];
  26. extern VDMPERF_INFO VdmperfInfo;
  27. extern PUCHAR PerfNames[];
  28. BOOLEAN
  29. FitPerfWindows(
  30. IN HWND hWnd,
  31. IN HDC hDC,
  32. IN PDISPLAY_ITEM DisplayItems,
  33. IN ULONG NumberOfWindows
  34. )
  35. /*++
  36. Routine Description:
  37. Calculate all parameters to fit the given number of
  38. windows into the app window. Fill out the data structure
  39. for each sub-window
  40. Arguments:
  41. hDC - Screen context
  42. DisplayItems - List of display structures
  43. NumberOfWindows - Number of sub-windows
  44. Return Value:
  45. Status
  46. Revision History:
  47. 02-17-91 Initial code
  48. --*/
  49. {
  50. RECT ClientRect;
  51. int cx,cy;
  52. UINT Index;
  53. int ActiveWindows,IndexX,IndexY;
  54. int WindowsX,WindowsY,WindowWidth,WindowHeight;
  55. int LastRowWidth,LoopWidth;
  56. double fWindowsX,fActiveWindows,fcx,fcy;
  57. //
  58. // Find out the client area bounds
  59. //
  60. GetClientRect(hWnd,&ClientRect);
  61. cx = ClientRect.right;
  62. cy = ClientRect.bottom - 2; // subtract 2 to give a little more border
  63. //
  64. // Find out how many perf windows are active
  65. //
  66. ActiveWindows = 0;
  67. for (Index=0;Index<NumberOfWindows;Index++) {
  68. if (DisplayItems[Index].Display == TRUE) {
  69. ActiveWindows++;
  70. }
  71. }
  72. //
  73. // Return if there are no active windows to display
  74. //
  75. if (ActiveWindows == 0) {
  76. return(TRUE);
  77. }
  78. //
  79. // Now convert the window dimensions to floating point and
  80. // then take the square root of the window dimension to find
  81. // out the number of windows in the x direction
  82. //
  83. fActiveWindows = 1.0 * ActiveWindows;
  84. fcx = 1.0 * cx;
  85. fcy = 1.0 * cy;
  86. if (fcy != 0.0) {
  87. fWindowsX = sqrt((fcx * fActiveWindows) / fcy);
  88. } else {
  89. //
  90. // If fcy = 0 then return since this is an error condition that
  91. // would cause a divide by zero.
  92. //
  93. return(FALSE);
  94. }
  95. //
  96. // convert back to integer
  97. //
  98. WindowsX = (int)fWindowsX;
  99. if (WindowsX == 0) {
  100. WindowsX = 1;
  101. } else if (WindowsX > ActiveWindows) {
  102. WindowsX = ActiveWindows;
  103. }
  104. WindowsY = ActiveWindows / WindowsX;
  105. //
  106. // Add on extra line to Y to take care of the left over windows ie:
  107. // if there are 15 active windows and the x number = 7 then y = 2 with 1
  108. // left over.
  109. //
  110. Index = ActiveWindows - (WindowsX * WindowsY);
  111. if (Index > 0) {
  112. WindowsY++;
  113. LastRowWidth = cx / Index;
  114. } else {
  115. LastRowWidth = cx / WindowsX;
  116. }
  117. WindowWidth = cx / WindowsX;
  118. WindowHeight = cy / WindowsY;
  119. //
  120. // Assign positions for each active window
  121. //
  122. Index = 0;
  123. for (IndexY=0;IndexY<WindowsY;IndexY++) {
  124. for (IndexX=0;IndexX<WindowsX;IndexX++) {
  125. //
  126. // Find the next active display item
  127. //
  128. while ((DisplayItems[Index].Display != TRUE) && (Index < NumberOfWindows)) {
  129. Index++;
  130. }
  131. //
  132. // Add y fixup for last row
  133. //
  134. if (IndexY == WindowsY - 1) {
  135. LoopWidth = LastRowWidth;
  136. } else {
  137. LoopWidth = WindowWidth;
  138. }
  139. DisplayItems[Index].PositionX = LoopWidth * IndexX;
  140. DisplayItems[Index].PositionY = WindowHeight * IndexY + 1; // +1 for more top border
  141. DisplayItems[Index].Width = LoopWidth - 1;
  142. DisplayItems[Index].Height = WindowHeight - 1;
  143. //
  144. // Last Column fix-up to use all of window.
  145. //
  146. if (IndexX == WindowsX - 1) {
  147. DisplayItems[Index].Width = cx - DisplayItems[Index].PositionX - 1;
  148. }
  149. //
  150. //
  151. //
  152. Index++;
  153. if (Index >= NumberOfWindows) {
  154. break;
  155. }
  156. }
  157. if (Index >= NumberOfWindows) {
  158. break;
  159. }
  160. }
  161. return(TRUE);
  162. }
  163. VOID
  164. CalcDrawFrame(
  165. PDISPLAY_ITEM DisplayItem
  166. )
  167. /*++
  168. Routine Description:
  169. Calculate all borders for graphics windows
  170. Arguments:
  171. DisplayItem - Data structure with all perf window info
  172. Return Value:
  173. status of operation
  174. Revision History:
  175. 03-21-91 Initial code
  176. --*/
  177. {
  178. LONG x1,x2,y1,y2;
  179. LONG gx1,gx2,gy1,gy2;
  180. LONG tx1,tx2,ty1,ty2;
  181. LONG GraphHeight,TextHeight;
  182. BOOLEAN TextWindow;
  183. double fx1,fx2,fy1;
  184. //
  185. // Draw a 3-d stand out box around item window
  186. //
  187. x1 = DisplayItem->PositionX + 2;
  188. x2 = DisplayItem->PositionX + DisplayItem->Width - 2;
  189. y1 = DisplayItem->PositionY + 2;
  190. y2 = DisplayItem->PositionY + DisplayItem->Height - 2;
  191. //
  192. // find out in there is enough space for a text window
  193. //
  194. if ((y2 - y1 - 12) > 30) {
  195. TextWindow = TRUE;
  196. //
  197. // Calculate dimensions for a text window and a graphics window
  198. //
  199. // fx1 = portion of the window - bordres and free space
  200. //
  201. // fx2 = fraction of window used for graphics
  202. //
  203. // fy1 = fraction of winddow used for text
  204. //
  205. fx1 = (y2 - y1 - 10);
  206. fx2 = fx1 * 0.6666;
  207. fy1 = fx1 * 0.3333;
  208. GraphHeight = (LONG)fx2;
  209. TextHeight = (LONG)fy1;
  210. if (TextHeight > 20) {
  211. GraphHeight += TextHeight-20;
  212. TextHeight = 20;
  213. }
  214. //
  215. // Calculate window boundaries
  216. //
  217. gx1 = x1 + 4;
  218. gx2 = x2 - 4;
  219. gy1 = y1 + 4;
  220. gy2 = y1 + 4 + GraphHeight + 1;
  221. tx1 = x1 + 4;
  222. tx2 = x2 - 4;
  223. ty1 = gy2 + 1 + 2 + 1; // border,free space,border
  224. ty2 = gy2 + TextHeight + 1;
  225. } else {
  226. TextWindow = FALSE;
  227. GraphHeight = y2 - y1 - 10;
  228. gx1 = x1 + 4;
  229. gx2 = x2 - 4;
  230. gy1 = y1 + 4;
  231. gy2 = y2 - 4;
  232. tx1 = tx2 = ty1 = ty2 = 0;
  233. }
  234. //
  235. // Fill in structures for drawing text and graphics
  236. //
  237. DisplayItem->Border.left = x1;
  238. DisplayItem->Border.right = x2;
  239. DisplayItem->Border.top = y1;
  240. DisplayItem->Border.bottom = y2;
  241. DisplayItem->GraphBorder.left = gx1;
  242. DisplayItem->GraphBorder.right = gx2;
  243. DisplayItem->GraphBorder.top = gy1;
  244. DisplayItem->GraphBorder.bottom = gy2;
  245. DisplayItem->TextBorder.left = tx1;
  246. DisplayItem->TextBorder.right = tx2;
  247. DisplayItem->TextBorder.top = ty1;
  248. DisplayItem->TextBorder.bottom = ty2;
  249. }
  250. VOID
  251. DrawFrame(
  252. HDC hDC,
  253. PDISPLAY_ITEM DisplayItem
  254. )
  255. /*++
  256. Routine Description:
  257. Draw the window frame for a performance window
  258. Arguments:
  259. hDC - Device Context for window
  260. DisplayItem - Data structure with all perf window info
  261. Return Value:
  262. status of operation
  263. Revision History:
  264. 03-21-91 Initial code
  265. --*/
  266. {
  267. RECT DrawRect;
  268. LONG x1,x2,y1,y2;
  269. LONG gx1,gx2,gy1,gy2;
  270. LONG tx1,tx2,ty1,ty2;
  271. //
  272. // Draw a 3-d stand out box around item window
  273. //
  274. x1 = DisplayItem->Border.left;
  275. x2 = DisplayItem->Border.right;
  276. y1 = DisplayItem->Border.top;
  277. y2 = DisplayItem->Border.bottom;
  278. gx1 = DisplayItem->GraphBorder.left;
  279. gx2 = DisplayItem->GraphBorder.right;
  280. gy1 = DisplayItem->GraphBorder.top;
  281. gy2 = DisplayItem->GraphBorder.bottom;
  282. tx1 = DisplayItem->TextBorder.left;
  283. tx2 = DisplayItem->TextBorder.right;
  284. ty1 = DisplayItem->TextBorder.top;
  285. ty2 = DisplayItem->TextBorder.bottom;
  286. //
  287. // Draw top border in light shade
  288. //
  289. DrawRect.left = x1;
  290. DrawRect.right = x2;
  291. DrawRect.top = y1;
  292. DrawRect.bottom = y1 + 2;
  293. FillRect(hDC,&DrawRect,VdmperfInfo.hLightBrush);
  294. //
  295. // Draw Left border in light shade
  296. //
  297. DrawRect.left = x1;
  298. DrawRect.right = x1 + 2;
  299. DrawRect.top = y1;
  300. DrawRect.bottom = y2;
  301. FillRect(hDC,&DrawRect,VdmperfInfo.hLightBrush);
  302. //
  303. // Draw right border in dark shade
  304. //
  305. DrawRect.left = x2 - 2;
  306. DrawRect.right = x2;
  307. DrawRect.top = y1;
  308. DrawRect.bottom = y2;
  309. FillRect(hDC,&DrawRect,VdmperfInfo.hDarkBrush);
  310. //
  311. // draw bottom in dark shade
  312. //
  313. DrawRect.left = x1;
  314. DrawRect.right = x2;
  315. DrawRect.top = y2-2;
  316. DrawRect.bottom = y2;
  317. FillRect(hDC,&DrawRect,VdmperfInfo.hDarkBrush);
  318. //
  319. // Draw graphics area single border
  320. //
  321. //
  322. // Draw top border in dark shade
  323. //
  324. DrawRect.left = gx1;
  325. DrawRect.right = gx2;
  326. DrawRect.top = gy1;
  327. DrawRect.bottom = gy1+1;
  328. FillRect(hDC,&DrawRect,VdmperfInfo.hDarkBrush);
  329. //
  330. // Draw Left border in Dark shade
  331. //
  332. DrawRect.left = gx1;
  333. DrawRect.right = gx1 + 1;
  334. DrawRect.top = gy1;
  335. DrawRect.bottom = gy2;
  336. FillRect(hDC,&DrawRect,VdmperfInfo.hDarkBrush);
  337. //
  338. // Draw right border in Light shade
  339. //
  340. DrawRect.left = gx2 - 1;
  341. DrawRect.right = gx2;
  342. DrawRect.top = gy1;
  343. DrawRect.bottom = gy2;
  344. FillRect(hDC,&DrawRect,VdmperfInfo.hLightBrush);
  345. //
  346. // draw bottom in Light shade
  347. //
  348. DrawRect.left = gx1;
  349. DrawRect.right = gx2;
  350. DrawRect.top = gy2-1;
  351. DrawRect.bottom = gy2;
  352. FillRect(hDC,&DrawRect,VdmperfInfo.hLightBrush);
  353. if (tx2 > 0) {
  354. //
  355. // Draw top border in Dark shade
  356. //
  357. DrawRect.left = tx1;
  358. DrawRect.right = tx2;
  359. DrawRect.top = ty1;
  360. DrawRect.bottom = ty1 + 1;
  361. FillRect(hDC,&DrawRect,VdmperfInfo.hDarkBrush);
  362. //
  363. // Draw Left border in Dark shade
  364. //
  365. DrawRect.left = tx1;
  366. DrawRect.right = tx1 + 1;
  367. DrawRect.top = ty1;
  368. DrawRect.bottom = ty2;
  369. FillRect(hDC,&DrawRect,VdmperfInfo.hDarkBrush);
  370. //
  371. // Draw right border in Light shade
  372. //
  373. DrawRect.left = tx2 - 1;
  374. DrawRect.right = tx2;
  375. DrawRect.top = ty1;
  376. DrawRect.bottom = ty2;
  377. FillRect(hDC,&DrawRect,VdmperfInfo.hLightBrush);
  378. //
  379. // draw bottom in Light shade
  380. //
  381. DrawRect.left = tx1;
  382. DrawRect.right = tx2;
  383. DrawRect.top = ty2-1;
  384. DrawRect.bottom = ty2;
  385. FillRect(hDC,&DrawRect,VdmperfInfo.hLightBrush);
  386. }
  387. }
  388. VOID
  389. DrawPerfText(
  390. HDC hDC,
  391. PDISPLAY_ITEM DisplayItem,
  392. UINT Item
  393. )
  394. /*++
  395. Routine Description:
  396. Draw text into the perf window
  397. Arguments:
  398. hDC - Device Context for window
  399. DisplayItem - Data structure with all perf window info
  400. Return Value:
  401. status of operation
  402. Revision History:
  403. 03-21-91 Initial code
  404. --*/
  405. {
  406. RECT TextRect;
  407. UCHAR TextStr[50];
  408. UINT FontSize;
  409. //
  410. // Check that text display is enabled
  411. //
  412. if (DisplayItem->TextBorder.right == 0) {
  413. return;
  414. }
  415. TextRect.left = DisplayItem->TextBorder.left +1;
  416. TextRect.right = DisplayItem->TextBorder.right -1;
  417. TextRect.top = DisplayItem->TextBorder.top +1;
  418. TextRect.bottom = DisplayItem->TextBorder.bottom -1;
  419. FillRect(hDC,&TextRect,VdmperfInfo.hBackground);
  420. SetBkColor(hDC,RGB(192,192,192));
  421. //
  422. // Decide which font to draw with
  423. //
  424. FontSize = TextRect.bottom - TextRect.top;
  425. if (FontSize >= 15) {
  426. VdmperfInfo.hOldFont = SelectObject(hDC,VdmperfInfo.LargeFont);
  427. } else if (FontSize > 10) {
  428. VdmperfInfo.hOldFont = SelectObject(hDC,VdmperfInfo.MediumFont);
  429. } else {
  430. VdmperfInfo.hOldFont = SelectObject(hDC,VdmperfInfo.SmallFont);
  431. }
  432. DrawText(
  433. hDC,
  434. PerfNames[Item],
  435. strlen(PerfNames[Item]),
  436. &TextRect,
  437. DT_LEFT | DT_VCENTER | DT_SINGLELINE
  438. );
  439. //
  440. // Build the numeric value
  441. //
  442. wsprintf(TextStr," %li",DisplayItem->TotalTime[0]);
  443. DrawText(
  444. hDC,
  445. TextStr,
  446. strlen(TextStr),
  447. &TextRect,
  448. DT_RIGHT | DT_VCENTER | DT_SINGLELINE
  449. );
  450. SelectObject(hDC,VdmperfInfo.hOldFont);
  451. }
  452. VOID
  453. DrawPerfGraph(
  454. HDC hDC,
  455. PDISPLAY_ITEM DisplayItem
  456. )
  457. /*++
  458. Routine Description:
  459. Draw graphics into the perf window
  460. Arguments:
  461. hDC - Device Context for window
  462. DisplayItem - Data structure with all perf window info
  463. Return Value:
  464. status of operation
  465. Revision History:
  466. 03-21-91 Initial code
  467. --*/
  468. {
  469. RECT GraphRect,MemGraphRect;
  470. ULONG Scale,i,GraphWidth,GraphHeight;
  471. GraphRect.left = DisplayItem->GraphBorder.left + 1;
  472. GraphRect.right = DisplayItem->GraphBorder.right - 1;
  473. GraphRect.top = DisplayItem->GraphBorder.top + 1;
  474. GraphRect.bottom = DisplayItem->GraphBorder.bottom - 1;
  475. GraphWidth = GraphRect.right - GraphRect.left -1;
  476. GraphHeight = GraphRect.bottom - GraphRect.top -1;
  477. //
  478. // Memory bitmap is zero-offset for all windows, add 1 to make fillrect fill out
  479. // to right and bottom edge
  480. //
  481. MemGraphRect.left = 0;
  482. MemGraphRect.right = GraphWidth +1;
  483. MemGraphRect.top = 0;
  484. MemGraphRect.bottom = GraphHeight +1;
  485. FillRect(DisplayItem->MemoryDC,&MemGraphRect,VdmperfInfo.hBackground);
  486. MemGraphRect.right = GraphWidth;
  487. MemGraphRect.bottom = GraphHeight;
  488. if (DisplayItem->Max == 0) {
  489. DisplayItem->Max = 1;
  490. }
  491. //
  492. // calculate scale from data to perf window
  493. //
  494. //
  495. // Outline object in green
  496. //
  497. SelectObject(DisplayItem->MemoryDC,VdmperfInfo.hRedPen);
  498. //
  499. // X scale factor (100 items in x space). Scale can not be less than 1
  500. //
  501. Scale = (GraphWidth -1)/ DATA_LIST_LENGTH;
  502. if (Scale == 0) {
  503. Scale = 1;
  504. }
  505. MoveToEx(DisplayItem->MemoryDC,
  506. MemGraphRect.right,
  507. MemGraphRect.bottom - (DisplayItem->TotalTime[0] * GraphHeight)/ DisplayItem->Max,
  508. (LPPOINT)NULL);
  509. for (i=1;((i<DATA_LIST_LENGTH) && i*Scale < GraphWidth);i++) {
  510. LineTo(DisplayItem->MemoryDC,
  511. MemGraphRect.right - Scale * i,
  512. MemGraphRect.bottom - (DisplayItem->TotalTime[i] * GraphHeight)/DisplayItem->Max);
  513. }
  514. //
  515. // Draw UserTime if needed
  516. //
  517. if (DisplayItem->NumberOfElements>1) {
  518. //
  519. // Select kernel pen
  520. //
  521. SelectObject(DisplayItem->MemoryDC,VdmperfInfo.hRedPen);
  522. MoveToEx(DisplayItem->MemoryDC,
  523. MemGraphRect.right,
  524. MemGraphRect.bottom - (DisplayItem->KernelTime[0] * GraphHeight)/ DisplayItem->Max,
  525. (LPPOINT)NULL);
  526. for (i=1;((i<DATA_LIST_LENGTH) && i*Scale < GraphWidth);i++) {
  527. LineTo(DisplayItem->MemoryDC,
  528. MemGraphRect.right - Scale * i,
  529. MemGraphRect.bottom - (DisplayItem->KernelTime[i] * GraphHeight)/DisplayItem->Max
  530. );
  531. }
  532. //
  533. // Select User Pen
  534. //
  535. SelectObject(DisplayItem->MemoryDC,VdmperfInfo.hGreenPen);
  536. MoveToEx(DisplayItem->MemoryDC,
  537. MemGraphRect.right,
  538. MemGraphRect.bottom - (DisplayItem->UserTime[0] * GraphHeight)/ DisplayItem->Max,
  539. (LPPOINT)NULL);
  540. for (i=1;((i<DATA_LIST_LENGTH) && i * Scale < GraphWidth);i++) {
  541. LineTo(DisplayItem->MemoryDC,
  542. MemGraphRect.right - Scale * i,
  543. MemGraphRect.bottom - (DisplayItem->UserTime[i] * GraphHeight)/DisplayItem->Max);
  544. }
  545. }
  546. BitBlt(
  547. hDC,
  548. GraphRect.left,
  549. GraphRect.top,
  550. GraphWidth+1,
  551. GraphHeight+1,
  552. DisplayItem->MemoryDC,
  553. 0,
  554. 0,
  555. SRCCOPY);
  556. }
  557. VOID
  558. ShiftPerfGraph(
  559. HDC hDC,
  560. PDISPLAY_ITEM DisplayItem
  561. )
  562. /*++
  563. Routine Description:
  564. Shift memory bitmap 1 location left then draw the 1 new data point.
  565. BitBlt this to the screen.
  566. Arguments:
  567. hDC - Device Context for window
  568. DisplayItem - Data structure with all perf window info
  569. Return Value:
  570. status of operation
  571. Revision History:
  572. 03-21-91 Initial code
  573. --*/
  574. {
  575. RECT GraphRect,MemGraphRect,FillArea;
  576. ULONG Scale,GraphWidth,GraphHeight;
  577. GraphRect.left = DisplayItem->GraphBorder.left + 1;
  578. GraphRect.right = DisplayItem->GraphBorder.right - 1;
  579. GraphRect.top = DisplayItem->GraphBorder.top + 1;
  580. GraphRect.bottom = DisplayItem->GraphBorder.bottom - 1;
  581. GraphWidth = GraphRect.right - GraphRect.left -1;
  582. GraphHeight = GraphRect.bottom - GraphRect.top -1;
  583. //
  584. // Memory bitmap is zero-offset for all windows, add 1 to make fillrect fill out
  585. // to right and bottom edge
  586. //
  587. MemGraphRect.left = 0;
  588. MemGraphRect.right = GraphWidth;
  589. MemGraphRect.top = 0;
  590. MemGraphRect.bottom = GraphHeight;
  591. if (DisplayItem->Max == 0) {
  592. DisplayItem->Max = 1;
  593. }
  594. //
  595. // calculate scale from data to perf window
  596. //
  597. // X scale factor (100 items in x space). Scale can not be less than 1
  598. //
  599. Scale = (GraphWidth -1)/ DATA_LIST_LENGTH;
  600. if (Scale == 0) {
  601. Scale = 1;
  602. }
  603. //
  604. // Shift memory image left by scale
  605. //
  606. BitBlt( DisplayItem->MemoryDC,
  607. 0,
  608. 0,
  609. GraphWidth+1 - Scale,
  610. GraphHeight+1,
  611. DisplayItem->MemoryDC,
  612. Scale,
  613. 0,
  614. SRCCOPY);
  615. //
  616. // Fill The new area on the right of the screen
  617. //
  618. FillArea.left = GraphWidth +1 - Scale;
  619. FillArea.right = GraphWidth +1;
  620. FillArea.top = 0;
  621. FillArea.bottom = GraphHeight +1;
  622. FillRect(DisplayItem->MemoryDC,&FillArea,VdmperfInfo.hBackground);
  623. //
  624. // Draw the 1 new data point
  625. //
  626. SelectObject(DisplayItem->MemoryDC,VdmperfInfo.hRedPen);
  627. MoveToEx(DisplayItem->MemoryDC,
  628. MemGraphRect.right,
  629. MemGraphRect.bottom - (DisplayItem->TotalTime[0] * GraphHeight)/ DisplayItem->Max,
  630. (LPPOINT)NULL);
  631. LineTo(DisplayItem->MemoryDC,
  632. MemGraphRect.right - Scale,
  633. MemGraphRect.bottom - (DisplayItem->TotalTime[1] * GraphHeight)/DisplayItem->Max);
  634. //
  635. // Draw UserTime if needed
  636. //
  637. if (DisplayItem->NumberOfElements>1) {
  638. //
  639. // Select kernel pen
  640. //
  641. SelectObject(DisplayItem->MemoryDC,VdmperfInfo.hRedPen);
  642. MoveToEx(DisplayItem->MemoryDC,
  643. MemGraphRect.right,
  644. MemGraphRect.bottom - (DisplayItem->KernelTime[0] * GraphHeight)/ DisplayItem->Max,
  645. (LPPOINT)NULL);
  646. LineTo(
  647. DisplayItem->MemoryDC,
  648. MemGraphRect.right - Scale,
  649. MemGraphRect.bottom - (DisplayItem->KernelTime[1] * GraphHeight)/DisplayItem->Max
  650. );
  651. //
  652. // Select User Pen
  653. //
  654. SelectObject(DisplayItem->MemoryDC,VdmperfInfo.hGreenPen);
  655. MoveToEx(
  656. DisplayItem->MemoryDC,
  657. MemGraphRect.right,
  658. MemGraphRect.bottom - (DisplayItem->UserTime[0] * GraphHeight)/ DisplayItem->Max,
  659. (LPPOINT)NULL
  660. );
  661. LineTo(
  662. DisplayItem->MemoryDC,
  663. MemGraphRect.right - Scale,
  664. MemGraphRect.bottom - (DisplayItem->UserTime[1] * GraphHeight)/DisplayItem->Max
  665. );
  666. }
  667. BitBlt(
  668. hDC,
  669. GraphRect.left,
  670. GraphRect.top,
  671. GraphWidth+1,
  672. GraphHeight+1,
  673. DisplayItem->MemoryDC,
  674. 0,
  675. 0,
  676. SRCCOPY);
  677. }
  678. BOOLEAN
  679. CreateMemoryContext(
  680. HDC hDC,
  681. PDISPLAY_ITEM DisplayItem
  682. )
  683. /*++
  684. Routine Description:
  685. Create a memory context and a memory bitmap for each perf window
  686. Arguments:
  687. hDC - Device Context for window
  688. DisplayItem - Data structure with all perf window info
  689. Return Value:
  690. status of operation
  691. Revision History:
  692. 03-21-91 Initial code
  693. --*/
  694. {
  695. int Width;
  696. int Height;
  697. if (DisplayItem->Display == TRUE) {
  698. //
  699. // Calculate width of memory bitmap needed
  700. //
  701. Width = DisplayItem->GraphBorder.right - DisplayItem->GraphBorder.left;
  702. Height = DisplayItem->GraphBorder.bottom - DisplayItem->GraphBorder.top;
  703. if ((Width<=0) || (Height <= 0)) {
  704. //
  705. // Disable this window that is to small to be seen
  706. //
  707. DisplayItem->Display = FALSE;
  708. return(TRUE);
  709. }
  710. //
  711. // Create DC and Bitmap
  712. //
  713. DisplayItem->MemoryDC = CreateCompatibleDC(hDC);
  714. if (DisplayItem->MemoryDC == NULL) {
  715. return(FALSE);
  716. }
  717. //DbgPrint("Createcompatiblebitmap %i %i\n",Width,Height);
  718. DisplayItem->MemoryBitmap = CreateCompatibleBitmap(hDC,Width,Height);
  719. if (DisplayItem->MemoryBitmap == 0) {
  720. return(FALSE);
  721. }
  722. SelectObject(DisplayItem->MemoryDC,DisplayItem->MemoryBitmap);
  723. }
  724. return(TRUE);
  725. }
  726. VOID
  727. DeleteMemoryContext(
  728. PDISPLAY_ITEM DisplayItem
  729. )
  730. /*++
  731. Routine Description:
  732. Delete memory bitmap and context
  733. Arguments:
  734. hDC - Device Context for window
  735. DisplayItem - Data structure with all perf window info
  736. Return Value:
  737. status of operation
  738. Revision History:
  739. 03-21-91 Initial code
  740. --*/
  741. {
  742. if (DisplayItem->MemoryDC != NULL) {
  743. DeleteDC(DisplayItem->MemoryDC);
  744. }
  745. if (DisplayItem->MemoryBitmap != NULL) {
  746. DeleteObject(DisplayItem->MemoryBitmap);
  747. }
  748. }