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.

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