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.

480 lines
9.5 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. Progress.cpp
  5. Abstract:
  6. Implementation of the old style progress bar class.
  7. Notes:
  8. ANSI only - must run on Win9x.
  9. History:
  10. 01/30/01 rparsons Created (Thanks to carlco)
  11. 01/10/02 rparsons Revised
  12. --*/
  13. #include "progress.h"
  14. /*++
  15. Routine Description:
  16. Constructor - initialize member variables.
  17. Arguments:
  18. None.
  19. Return Value:
  20. None.
  21. --*/
  22. CProgress::CProgress()
  23. {
  24. m_dwMax = 0;
  25. m_dwMin = 0;
  26. m_dwPos = 0;
  27. m_hWndParent = NULL;
  28. m_hWnd = NULL;
  29. m_hBackground = NULL;
  30. m_hComplete = NULL;
  31. m_hFont = NULL;
  32. }
  33. /*++
  34. Routine Description:
  35. Destructor - destroy objects and release memory.
  36. Arguments:
  37. None.
  38. Return Value:
  39. None.
  40. --*/
  41. CProgress::~CProgress()
  42. {
  43. if (IsWindow(m_hWnd) == TRUE) {
  44. DestroyWindow(m_hWnd);
  45. }
  46. if (m_hBackground) {
  47. DeleteObject(m_hBackground);
  48. }
  49. if (m_hComplete) {
  50. DeleteObject(m_hComplete);
  51. }
  52. if (m_hFont) {
  53. DeleteObject(m_hFont);
  54. }
  55. }
  56. /*++
  57. Routine Description:
  58. Sets up the progress bar class and creates the window.
  59. Arguments:
  60. hWndParent - Handle to the parent window.
  61. hInstance - Instance handle.
  62. x - Initial horizontal position of the window.
  63. y - Initial vertical position of the window.
  64. nWidth - Width, in device units, of the window.
  65. nHeight - Height, in device units, of the window.
  66. Return Value:
  67. 0 on success, -1 on failure.
  68. --*/
  69. int
  70. CProgress::Create(
  71. IN HWND hWndParent,
  72. IN HINSTANCE hInstance,
  73. IN LPSTR lpClassName,
  74. IN int x,
  75. IN int y,
  76. IN int nWidth,
  77. IN int nHeight
  78. )
  79. {
  80. WNDCLASS wc;
  81. ATOM aClass = NULL;
  82. //
  83. // Create brushes and the font.
  84. //
  85. m_hBackground = CreateSolidBrush(RGB(255,255,255));
  86. m_hComplete = CreateSolidBrush(RGB(0,20,244));
  87. m_hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
  88. //
  89. // Set up the windows class struct and register it.
  90. //
  91. ZeroMemory(&wc, sizeof(WNDCLASS));
  92. wc.style = CS_VREDRAW | CS_HREDRAW;
  93. wc.lpfnWndProc = CProgress::WndProc;
  94. wc.hInstance = hInstance;
  95. wc.hbrBackground = m_hBackground;
  96. wc.lpszClassName = lpClassName;
  97. aClass = RegisterClass(&wc);
  98. if (NULL == aClass) {
  99. return -1;
  100. }
  101. m_hWnd = CreateWindow(lpClassName,
  102. NULL,
  103. WS_CHILD | WS_VISIBLE,
  104. x,
  105. y,
  106. nWidth,
  107. nHeight,
  108. hWndParent,
  109. 0,
  110. hInstance,
  111. (LPVOID)this);
  112. return (m_hWnd ? 0 : -1);
  113. }
  114. /*++
  115. Routine Description:
  116. Sets the current position of the progress bar.
  117. Arguments:
  118. dwNew - The new value to set.
  119. Return Value:
  120. The new position.
  121. --*/
  122. DWORD
  123. CProgress::SetPos(
  124. IN DWORD dwNewPos
  125. )
  126. {
  127. m_dwPos = dwNewPos;
  128. this->Refresh();
  129. return m_dwPos;
  130. }
  131. /*++
  132. Routine Description:
  133. Sets the maximum range of the progress bar.
  134. Arguments:
  135. dwMax - The maximum value to set.
  136. Return Value:
  137. None.
  138. --*/
  139. void
  140. CProgress::SetMax(
  141. IN DWORD dwMax
  142. )
  143. {
  144. m_dwMax = dwMax;
  145. if (m_dwMin > dwMax) {
  146. m_dwMax = m_dwMin;
  147. }
  148. this->Refresh();
  149. }
  150. /*++
  151. Routine Description:
  152. Sets the minimum range of the progress bar.
  153. Arguments:
  154. dwMin - The minimum value to set.
  155. Return Value:
  156. None.
  157. --*/
  158. void
  159. CProgress::SetMin(
  160. IN DWORD dwMin
  161. )
  162. {
  163. m_dwMin = dwMin;
  164. if (m_dwMin > m_dwMax) {
  165. m_dwMin = m_dwMax;
  166. }
  167. this->Refresh();
  168. }
  169. /*++
  170. Routine Description:
  171. Runs the message loop for the progress bar.
  172. Arguments:
  173. hWnd - Owner window handle.
  174. uMsg - Windows message.
  175. wParam - Additional message info.
  176. lParam - Additional message info.
  177. Return Value:
  178. TRUE if the message was handled, FALSE otherwise.
  179. --*/
  180. LRESULT
  181. CALLBACK
  182. CProgress::WndProc(
  183. IN HWND hWnd,
  184. IN UINT uMsg,
  185. IN WPARAM wParam,
  186. IN LPARAM lParam
  187. )
  188. {
  189. CProgress *pThis = (CProgress*)GetWindowLong(hWnd, GWL_USERDATA);
  190. switch(uMsg) {
  191. case WM_CREATE:
  192. {
  193. LPCREATESTRUCT cs = (LPCREATESTRUCT)lParam;
  194. pThis = (CProgress*)cs->lpCreateParams;
  195. SetWindowLong(hWnd, GWL_USERDATA, (LONG)pThis);
  196. return 0;
  197. }
  198. case WM_PAINT:
  199. pThis->OnPaint();
  200. return 0;
  201. }
  202. return DefWindowProc(hWnd, uMsg, wParam, lParam);
  203. }
  204. /*++
  205. Routine Description:
  206. Ensure that are values are within their specified
  207. ranges.
  208. Arguments:
  209. None.
  210. Return Value:
  211. None.
  212. --*/
  213. inline
  214. void
  215. CProgress::CorrectBounds()
  216. {
  217. if (m_dwPos < m_dwMin) {
  218. m_dwPos = m_dwMin;
  219. }
  220. if (m_dwPos > m_dwMax) {
  221. m_dwPos = m_dwMax;
  222. }
  223. }
  224. /*++
  225. Routine Description:
  226. Forces a redraw of the progress bar.
  227. Arguments:
  228. None.
  229. Return Value:
  230. None.
  231. --*/
  232. void
  233. CProgress::Refresh()
  234. {
  235. InvalidateRect(m_hWnd, NULL, FALSE);
  236. }
  237. /*++
  238. Routine Description:
  239. Does all the work of making the progress bar move and drawing the text.
  240. Arguments:
  241. None.
  242. Return Value:
  243. None.
  244. --*/
  245. void
  246. CProgress::OnPaint()
  247. {
  248. PAINTSTRUCT ps;
  249. RECT rcClientRect;
  250. RECT rcComplete;
  251. RECT rcTheRest;
  252. RECT rcTextBounds;
  253. RECT rcTextComplete;
  254. RECT rcTextTheRest;
  255. DWORD dwRange = (m_dwMax - m_dwMin);
  256. char szPercent[5];
  257. SIZE TextSize;
  258. HRESULT hr;
  259. BeginPaint(m_hWnd, &ps);
  260. SetBkMode(ps.hdc, TRANSPARENT);
  261. SelectObject(ps.hdc, m_hFont);
  262. GetClientRect(m_hWnd, &rcClientRect);
  263. InflateRect(&rcClientRect, -2,-2); // this will make the DrawFrame() function look nicer
  264. //
  265. // Get the pixel offset of the completed area.
  266. //
  267. float Ratio = (float)m_dwPos / (float)dwRange;
  268. int nOffset = (int)(Ratio * rcClientRect.right);
  269. //
  270. // Get the RECT for completed area.
  271. //
  272. SetRect(&rcComplete, 0, 0, nOffset, rcClientRect.bottom);
  273. //
  274. // Get the RECT for the rest.
  275. //
  276. SetRect(&rcTheRest, nOffset, 0, rcClientRect.right, rcClientRect.bottom);
  277. //
  278. // Get the percent, text, and size of the text...
  279. //
  280. hr = StringCchPrintf(szPercent,
  281. sizeof(szPercent),
  282. "%3d%%",
  283. (DWORD)(100 * ((float)m_dwPos / (float)dwRange)));
  284. if (FAILED(hr)) {
  285. return;
  286. }
  287. GetTextExtentPoint32(ps.hdc, szPercent, strlen(szPercent), &TextSize);
  288. //
  289. // Figure out where to draw the text.
  290. //
  291. rcTextBounds.top = 0;
  292. rcTextBounds.bottom = rcClientRect.bottom;
  293. rcTextBounds.left = (rcClientRect.right / 2) - (TextSize.cx / 2);
  294. rcTextBounds.right = (rcClientRect.right / 2) + (TextSize.cx / 2);
  295. CopyRect(&rcTextComplete, &rcTextBounds);
  296. CopyRect(&rcTextTheRest, &rcTextBounds);
  297. rcTextComplete.right = rcComplete.right;
  298. rcTextTheRest.left = rcTheRest.left;
  299. FillRect(ps.hdc, &rcComplete, m_hComplete);
  300. FillRect(ps.hdc, &rcTheRest, m_hBackground);
  301. //
  302. // Draw the completed text.
  303. //
  304. SetTextColor(ps.hdc, RGB(255,255,255));
  305. HRGN hTextComplete = CreateRectRgn(rcTextComplete.left,
  306. rcTextComplete.top,
  307. rcTextComplete.right,
  308. rcTextComplete.bottom);
  309. SelectClipRgn(ps.hdc, hTextComplete);
  310. DrawText(ps.hdc,
  311. szPercent,
  312. strlen(szPercent),
  313. &rcTextBounds,
  314. DT_SINGLELINE | DT_VCENTER | DT_CENTER);
  315. DeleteObject(hTextComplete);
  316. //
  317. // Draw the completed text.
  318. //
  319. SetTextColor(ps.hdc, RGB(0,0,255));
  320. HRGN hTextTheRest = CreateRectRgn(rcTextTheRest.left,
  321. rcTextTheRest.top,
  322. rcTextTheRest.right,
  323. rcTextTheRest.bottom);
  324. SelectClipRgn(ps.hdc, hTextTheRest);
  325. DrawText(ps.hdc,
  326. szPercent,
  327. strlen(szPercent),
  328. &rcTextBounds,
  329. DT_SINGLELINE | DT_VCENTER | DT_CENTER);
  330. DeleteObject(hTextTheRest);
  331. //
  332. // And draw a frame around it.
  333. //
  334. GetClientRect(m_hWnd, &rcClientRect); //refresh this because we changed it above
  335. HRGN hEntireRect = CreateRectRgn(rcClientRect.left,
  336. rcClientRect.top,
  337. rcClientRect.right,
  338. rcClientRect.bottom);
  339. SelectClipRgn(ps.hdc, hEntireRect);
  340. DrawEdge(ps.hdc, &rcClientRect, EDGE_SUNKEN, BF_RECT);
  341. DeleteObject(hEntireRect);
  342. EndPaint(m_hWnd, &ps);
  343. }