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.

294 lines
7.3 KiB

  1. /*****************************************************************************
  2. *
  3. * Progress.c
  4. *
  5. * Copyright (c) 1996 Microsoft Corporation. All Rights Reserved.
  6. *
  7. * Abstract:
  8. *
  9. * Our private progress control (because commctrl might be damanged)
  10. *
  11. * Contents:
  12. *
  13. * Progress_Init
  14. *
  15. *****************************************************************************/
  16. #include "sigverif.h"
  17. /***************************************************************************
  18. *
  19. * GWL_* for Progress goo.
  20. *
  21. ***************************************************************************/
  22. #define GWL_CUR GWLP_USERDATA
  23. /***************************************************************************
  24. *
  25. * @doc INTERNAL
  26. *
  27. * @func int | Progress_GetRectPos |
  28. *
  29. * Compute the position within the drawing rectangle that
  30. * corresponds to the current position.
  31. *
  32. * This is basically a MulDiv, except that we don't let the
  33. * bar get all the way to 100% unless it really means it.
  34. *
  35. *
  36. ***************************************************************************/
  37. int Progress_GetRectPos(int cx, int iCur, int iMax)
  38. {
  39. int iRc;
  40. if (iCur != iMax) {
  41. iRc = MulDiv(cx, iCur, iMax);
  42. } else {
  43. iRc = cx;
  44. }
  45. return iRc;
  46. }
  47. /***************************************************************************
  48. *
  49. * @doc INTERNAL
  50. *
  51. * @func LRESULT | Progress_OnPaint |
  52. *
  53. * Draw the first part in the highlight colors.
  54. *
  55. * Draw the second part in the 3dface colors.
  56. *
  57. ***************************************************************************/
  58. void Progress_OnPaint(HWND hwnd)
  59. {
  60. HDC hdc;
  61. PAINTSTRUCT ps;
  62. hdc = BeginPaint(hwnd, &ps);
  63. if (hdc) {
  64. UINT taPrev;
  65. RECT rc;
  66. int cx;
  67. COLORREF clrTextPrev, clrBackPrev;
  68. int iCur, iMax, iPct;
  69. int ctch;
  70. HFONT hfPrev;
  71. TCHAR tsz[256];
  72. SIZE size;
  73. /*
  74. * Set up the DC generically.
  75. */
  76. taPrev = SetTextAlign(hdc, TA_CENTER | TA_TOP);
  77. hfPrev = SelectFont(hdc, GetWindowFont(GetParent(hwnd)));
  78. /*
  79. * Set up the colors for the left-hand side.
  80. */
  81. clrTextPrev = SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
  82. clrBackPrev = SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
  83. /*
  84. * Now do some math.
  85. */
  86. GetClientRect(hwnd, &rc);
  87. cx = rc.right;
  88. iCur = LOWORD(GetWindowLong(hwnd, GWL_CUR));
  89. iMax = HIWORD(GetWindowLong(hwnd, GWL_CUR));
  90. if (iMax == 0)
  91. {
  92. iMax = 1; /* Avoid divide by zero */
  93. }
  94. if (iCur > 0)
  95. {
  96. iPct = (iCur * 100) / iMax;
  97. if (iPct < 1)
  98. iPct = 1;
  99. } else iPct = 0;
  100. rc.right = Progress_GetRectPos(cx, iCur, iMax);
  101. // Update the percentage text in the progress bar.
  102. wsprintf(tsz, TEXT("%d%%"), iPct);
  103. for(ctch=0;tsz[ctch];ctch++);
  104. /*
  105. * Draw the left-hand side.
  106. */
  107. //ctch = GetWindowText(hwnd, tsz, cA(tsz));
  108. if (!GetTextExtentPoint32(hdc, tsz, ctch, &size))
  109. {
  110. ExtTextOut( hdc, cx/2, 1,
  111. ETO_CLIPPED | ETO_OPAQUE,
  112. &rc, tsz, ctch, 0);
  113. } else {
  114. ExtTextOut( hdc, cx/2, (rc.bottom - rc.top - size.cy + 1) / 2,
  115. ETO_CLIPPED | ETO_OPAQUE,
  116. &rc, tsz, ctch, 0);
  117. }
  118. /*
  119. * Now set up for the right-hand side.
  120. */
  121. SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
  122. SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
  123. rc.left = rc.right;
  124. rc.right = cx;
  125. /*
  126. * Draw the right-hand side.
  127. */
  128. if (!GetTextExtentPoint32(hdc, tsz, ctch, &size))
  129. {
  130. ExtTextOut( hdc, cx/2, 1,
  131. ETO_CLIPPED | ETO_OPAQUE,
  132. &rc, tsz, ctch, 0);
  133. } else {
  134. ExtTextOut( hdc, cx/2, (rc.bottom - rc.top - size.cy + 1) / 2,
  135. ETO_CLIPPED | ETO_OPAQUE,
  136. &rc, tsz, ctch, 0);
  137. }
  138. SetBkColor(hdc, clrBackPrev);
  139. SetTextColor(hdc, clrTextPrev);
  140. SelectFont(hdc, hfPrev);
  141. SetTextAlign(hdc, taPrev);
  142. EndPaint(hwnd, &ps);
  143. }
  144. }
  145. /***************************************************************************
  146. *
  147. * @doc INTERNAL
  148. *
  149. * @func LRESULT | Progress_OnSetPos |
  150. *
  151. * Update the state and invalidate the section that is affected.
  152. *
  153. ***************************************************************************/
  154. void Progress_OnSetPos(HWND hwnd, WPARAM wp)
  155. {
  156. int iCur, iMax;
  157. RECT rc;
  158. LONG lState = GetWindowLong(hwnd, GWL_CUR);
  159. GetClientRect(hwnd, &rc);
  160. iCur = LOWORD(GetWindowLong(hwnd, GWL_CUR));
  161. iMax = HIWORD(GetWindowLong(hwnd, GWL_CUR));
  162. if (iMax == 0) {
  163. iMax = 1; /* Avoid divide by zero */
  164. }
  165. rc.left = Progress_GetRectPos(rc.right, iCur, iMax);
  166. rc.right = Progress_GetRectPos(rc.right, (int)wp, iMax);
  167. InvalidateRect(hwnd, 0, 0);
  168. SetWindowLong(hwnd, GWL_CUR, MAKELONG(wp,HIWORD(lState)));
  169. }
  170. /***************************************************************************
  171. *
  172. * @doc INTERNAL
  173. *
  174. * @func LRESULT | Progress_WndProc |
  175. *
  176. * There really isn't much to do.
  177. *
  178. * The string is our window text (which Windows manages for us).
  179. *
  180. * The progress bar itself is kept in the high/low words of
  181. * our GWL_USERDATA.
  182. *
  183. * HIWORD(GetWindowLong(GWL_USERDATA)) = maximum
  184. * LOWORD(GetWindowLong(GWL_USERDATA)) = current value
  185. *
  186. ***************************************************************************/
  187. LRESULT CALLBACK
  188. Progress_WndProc(HWND hwnd, UINT wm, WPARAM wp, LPARAM lp)
  189. {
  190. switch (wm) {
  191. case WM_PAINT:
  192. Progress_OnPaint(hwnd);
  193. return 0;
  194. /*
  195. * When the range resets, invalidate so we repaint.
  196. *
  197. * wp = new current pos
  198. * lp = new range
  199. */
  200. case PBM_SETRANGE:
  201. lp = HIWORD(lp);
  202. SetWindowLong(hwnd, GWL_CUR, MAKELONG(wp, lp));
  203. /* FALLTHROUGH */
  204. /*
  205. * When our text changes, invalidate so we repaint.
  206. */
  207. //case WM_SETTEXT:
  208. //InvalidateRect(hwnd, 0, 0);
  209. //break;
  210. case PBM_SETPOS:
  211. Progress_OnSetPos(hwnd, wp);
  212. break;
  213. case PBM_DELTAPOS:
  214. lp = LOWORD(GetWindowLong(hwnd, GWL_CUR));
  215. Progress_OnSetPos(hwnd, wp + lp);
  216. break;
  217. case WM_ERASEBKGND:
  218. return 0;
  219. }
  220. return DefWindowProc(hwnd, wm, wp, lp);
  221. }
  222. /***************************************************************************
  223. *
  224. * @doc INTERNAL
  225. *
  226. * @func void | Progress_InitRegisterClass |
  227. *
  228. * Register our window classes.
  229. *
  230. ***************************************************************************/
  231. void Progress_InitRegisterClass(void)
  232. {
  233. WNDCLASS wc;
  234. /*
  235. * Progress control.
  236. */
  237. wc.style = 0;
  238. wc.lpfnWndProc = Progress_WndProc;
  239. wc.cbClsExtra = 0;
  240. wc.cbWndExtra = cbX(DWORD);
  241. wc.hInstance = g_App.hInstance;
  242. wc.hIcon = 0;
  243. wc.hCursor = LoadCursor(0, IDC_ARROW);
  244. wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
  245. wc.lpszMenuName = 0;
  246. wc.lpszClassName = TEXT("progress");
  247. RegisterClass(&wc);
  248. }