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.

317 lines
7.7 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
  38. Progress_GetRectPos(
  39. int cx,
  40. int iCur,
  41. int iMax
  42. )
  43. {
  44. int iRc;
  45. if (iCur != iMax) {
  46. iRc = MulDiv(cx, iCur, iMax);
  47. } else {
  48. iRc = cx;
  49. }
  50. return iRc;
  51. }
  52. /***************************************************************************
  53. *
  54. * @doc INTERNAL
  55. *
  56. * @func LRESULT | Progress_OnPaint |
  57. *
  58. * Draw the first part in the highlight colors.
  59. *
  60. * Draw the second part in the 3dface colors.
  61. *
  62. ***************************************************************************/
  63. void
  64. Progress_OnPaint(
  65. HWND hwnd
  66. )
  67. {
  68. HDC hdc;
  69. PAINTSTRUCT ps;
  70. HRESULT hr;
  71. hdc = BeginPaint(hwnd, &ps);
  72. if (hdc) {
  73. UINT taPrev;
  74. RECT rc;
  75. int cx;
  76. COLORREF clrTextPrev, clrBackPrev;
  77. int iCur, iMax, iPct;
  78. int ctch;
  79. HFONT hfPrev;
  80. TCHAR tsz[256];
  81. SIZE size;
  82. //
  83. // Set up the DC generically.
  84. //
  85. taPrev = SetTextAlign(hdc, TA_CENTER | TA_TOP);
  86. hfPrev = SelectFont(hdc, GetWindowFont(GetParent(hwnd)));
  87. //
  88. // Set up the colors for the left-hand side.
  89. //
  90. clrTextPrev = SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
  91. clrBackPrev = SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
  92. //
  93. // Now do some math.
  94. //
  95. GetClientRect(hwnd, &rc);
  96. cx = rc.right;
  97. iCur = LOWORD(GetWindowLong(hwnd, GWL_CUR));
  98. iMax = HIWORD(GetWindowLong(hwnd, GWL_CUR));
  99. if (iMax == 0) {
  100. iMax = 1; /* Avoid divide by zero */
  101. }
  102. if (iCur > 0) {
  103. iPct = (iCur * 100) / iMax;
  104. if (iPct < 1) {
  105. iPct = 1;
  106. }
  107. } else {
  108. iPct = 0;
  109. }
  110. rc.right = Progress_GetRectPos(cx, iCur, iMax);
  111. //
  112. // Update the percentage text in the progress bar.
  113. //
  114. hr = StringCchPrintf(tsz, cA(tsz), TEXT("%d%%"), iPct);
  115. if (FAILED(hr) && (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) {
  116. tsz[0] = TEXT('\0');
  117. }
  118. for(ctch=0;tsz[ctch];ctch++);
  119. //
  120. // Draw the left-hand side.
  121. //
  122. if (!GetTextExtentPoint32(hdc, tsz, ctch, &size)) {
  123. ExtTextOut( hdc, cx/2, 1,
  124. ETO_CLIPPED | ETO_OPAQUE,
  125. &rc, tsz, ctch, 0);
  126. } else {
  127. ExtTextOut( hdc, cx/2, (rc.bottom - rc.top - size.cy + 1) / 2,
  128. ETO_CLIPPED | ETO_OPAQUE,
  129. &rc, tsz, ctch, 0);
  130. }
  131. //
  132. // Now set up for the right-hand side.
  133. //
  134. SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
  135. SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
  136. rc.left = rc.right;
  137. rc.right = cx;
  138. //
  139. // Draw the right-hand side.
  140. //
  141. if (!GetTextExtentPoint32(hdc, tsz, ctch, &size)) {
  142. ExtTextOut( hdc, cx/2, 1,
  143. ETO_CLIPPED | ETO_OPAQUE,
  144. &rc, tsz, ctch, 0);
  145. } else {
  146. ExtTextOut( hdc, cx/2, (rc.bottom - rc.top - size.cy + 1) / 2,
  147. ETO_CLIPPED | ETO_OPAQUE,
  148. &rc, tsz, ctch, 0);
  149. }
  150. SetBkColor(hdc, clrBackPrev);
  151. SetTextColor(hdc, clrTextPrev);
  152. SelectFont(hdc, hfPrev);
  153. SetTextAlign(hdc, taPrev);
  154. EndPaint(hwnd, &ps);
  155. }
  156. }
  157. /***************************************************************************
  158. *
  159. * @doc INTERNAL
  160. *
  161. * @func LRESULT | Progress_OnSetPos |
  162. *
  163. * Update the state and invalidate the section that is affected.
  164. *
  165. ***************************************************************************/
  166. void
  167. Progress_OnSetPos(
  168. HWND hwnd,
  169. WPARAM wp
  170. )
  171. {
  172. int iCur, iMax;
  173. RECT rc;
  174. LONG lState = GetWindowLong(hwnd, GWL_CUR);
  175. GetClientRect(hwnd, &rc);
  176. iCur = LOWORD(GetWindowLong(hwnd, GWL_CUR));
  177. iMax = HIWORD(GetWindowLong(hwnd, GWL_CUR));
  178. if (iMax == 0) {
  179. iMax = 1; /* Avoid divide by zero */
  180. }
  181. rc.left = Progress_GetRectPos(rc.right, iCur, iMax);
  182. rc.right = Progress_GetRectPos(rc.right, (int)wp, iMax);
  183. InvalidateRect(hwnd, 0, 0);
  184. SetWindowLong(hwnd, GWL_CUR, MAKELONG(wp,HIWORD(lState)));
  185. }
  186. /***************************************************************************
  187. *
  188. * @doc INTERNAL
  189. *
  190. * @func LRESULT | Progress_WndProc |
  191. *
  192. * There really isn't much to do.
  193. *
  194. * The string is our window text (which Windows manages for us).
  195. *
  196. * The progress bar itself is kept in the high/low words of
  197. * our GWL_USERDATA.
  198. *
  199. * HIWORD(GetWindowLong(GWL_USERDATA)) = maximum
  200. * LOWORD(GetWindowLong(GWL_USERDATA)) = current value
  201. *
  202. ***************************************************************************/
  203. LRESULT CALLBACK
  204. Progress_WndProc(
  205. HWND hwnd,
  206. UINT wm,
  207. WPARAM wp,
  208. LPARAM lp
  209. )
  210. {
  211. switch (wm) {
  212. case WM_PAINT:
  213. Progress_OnPaint(hwnd);
  214. return 0;
  215. //
  216. // When the range resets, invalidate so we repaint.
  217. //
  218. // wp = new current pos
  219. // lp = new range
  220. //
  221. case PBM_SETRANGE:
  222. lp = HIWORD(lp);
  223. SetWindowLong(hwnd, GWL_CUR, MAKELONG(wp, lp));
  224. /* FALLTHROUGH */
  225. case PBM_SETPOS:
  226. Progress_OnSetPos(hwnd, wp);
  227. break;
  228. case PBM_DELTAPOS:
  229. lp = LOWORD(GetWindowLong(hwnd, GWL_CUR));
  230. Progress_OnSetPos(hwnd, wp + lp);
  231. break;
  232. case WM_ERASEBKGND:
  233. return 0;
  234. }
  235. return DefWindowProc(hwnd, wm, wp, lp);
  236. }
  237. /***************************************************************************
  238. *
  239. * @doc INTERNAL
  240. *
  241. * @func void | Progress_InitRegisterClass |
  242. *
  243. * Register our window classes.
  244. *
  245. ***************************************************************************/
  246. void
  247. Progress_InitRegisterClass(void)
  248. {
  249. WNDCLASS wc;
  250. //
  251. // Progress control.
  252. //
  253. wc.style = 0;
  254. wc.lpfnWndProc = Progress_WndProc;
  255. wc.cbClsExtra = 0;
  256. wc.cbWndExtra = cbX(DWORD);
  257. wc.hInstance = g_App.hInstance;
  258. wc.hIcon = 0;
  259. wc.hCursor = LoadCursor(0, IDC_ARROW);
  260. wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
  261. wc.lpszMenuName = 0;
  262. wc.lpszClassName = TEXT("progress");
  263. RegisterClass(&wc);
  264. }