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.

540 lines
16 KiB

  1. //*****************************************************************************************************************
  2. //
  3. // CLASS: DISKDISPLAY
  4. //
  5. // COPYRIGHT� 2001 Microsoft Corporation and Executive Software International, Inc.
  6. //
  7. // CLASS DESCRIPTION:
  8. // Uses an array passed in from the DiskView class called the LineArray that contains the necessary
  9. // data to draw a graphical representation of a disk. Each byte in the LineArray is set to a specific
  10. // value that specifies the color of a corresponding vertical line on the screen when painted using
  11. // the DiskDisplay class. This class also handles the painting of a legend at the bottom of the display
  12. // and data about the size of the disk, etc. All the computational data for the display is done by
  13. // DiskView; DiskDisplay just paints it on the screen.
  14. //
  15. //*****************************************************************************************************************
  16. #include "stdafx.h"
  17. #include "DiskDisp.h"
  18. #include "Graphix.h"
  19. #include "ErrMacro.h"
  20. /*****************************************************************************************************************
  21. METHOD: DiskDisplay::DiskDisplay (Constructor)
  22. METHOD DESCRIPTION:
  23. Initializes class variables.
  24. RETURN:
  25. None.
  26. */
  27. DiskDisplay::DiskDisplay()
  28. {
  29. int i;
  30. //There is not yet data to draw with, so don't execute drawing functions later on until there is data to draw.
  31. m_bReadyToDraw = FALSE;
  32. m_LineArray = NULL;
  33. m_NumLines = 0;
  34. m_SpacerHeight = SPACER_HEIGHT;
  35. m_GraphicWellWidth = 0;
  36. m_GraphicWellHeight = 0;
  37. _tcscpy(m_Label, TEXT(""));
  38. //Allocate internal arrays for the maximum number of colors of lines we will be displaying.
  39. m_ColorArray = NULL;
  40. m_PenArray = NULL;
  41. m_BrushArray = NULL;
  42. //Initialize the colors for the various lines.
  43. m_ColorArray = new int [NUM_COLORS];
  44. EV(m_ColorArray);
  45. ChangeLineColor(SystemFileColor, GREEN); // System files
  46. ChangeLineColor(PageFileColor, YELLOW); // Pagefile
  47. ChangeLineColor(FragmentColor, RED); // Fragmented files
  48. ChangeLineColor(UsedSpaceColor, BLUE); // Contiguous files
  49. ChangeLineColor(FreeSpaceColor, LIGHTGRAY); // Free space
  50. ChangeLineColor(DirectoryColor, LIGHTBLUE); // Directories
  51. ChangeLineColor(MftZoneFreeSpaceColor, BLUE); // MFT Zone sks defrag mft changed from GREEN
  52. m_bStripeMftZone = TRUE;
  53. //Create all the pens that we'll draw with.
  54. m_PenArray = new HPEN [NUM_COLORS];
  55. EV(m_PenArray);
  56. for(i=0; i<NUM_COLORS; i++){
  57. m_PenArray[i] = CreatePen(PS_SOLID, 1, m_ColorArray[i]);
  58. EH(m_PenArray[i]);
  59. }
  60. //Create all the brushes that we'll draw with.
  61. m_BrushArray = new HBRUSH [NUM_COLORS];
  62. EV(m_BrushArray);
  63. for(i=0; i<NUM_COLORS; i++){
  64. m_BrushArray[i] = CreateHatchBrush(HS_BDIAGONAL, m_ColorArray[i]);
  65. EH(m_BrushArray[i]);
  66. }
  67. m_hCurrentPen = 0;
  68. }
  69. /*****************************************************************************************************************
  70. METHOD: DiskDisplay::~DiskDisplay (Destructor)
  71. COPYRIGHT 2001 Microsoft Corporation and Executive Software International, Inc.
  72. METHOD DESCRIPTION:
  73. Does cleanup.
  74. */
  75. DiskDisplay::~DiskDisplay()
  76. {
  77. int i;
  78. if (m_LineArray)
  79. delete [] m_LineArray;
  80. if (m_PenArray) {
  81. for(i=0; i<NUM_COLORS; i++){
  82. if (m_PenArray[i])
  83. DeleteObject(m_PenArray[i]);
  84. }
  85. delete [] m_PenArray;
  86. }
  87. if (m_BrushArray) {
  88. for(i=0; i<NUM_COLORS; i++){
  89. if (m_BrushArray[i])
  90. DeleteObject(m_BrushArray[i]);
  91. }
  92. delete [] m_BrushArray;
  93. }
  94. if (m_ColorArray)
  95. delete [] m_ColorArray;
  96. }
  97. /*****************************************************************************************************************
  98. METHOD: DiskView::operator=
  99. COPYRIGHT 2001 Microsoft Corporation and Executive Software International, Inc.
  100. METHOD DESCRIPTION:
  101. Duplicates a DiskDisplay.
  102. CLASS VARIABLES:
  103. INPUT + OUTPUT:
  104. RETURN:
  105. none.
  106. */
  107. DiskDisplay& DiskDisplay::operator=(DiskDisplay& InDiskDisplay)
  108. {
  109. if(this == &InDiskDisplay){
  110. return *this;
  111. }
  112. //If the other DiskDisplay has data to draw, then so will we.
  113. m_bReadyToDraw = InDiskDisplay.m_bReadyToDraw;
  114. //Don't need to do anything with m_PenArray, m_BrushArray, or m_ColorArray since these are already created by the constructor.
  115. m_hCurrentPen = InDiskDisplay.m_hCurrentPen;
  116. //If the number of clusters in the cluster array are not identical, realloc the array.
  117. if(m_NumLines != InDiskDisplay.m_NumLines){
  118. //Get the new size for the cluster array.
  119. m_NumLines = InDiskDisplay.m_NumLines;
  120. //Redimension the cluster array.
  121. if (m_LineArray)
  122. delete [] m_LineArray;
  123. m_LineArray = new char [m_NumLines];
  124. EH(m_LineArray);
  125. }
  126. //Copy over the line array.
  127. if (m_LineArray != NULL && InDiskDisplay.m_LineArray != NULL)
  128. CopyMemory(m_LineArray, InDiskDisplay.m_LineArray, m_NumLines);
  129. return *this;
  130. }
  131. /*****************************************************************************************************************
  132. METHOD: DiskDisplay::SetNewOutputDimensions
  133. COPYRIGHT 2001 Microsoft Corporation and Executive Software International, Inc.
  134. METHOD DESCRIPTION:
  135. Given new coordinates to draw in, calculate anew how many lines we can draw in and figure what the
  136. m_ClusterFactor now is. Reset all the appropriate variables and redimension the internal arrays.
  137. INPUT + OUTPUT:
  138. rect - rectangle that borders the entire graphics area
  139. isSingleRow - set to TRUE is the rectangle holds a single row of graphics
  140. spacerHeight - number of pixels between each graphic well
  141. RETURN:
  142. None.
  143. */
  144. void DiskDisplay::SetOutputArea(RECT rect, BOOL isSingleRow, UINT spacerHeight)
  145. {
  146. m_GraphicWellWidth = rect.right - rect.left - 1;
  147. m_Rect = rect;
  148. if (isSingleRow){
  149. m_SpacerHeight = 0;
  150. m_NumGraphicsRows = 1;
  151. m_GraphicWellHeight = rect.bottom - rect.top - 1;
  152. }
  153. else {
  154. m_SpacerHeight = spacerHeight;
  155. m_GraphicWellHeight = GRAPHIC_WELL_HEIGHT;
  156. m_NumGraphicsRows = (rect.bottom - rect.top + m_SpacerHeight) / (m_GraphicWellHeight + m_SpacerHeight);
  157. }
  158. int numLines = m_NumGraphicsRows * m_GraphicWellWidth;
  159. EV_ASSERT(numLines);
  160. if (numLines != m_NumLines){
  161. m_NumLines = numLines;
  162. if (m_LineArray)
  163. delete [] m_LineArray;
  164. m_LineArray = new char [m_NumLines];
  165. EV(m_LineArray);
  166. m_bReadyToDraw = FALSE;
  167. }
  168. }
  169. /*****************************************************************************************************************
  170. METHOD: DiskDisplay::ChangeLineColor
  171. COPYRIGHT 2001 Microsoft Corporation and Executive Software International, Inc.
  172. METHOD DESCRIPTION:
  173. Sets the color of in the ColorArray to a passed in color.
  174. CLASS VARIABLES:
  175. m_ColorArray - The ColorArray.
  176. INPUT + OUTPUT:
  177. iSet - The index in the ColorArray to set to NewColor.
  178. NewColor - The new color to put in the array.
  179. RETURN:
  180. None.
  181. */
  182. void DiskDisplay::ChangeLineColor(int iSet, int NewColor)
  183. {
  184. require(iSet < NUM_COLORS);
  185. // this is a no-op if there is no color array allocated
  186. if (m_ColorArray != NULL){
  187. //The RGB values define the red, green, and blue contents for each of these colors.
  188. //These numbers give good results over different color setups (256 colors, or 65536 colors).
  189. switch (NewColor){
  190. case BLACK:
  191. m_ColorArray[iSet] = RGB(0, 0, 0);
  192. break;
  193. case RED:
  194. m_ColorArray[iSet] = RGB(220, 0, 0);
  195. break;
  196. case GREEN:
  197. m_ColorArray[iSet] = RGB(0, 220, 0);
  198. break;
  199. case YELLOW:
  200. m_ColorArray[iSet] = RGB(220, 220, 0);
  201. break;
  202. case BLUE:
  203. m_ColorArray[iSet] = RGB(0, 0, 220);
  204. break;
  205. case PURPLE:
  206. m_ColorArray[iSet] = RGB(200, 0, 200);
  207. break;
  208. case LIGHTBLUE:
  209. m_ColorArray[iSet] = RGB(0, 255, 255);
  210. break;
  211. case WHITE:
  212. m_ColorArray[iSet] = RGB(255, 255, 255);
  213. break;
  214. case LIGHTGRAY:
  215. m_ColorArray[iSet] = RGB(200, 200, 200);
  216. break;
  217. default:
  218. EV_ASSERT(FALSE);
  219. break;
  220. }
  221. }
  222. }
  223. /*****************************************************************************************************************
  224. METHOD: DiskDisplay::SetNewLineColor
  225. COPYRIGHT 2001 Microsoft Corporation and Executive Software International, Inc.
  226. METHOD DESCRIPTION:
  227. Changes the color of one of the types of display lines.
  228. INPUT + OUTPUT:
  229. iSet - The index in the ColorArray to set to NewColor.
  230. NewColor - The new color to put in the array.
  231. RETURN:
  232. None.
  233. */
  234. void DiskDisplay::SetNewLineColor(int iSet, int NewColor)
  235. {
  236. require(iSet < NUM_COLORS);
  237. if(m_ColorArray != NULL){
  238. ChangeLineColor(iSet, NewColor);
  239. if (m_PenArray != NULL){
  240. if (m_PenArray[iSet]){
  241. EH_ASSERT(DeleteObject(m_PenArray[iSet]));
  242. }
  243. m_PenArray[iSet] = CreatePen(PS_SOLID, 1, m_ColorArray[iSet]);
  244. EH(m_PenArray[iSet]);
  245. }
  246. if (m_BrushArray != NULL){
  247. if (m_BrushArray[iSet]){
  248. EH_ASSERT(DeleteObject(m_BrushArray[iSet]));
  249. }
  250. m_BrushArray[iSet] = CreateHatchBrush(HS_BDIAGONAL, m_ColorArray[iSet]);
  251. EH(m_BrushArray[iSet]);
  252. }
  253. }
  254. }
  255. /*****************************************************************************************************************
  256. METHOD: DiskDisplay::StripeMftZoneFreeSpace
  257. COPYRIGHT 2001 Microsoft Corporation and Executive Software International, Inc.
  258. METHOD DESCRIPTION:
  259. Determines whether the MFT zone is displayed as a striped color or as a solid color.
  260. INPUT + OUTPUT:
  261. bInStripeMftZone - The value to set to.
  262. RETURN:
  263. None.
  264. */
  265. void DiskDisplay::StripeMftZoneFreeSpace(BOOL bInStripeMftZone)
  266. {
  267. m_bStripeMftZone = bInStripeMftZone;
  268. }
  269. /*****************************************************************************************************************
  270. METHOD: DiskDisplay::DrawLinesInHDC
  271. COPYRIGHT 2001 Microsoft Corporation and Executive Software International, Inc.
  272. METHOD DESCRIPTION:
  273. Draw the display.
  274. INPUT + OUTPUT:
  275. hWndOutput - The window handle to use for painting functions.
  276. WorkDC - The DC to output to.
  277. rcPaint - The rectangle to paint within (usually because a portion of the screen was covered up by
  278. another window). NULL if no paint area specified.
  279. RETURN:
  280. None.
  281. */
  282. void DiskDisplay::DrawLinesInHDC(HDC WorkDC)
  283. {
  284. RECT BoxRect;
  285. m_hCurrentPen = 0;
  286. //Draw each line in the HDC.
  287. BoxRect.left = m_Rect.left;
  288. BoxRect.right = m_Rect.right;
  289. ::SetBkColor(WorkDC, RGB(255, 255, 255));
  290. ::SetBkMode(WorkDC, OPAQUE);
  291. int iLine = 0;
  292. int yOffset;
  293. for (int row=0; row<m_NumGraphicsRows; row++) {
  294. yOffset = m_Rect.top + (m_GraphicWellHeight + m_SpacerHeight) * row;
  295. //Make a box around this row
  296. BoxRect.top = yOffset-1;
  297. BoxRect.bottom = yOffset + m_GraphicWellHeight;
  298. // Fill the dark gray graphics area
  299. HBRUSH hBrush = ::CreateSolidBrush(GetSysColor(COLOR_3DSHADOW));
  300. EV_ASSERT(hBrush);
  301. ::FillRect(WorkDC, &BoxRect, hBrush);
  302. ::DeleteObject(hBrush);
  303. // draw a border
  304. ::DrawBorderEx(WorkDC, BoxRect, SUNKEN_BOX);
  305. // draw the label in the center of the first well
  306. if (row==0 && _tcslen(m_Label)) {
  307. // make the text white in all color schemes
  308. SetTextColor(WorkDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
  309. SetBkMode(WorkDC, TRANSPARENT);
  310. ::DrawText(WorkDC, m_Label, _tcslen(m_Label), &BoxRect, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
  311. }
  312. if (m_bReadyToDraw && m_LineArray){
  313. //Draw the individual lines
  314. for(int line=0; line < m_GraphicWellWidth && iLine < m_NumLines; line++){
  315. DrawLine(WorkDC, m_LineArray[iLine++], m_Rect.left + line + 1, yOffset, yOffset + m_GraphicWellHeight);
  316. }
  317. }
  318. }
  319. }
  320. /*****************************************************************************************************************
  321. METHOD: DiskDisplay::DrawLine
  322. COPYRIGHT 2001 Microsoft Corporation and Executive Software International, Inc.
  323. METHOD DESCRIPTION:
  324. Draw one line in the display.
  325. CLASS VARIABLES:
  326. m_PenArray - An array of pens of different colors that we use to draw the lines.
  327. m_BrushArray - An array of brushes we also use to draw the lines.
  328. m_xOut - The x coordinate of the upper left-hand corner of the box we can paint in in the HDC.
  329. m_yOut - The y coordinate.
  330. m_hCurrentPen - The pen selected into the DC last time DrawLine was called (used so we don't keep reselecting the same pen into the same DC).
  331. INPUT + OUTPUT:
  332. WorkDC - The DC to draw in.
  333. Line - The color to draw
  334. RETURN:
  335. None.
  336. */
  337. inline void DiskDisplay::DrawLine(
  338. HDC WorkDC,
  339. char Color,
  340. int x,
  341. int yStart,
  342. int yEnd)
  343. {
  344. if(m_BrushArray != NULL && m_PenArray != NULL){
  345. //Striped colors.
  346. if(m_bStripeMftZone && Color == MftZoneFreeSpaceColor){
  347. RECT Rect;
  348. //Get the appropriate brush.
  349. if (m_hCurrentBrush != (HBRUSH)m_BrushArray[MftZoneFreeSpaceColor]){
  350. m_hCurrentBrush = (HBRUSH)m_BrushArray[MftZoneFreeSpaceColor];
  351. }
  352. //Get the rectangle for one line.
  353. Rect.left = x;
  354. Rect.right = x + 1;
  355. Rect.top = yStart;
  356. Rect.bottom = Rect.top + m_GraphicWellHeight;
  357. //Draw the striped line.
  358. FillRect(WorkDC, &Rect, m_hCurrentBrush);
  359. }
  360. //Solid colors.
  361. else{
  362. //Get the appropriate pen.
  363. if (m_hCurrentPen != (HPEN)m_PenArray[Color]){
  364. SelectObject(WorkDC, (HPEN)m_PenArray[Color]);
  365. m_hCurrentPen = (HPEN)m_PenArray[Color];
  366. }
  367. //Draw the line.
  368. MoveToEx(WorkDC, x, yStart, NULL);
  369. LineTo(WorkDC, x, yEnd);
  370. }
  371. }
  372. }
  373. /*****************************************************************************************************************
  374. METHOD: DiskDisplay::SetLineArray
  375. COPYRIGHT 2001 Microsoft Corporation and Executive Software International, Inc.
  376. METHOD DESCRIPTION:
  377. Store a new LineArray from the DiskView class.
  378. CLASS VARIABLES:
  379. m_NumLines - How many lines we have in m_LineArray.
  380. m_LineArray - The array of bytes that store the color code for each line to display.
  381. INPUT + OUTPUT:
  382. pInLineArray - Passed in buffer to be copied to m_LineArray.
  383. InNumLines - The number of lines in this passed in buffer.
  384. RETURN:
  385. TRUE - Success.
  386. FALSE - Invalid size buffer was passed in.
  387. */
  388. void DiskDisplay::SetLineArray(char* pInLineArray, int InNumLines)
  389. {
  390. //If the size of the passed in buffer does not match what we're expecting, bail out.
  391. if (InNumLines > 0 && InNumLines == m_NumLines){
  392. //Copy the new buffer into the LineArray buffer.
  393. if (m_LineArray) {
  394. CopyMemory(m_LineArray, pInLineArray, m_NumLines);
  395. //Note that we now have data to draw with.
  396. m_bReadyToDraw = TRUE;
  397. }
  398. }
  399. }
  400. void DiskDisplay::SetReadyToDraw(IN BOOL bReadyToDraw)
  401. {
  402. m_bReadyToDraw = bReadyToDraw;
  403. }
  404. void DiskDisplay::DeleteAllData(void)
  405. {
  406. m_bReadyToDraw = FALSE;
  407. }
  408. void DiskDisplay::SetLabel(PTCHAR InLabel)
  409. {
  410. if (InLabel) {
  411. if (_tcslen(InLabel) > MAX_PATH * 2 - 3) {
  412. _tcsncpy(m_Label, InLabel, MAX_PATH * 2 - 3);
  413. m_Label[MAX_PATH * 2 - 3] = TEXT('\0');
  414. _tcscat(m_Label, TEXT("..."));
  415. }
  416. else {
  417. _tcscpy(m_Label, InLabel);
  418. }
  419. }
  420. else {
  421. _tcscpy(m_Label, TEXT(""));
  422. }
  423. }