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.

384 lines
9.6 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORP., 1993-1995
  4. * TITLE: FUELBAR.CPP
  5. * VERSION: 1.0
  6. * AUTHOR: jsenior
  7. * DATE: 10/28/1998
  8. *
  9. ********************************************************************************
  10. *
  11. * CHANGE LOG:
  12. *
  13. * DATE REV DESCRIPTION
  14. * ---------- ------- ----------------------------------------------------------
  15. * 10/28/1998 jsenior Original implementation.
  16. *
  17. *******************************************************************************/
  18. #include "FuelBar.h"
  19. #include "debug.h"
  20. #include <assert.h>
  21. const int FuelBar::NoImage = -1;
  22. const LPVOID FuelBar::NoID = (const LPVOID) -1;
  23. FuelBar::FuelBar() : currentTotalValue(0), highlightID(NoID),
  24. maxValue(100), calcRects(FALSE), hImageList(0)
  25. {
  26. GetSysColors();
  27. }
  28. FuelBar::~FuelBar()
  29. {
  30. Clear();
  31. }
  32. BOOL FuelBar::SubclassDlgItem( UINT nID, HWND hParent)
  33. {
  34. hwnd = GetDlgItem(hParent, nID);
  35. FuelSetWindowLongPtr(hwnd, FUELGWLP_USERDATA, (FUELLONG_PTR) this);
  36. prevWndProc = (WNDPROC) FuelSetWindowLongPtr(hwnd,
  37. FUELGWLP_WNDPROC,
  38. (FUELDWORD_PTR) StaticWndProc);
  39. return TRUE;
  40. }
  41. UINT FuelBar::AddItem(UINT Value, LPVOID ID, int ImageIndex)
  42. {
  43. FuelBarItem item;
  44. if (!Value)
  45. return 0;
  46. if (currentTotalValue + Value > maxValue)
  47. return 0;
  48. currentTotalValue += Value;
  49. item.value = Value;
  50. item.id = ID;
  51. item.imageIndex = ImageIndex;
  52. items.push_back(item);
  53. calcRects = TRUE;
  54. return currentTotalValue;
  55. }
  56. BOOL FuelBar::RemoveItem(LPVOID ID)
  57. {
  58. if (highlightID == ID) {
  59. highlightID = (LPVOID) NoID;
  60. }
  61. FuelBarItem *item;
  62. for (item = items.begin(); item; item = items.next()) {
  63. if (item->id == ID) {
  64. items.eraseCurrent();
  65. return TRUE;
  66. }
  67. }
  68. return FALSE;
  69. }
  70. void FuelBar::ClearItems()
  71. {
  72. Clear();
  73. InvalidateRect(hwnd, NULL, TRUE);
  74. }
  75. BOOL FuelBar::HighlightItem(LPVOID ID)
  76. {
  77. // do nothing if the id is the same
  78. if (ID == highlightID)
  79. return TRUE;
  80. FuelBarItem *item;
  81. highlightID = 0;
  82. //
  83. // Make sure that ID is indeed a member
  84. //
  85. for (item = items.begin(); item; item = items.next()) {
  86. if (item->id == ID) {
  87. highlightID = ID;
  88. break;
  89. }
  90. }
  91. // the total redrawing of the ctrl will erase the old and draw the new
  92. InvalidateRect(hwnd, NULL, FALSE);
  93. if (ID != highlightID) {
  94. return FALSE;
  95. }
  96. return TRUE;
  97. }
  98. void FuelBar::Clear()
  99. {
  100. items.clear();
  101. currentTotalValue = 0;
  102. calcRects = TRUE;
  103. }
  104. void FuelBar::CalculateRects(const RECT& ClientRect)
  105. {
  106. FuelBarItem *item, *prevItem;
  107. if (items.empty()) {
  108. calcRects = FALSE;
  109. return;
  110. }
  111. item = items.begin();
  112. item->rect = ClientRect;
  113. item->rect.right = ClientRect.left + 1 +
  114. (item->value * (ClientRect.right - ClientRect.left))/maxValue;
  115. prevItem = item;
  116. for (item = items.next(); item; item = items.next()) {
  117. item->rect.top = prevItem->rect.top;
  118. item->rect.bottom = prevItem->rect.bottom;
  119. item->rect.left = prevItem->rect.right;
  120. // Fill rect does not render the outside edge
  121. item->rect.right = item->rect.left + 1 +
  122. (item->value * (ClientRect.right - ClientRect.left))/maxValue;
  123. prevItem = item;
  124. }
  125. // make sure that if the bar is full, that the last item is rendered to
  126. // the edge of the entire bar
  127. if (currentTotalValue == maxValue)
  128. item->rect.right = ClientRect.right;
  129. calcRects = FALSE;
  130. }
  131. void FuelBar::SetImageList(HIMAGELIST ImageList)
  132. {
  133. IMAGEINFO imageInfo;
  134. hImageList = ImageList;
  135. ZeroMemory(&imageInfo, sizeof(IMAGEINFO));
  136. if (ImageList_GetImageInfo(hImageList, 0, &imageInfo)) {
  137. imageWidth = imageInfo.rcImage.right - imageInfo.rcImage.left;
  138. imageHeight = imageInfo.rcImage.bottom - imageInfo.rcImage.top;
  139. }
  140. else {
  141. assert(FALSE);
  142. }
  143. }
  144. void FuelBar::GetSysColors()
  145. {
  146. colorFace = GetSysColor(COLOR_3DFACE);
  147. colorLight = GetSysColor(COLOR_3DHILIGHT);
  148. colorDark = GetSysColor(COLOR_3DSHADOW);
  149. colorUnused = GetSysColor(COLOR_WINDOW);
  150. }
  151. /////////////////////////////////////////////////////////////////////////////
  152. // FuelBar message handlers
  153. void FillSolidRect(HDC dc,
  154. LPCRECT rect,
  155. COLORREF color)
  156. {
  157. SetBkColor(dc, color);
  158. ExtTextOut(dc, 0, 0, ETO_OPAQUE, rect, NULL, 0, NULL);
  159. }
  160. void FillSolidRect(HDC dc, int x, int y, int cx, int cy, COLORREF color)
  161. {
  162. RECT rect;
  163. rect.left = x;
  164. rect.right = x + cx;
  165. rect.top = y;
  166. rect.bottom = y + cy;
  167. SetBkColor(dc, color);
  168. ExtTextOut(dc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
  169. }
  170. void Draw3dRect(HDC dc,
  171. int x,
  172. int y,
  173. int cx,
  174. int cy,
  175. COLORREF clrTopLeft,
  176. COLORREF clrBottomRight,
  177. COLORREF clrFace)
  178. {
  179. FillSolidRect(dc, x, y, cx - 1, 1, clrTopLeft);
  180. FillSolidRect(dc, x, y, 1, cy - 1, clrTopLeft);
  181. FillSolidRect(dc, x + cx, y, -1, cy, clrBottomRight);
  182. FillSolidRect(dc, x, y + cy, cx, -1, clrBottomRight);
  183. FillSolidRect(dc, x+1, y+1, cx-2, cy-2, clrFace) ;
  184. }
  185. void FuelBar::OnPaint()
  186. {
  187. HDC dc;
  188. PAINTSTRUCT ps;
  189. RECT clientRect, *highlightRect, remainingRect;
  190. POINT pt;
  191. FuelBarItem *item, *prevItem;
  192. HBRUSH hBrush, hOldBrush;
  193. BOOL highlightFound = FALSE;
  194. dc = BeginPaint(hwnd, &ps);
  195. hBrush = CreateSolidBrush(colorFace);
  196. hOldBrush = (HBRUSH) SelectObject(dc, hBrush);
  197. GetClientRect(hwnd, &clientRect);
  198. FillSolidRect(dc, &clientRect, colorUnused);
  199. if (calcRects) {
  200. CalculateRects(clientRect);
  201. // FillSolidRect(dc, &clientRect, colorFace);
  202. }
  203. for (item = items.begin(); item; item = items.next()) {
  204. Draw3dRect(dc,
  205. item->rect.left,
  206. item->rect.top,
  207. item->rect.right - item->rect.left,
  208. item->rect.bottom - item->rect.top,
  209. colorLight,
  210. colorDark,
  211. colorFace);
  212. if (item->imageIndex != NoImage &&
  213. (item->rect.right - item->rect.left) > imageWidth) {
  214. // render the image in the center of the rectangle
  215. pt.x = item->rect.left +
  216. (item->rect.right - item->rect.left)/2 - (imageWidth)/2;
  217. pt.y = (item->rect.bottom - item->rect.top)/2 - (imageHeight)/2;
  218. ImageList_Draw(hImageList,
  219. item->imageIndex,
  220. dc,
  221. pt.x,
  222. pt.y,
  223. ILD_TRANSPARENT);
  224. }
  225. if (item->id == highlightID) {
  226. highlightRect = &item->rect;
  227. highlightFound = TRUE;
  228. }
  229. prevItem = item;
  230. }
  231. if (currentTotalValue < maxValue) {
  232. remainingRect = clientRect;
  233. if (!items.empty())
  234. remainingRect.left = prevItem->rect.right;
  235. FillSolidRect(dc, &remainingRect, colorUnused);
  236. }
  237. SelectObject(dc, hOldBrush);
  238. if (highlightFound) {
  239. // CPen pen(PS_SOLID, 1, RGB(0,0,0)), *oldPen;
  240. // oldPen = dc.SelectObject(&pen);
  241. HPEN hPen, hOldPen;
  242. hPen = CreatePen(PS_SOLID, 1, RGB(0,0,0));
  243. if (hPen) {
  244. hOldPen = (HPEN) SelectObject(dc, hPen);
  245. MoveToEx(dc, highlightRect->left, highlightRect->top, NULL);
  246. LineTo(dc, highlightRect->right-1, highlightRect->top);
  247. LineTo(dc, highlightRect->right-1, highlightRect->bottom-1);
  248. LineTo(dc, highlightRect->left, highlightRect->bottom-1);
  249. LineTo(dc, highlightRect->left, highlightRect->top);
  250. // dc.DrawFocusRect instead?
  251. SelectObject(dc, hOldPen);
  252. DeleteObject(hPen);
  253. }
  254. }
  255. EndPaint(hwnd, &ps);
  256. DeleteObject(hBrush);
  257. ValidateRect(hwnd, &clientRect);
  258. }
  259. BOOL FuelBar::OnToolTipNotify(UINT id, NMHDR * pNMHDR, LRESULT * pResult)
  260. {
  261. BOOL bHandledNotify = FALSE;
  262. #ifdef TOOL
  263. CPoint cursorPos;
  264. CRect clientRect;
  265. VERIFY(::GetCursorPos(&cursorPos));
  266. ScreenToClient(&cursorPos);
  267. GetClientRect(clientRect);
  268. // Make certain that the cursor is in the client rect, because the
  269. // mainframe also wants these messages to provide tooltips for the
  270. // toolbar.
  271. if (clientRect.PtInRect(cursorPos)) {
  272. FuelItem* item;
  273. int i;
  274. for (i = 0; i < items.GetSize(); i++) {
  275. item = (FuelItem*) items[i];
  276. }
  277. bHandledNotify = TRUE;
  278. }
  279. #endif
  280. return bHandledNotify;
  281. }
  282. void FuelBar::OnSysColorChange()
  283. {
  284. GetSysColors();
  285. }
  286. BOOL APIENTRY FuelBar::StaticWndProc(IN HWND hDlg,
  287. IN UINT uMessage,
  288. IN WPARAM wParam,
  289. IN LPARAM lParam)
  290. {
  291. FuelBar *that = (FuelBar*) FuelGetWindowLongPtr(hDlg, FUELGWLP_USERDATA);
  292. assert(that);
  293. switch (uMessage) {
  294. case WM_PAINT:
  295. that->OnPaint();
  296. break;
  297. }
  298. return (BOOL)CallWindowProc( (FUELPROC) that->prevWndProc,
  299. hDlg,
  300. uMessage,
  301. wParam,
  302. lParam);
  303. }
  304. LPVOID FuelBar::GetHighlightedItem()
  305. {
  306. return highlightID;
  307. }