4 * Copyright 1997 Dimitrie O. Paun
15 /* Control configuration constants */
21 #define UNKNOWN_PARAM(msg, wParam, lParam) WARN(progress, \
22 "Unknown parameter(s) for message " #msg \
23 "(%04x): wp=%04x lp=%08lx\n", msg, wParam, lParam);
25 #define PROGRESS_GetInfoPtr(wndPtr) ((PROGRESS_INFO *)wndPtr->wExtra[0])
28 /***********************************************************************
30 * Draws the progress bar.
33 PROGRESS_Draw (WND *wndPtr, HDC32 hdc)
35 PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(wndPtr);
36 HBRUSH32 hbrBar, hbrBk;
37 int rightBar, rightMost, ledWidth;
40 TRACE(progress, "refresh pos=%d min=%d, max=%d\n",
41 infoPtr->CurVal, infoPtr->MinVal, infoPtr->MaxVal);
43 /* get the required bar brush */
44 if (infoPtr->ColorBar == CLR_DEFAULT)
45 hbrBar = GetSysColorBrush32(COLOR_HIGHLIGHT);
47 hbrBar = CreateSolidBrush32 (infoPtr->ColorBar);
49 /* get the required background brush */
50 if (infoPtr->ColorBk == CLR_DEFAULT)
51 hbrBk = GetSysColorBrush32 (COLOR_3DFACE);
53 hbrBk = CreateSolidBrush32 (infoPtr->ColorBk);
55 /* get client rectangle */
56 GetClientRect32 (wndPtr->hwndSelf, &rect);
58 /* draw the background */
59 FillRect32(hdc, &rect, hbrBk);
61 rect.left++; rect.right--; rect.top++; rect.bottom--;
63 /* compute extent of progress bar */
64 if (wndPtr->dwStyle & PBS_VERTICAL)
66 rightBar = rect.bottom -
67 MulDiv32(infoPtr->CurVal-infoPtr->MinVal,
68 rect.bottom - rect.top,
69 infoPtr->MaxVal-infoPtr->MinVal);
70 ledWidth = MulDiv32 ((rect.right - rect.left), 2, 3);
75 rightBar = rect.left +
76 MulDiv32(infoPtr->CurVal-infoPtr->MinVal,
77 rect.right - rect.left,
78 infoPtr->MaxVal-infoPtr->MinVal);
79 ledWidth = MulDiv32 ((rect.bottom - rect.top), 2, 3);
80 rightMost = rect.right;
83 /* now draw the bar */
84 if (wndPtr->dwStyle & PBS_SMOOTH)
86 if (wndPtr->dwStyle & PBS_VERTICAL)
89 rect.right = rightBar;
90 FillRect32(hdc, &rect, hbrBar);
94 if (wndPtr->dwStyle & PBS_VERTICAL)
95 while(rect.bottom > rightBar) {
96 rect.top = rect.bottom-ledWidth;
97 if (rect.top < rightMost)
99 FillRect32(hdc, &rect, hbrBar);
100 rect.bottom = rect.top-LED_GAP;
103 while(rect.left < rightBar) {
104 rect.right = rect.left+ledWidth;
105 if (rect.right > rightMost)
106 rect.right = rightMost;
107 FillRect32(hdc, &rect, hbrBar);
108 rect.left = rect.right+LED_GAP;
112 /* delete bar brush */
113 if (infoPtr->ColorBar != CLR_DEFAULT)
114 DeleteObject32 (hbrBar);
116 /* delete background brush */
117 if (infoPtr->ColorBk != CLR_DEFAULT)
118 DeleteObject32 (hbrBk);
121 /***********************************************************************
123 * Draw the progress bar. The background need not be erased.
126 PROGRESS_Refresh (WND *wndPtr)
130 hdc = GetDC32 (wndPtr->hwndSelf);
131 PROGRESS_Draw (wndPtr, hdc);
132 ReleaseDC32 (wndPtr->hwndSelf, hdc);
135 /***********************************************************************
137 * Draw the progress bar. The background need not be erased.
138 * If dc!=0, it draws on it
141 PROGRESS_Paint (WND *wndPtr)
146 hdc = BeginPaint32 (wndPtr->hwndSelf, &ps);
147 PROGRESS_Draw (wndPtr, hdc);
148 EndPaint32 (wndPtr->hwndSelf, &ps);
152 /***********************************************************************
154 * Makes sure the current position (CUrVal) is within bounds.
156 static void PROGRESS_CoercePos(WND *wndPtr)
158 PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(wndPtr);
160 if(infoPtr->CurVal < infoPtr->MinVal)
161 infoPtr->CurVal = infoPtr->MinVal;
162 if(infoPtr->CurVal > infoPtr->MaxVal)
163 infoPtr->CurVal = infoPtr->MaxVal;
167 /***********************************************************************
169 * Set new Font for progress bar
172 PROGRESS_SetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
174 PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(wndPtr);
175 HFONT32 hOldFont = infoPtr->hFont;
177 infoPtr->hFont = (HFONT32)wParam;
179 PROGRESS_Refresh (wndPtr);
184 /***********************************************************************
187 LRESULT WINAPI ProgressWindowProc(HWND32 hwnd, UINT32 message,
188 WPARAM32 wParam, LPARAM lParam)
190 WND *wndPtr = WIN_FindWndPtr(hwnd);
191 PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(wndPtr);
197 wndPtr->dwExStyle |= WS_EX_STATICEDGE;
201 /* allocate memory for info struct */
203 (PROGRESS_INFO *)COMCTL32_Alloc (sizeof(PROGRESS_INFO));
204 wndPtr->wExtra[0] = (DWORD)infoPtr;
206 /* initialize the info struct */
211 infoPtr->ColorBar=CLR_DEFAULT;
212 infoPtr->ColorBk=CLR_DEFAULT;
213 infoPtr->hFont=(HANDLE32)NULL;
214 TRACE(progress, "Progress Ctrl creation, hwnd=%04x\n", hwnd);
218 TRACE (progress, "Progress Ctrl destruction, hwnd=%04x\n", hwnd);
219 COMCTL32_Free (infoPtr);
223 /* pretend to erase it here, but we will do it in the paint
224 function to avoid flicker */
228 return (LRESULT)infoPtr->hFont;
231 return PROGRESS_SetFont (wndPtr, wParam, lParam);
235 PROGRESS_Paint (wndPtr);
240 UNKNOWN_PARAM(PBM_DELTAPOS, wParam, lParam);
241 temp = infoPtr->CurVal;
243 infoPtr->CurVal += (UINT16)wParam;
244 PROGRESS_CoercePos(wndPtr);
245 PROGRESS_Refresh (wndPtr);
251 UNKNOWN_PARAM(PBM_SETPOS, wParam, lParam);
252 temp = infoPtr->CurVal;
254 infoPtr->CurVal = (UINT16)wParam;
255 PROGRESS_CoercePos(wndPtr);
256 PROGRESS_Refresh (wndPtr);
262 UNKNOWN_PARAM(PBM_SETRANGE, wParam, lParam);
263 temp = MAKELONG(infoPtr->MinVal, infoPtr->MaxVal);
265 infoPtr->MinVal = LOWORD(lParam);
266 infoPtr->MaxVal = HIWORD(lParam);
267 if(infoPtr->MaxVal <= infoPtr->MinVal)
268 infoPtr->MaxVal = infoPtr->MinVal+1;
269 PROGRESS_CoercePos(wndPtr);
270 PROGRESS_Refresh (wndPtr);
276 UNKNOWN_PARAM(PBM_SETSTEP, wParam, lParam);
277 temp = infoPtr->Step;
278 infoPtr->Step = (UINT16)wParam;
282 if (wParam || lParam)
283 UNKNOWN_PARAM(PBM_STEPIT, wParam, lParam);
284 temp = infoPtr->CurVal;
285 infoPtr->CurVal += infoPtr->Step;
286 if(infoPtr->CurVal > infoPtr->MaxVal)
287 infoPtr->CurVal = infoPtr->MinVal;
288 if(temp != infoPtr->CurVal)
289 PROGRESS_Refresh (wndPtr);
293 temp = MAKELONG(infoPtr->MinVal, infoPtr->MaxVal);
294 if((infoPtr->MinVal != (INT32)wParam) ||
295 (infoPtr->MaxVal != (INT32)lParam)) {
296 infoPtr->MinVal = (INT32)wParam;
297 infoPtr->MaxVal = (INT32)lParam;
298 if(infoPtr->MaxVal <= infoPtr->MinVal)
299 infoPtr->MaxVal = infoPtr->MinVal+1;
300 PROGRESS_CoercePos(wndPtr);
301 PROGRESS_Refresh (wndPtr);
307 ((PPBRANGE)lParam)->iLow = infoPtr->MinVal;
308 ((PPBRANGE)lParam)->iHigh = infoPtr->MaxVal;
310 return (wParam) ? infoPtr->MinVal : infoPtr->MaxVal;
313 if (wParam || lParam)
314 UNKNOWN_PARAM(PBM_STEPIT, wParam, lParam);
315 return (infoPtr->CurVal);
317 case PBM_SETBARCOLOR:
319 UNKNOWN_PARAM(PBM_SETBARCOLOR, wParam, lParam);
320 infoPtr->ColorBar = (COLORREF)lParam;
321 PROGRESS_Refresh (wndPtr);
326 UNKNOWN_PARAM(PBM_SETBKCOLOR, wParam, lParam);
327 infoPtr->ColorBk = (COLORREF)lParam;
328 PROGRESS_Refresh (wndPtr);
332 if (message >= WM_USER)
333 ERR(progress, "unknown msg %04x wp=%04x lp=%08lx\n",
334 message, wParam, lParam );
335 return DefWindowProc32A( hwnd, message, wParam, lParam );
342 /***********************************************************************
343 * PROGRESS_Register [Internal]
345 * Registers the progress bar window class.
349 PROGRESS_Register (VOID)
351 WNDCLASS32A wndClass;
353 if (GlobalFindAtom32A (PROGRESS_CLASS32A)) return;
355 ZeroMemory (&wndClass, sizeof( WNDCLASS32A));
356 wndClass.style = CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW;
357 wndClass.lpfnWndProc = (WNDPROC32)ProgressWindowProc;
358 wndClass.cbClsExtra = 0;
359 wndClass.cbWndExtra = sizeof (PROGRESS_INFO *);
360 wndClass.hCursor = LoadCursor32A (0, IDC_ARROW32A);
361 wndClass.lpszClassName = PROGRESS_CLASS32A;
363 RegisterClass32A (&wndClass);
367 /***********************************************************************
368 * PROGRESS_Unregister [Internal]
370 * Unregisters the progress bar window class.
374 PROGRESS_Unregister (VOID)
376 if (GlobalFindAtom32A (PROGRESS_CLASS32A))
377 UnregisterClass32A (PROGRESS_CLASS32A, (HINSTANCE32)NULL);