4 * Copyright 1997 Dimitrie O. Paun
14 /* Control configuration constants */
20 #define UNKNOWN_PARAM(msg, wParam, lParam) WARN(progress, \
21 "Unknown parameter(s) for message " #msg \
22 "(%04x): wp=%04x lp=%08lx\n", msg, wParam, lParam);
24 #define PROGRESS_GetInfoPtr(wndPtr) ((PROGRESS_INFO *)wndPtr->wExtra[0])
27 /***********************************************************************
29 * Draws the progress bar.
32 PROGRESS_Draw (WND *wndPtr, HDC32 hdc)
34 PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(wndPtr);
35 HBRUSH32 hbrBar, hbrBk;
36 int rightBar, rightMost, ledWidth;
39 TRACE(progress, "refresh pos=%d min=%d, max=%d\n",
40 infoPtr->CurVal, infoPtr->MinVal, infoPtr->MaxVal);
42 /* get the required bar brush */
43 if (infoPtr->ColorBar == CLR_DEFAULT)
44 hbrBar = GetSysColorBrush32(COLOR_HIGHLIGHT);
46 hbrBar = CreateSolidBrush32 (infoPtr->ColorBar);
48 /* get the required background brush */
49 if (infoPtr->ColorBk == CLR_DEFAULT)
50 hbrBk = GetSysColorBrush32 (COLOR_3DFACE);
52 hbrBk = CreateSolidBrush32 (infoPtr->ColorBk);
54 /* get client rectangle */
55 GetClientRect32 (wndPtr->hwndSelf, &rect);
57 /* draw the background */
58 FillRect32(hdc, &rect, hbrBk);
60 rect.left++; rect.right--; rect.top++; rect.bottom--;
62 /* compute extent of progress bar */
63 if (wndPtr->dwStyle & PBS_VERTICAL)
65 rightBar = rect.bottom -
66 MulDiv32(infoPtr->CurVal-infoPtr->MinVal,
67 rect.bottom - rect.top,
68 infoPtr->MaxVal-infoPtr->MinVal);
69 ledWidth = MulDiv32 ((rect.right - rect.left), 2, 3);
74 rightBar = rect.left +
75 MulDiv32(infoPtr->CurVal-infoPtr->MinVal,
76 rect.right - rect.left,
77 infoPtr->MaxVal-infoPtr->MinVal);
78 ledWidth = MulDiv32 ((rect.bottom - rect.top), 2, 3);
79 rightMost = rect.right;
82 /* now draw the bar */
83 if (wndPtr->dwStyle & PBS_SMOOTH)
85 if (wndPtr->dwStyle & PBS_VERTICAL)
88 rect.right = rightBar;
89 FillRect32(hdc, &rect, hbrBar);
93 if (wndPtr->dwStyle & PBS_VERTICAL)
94 while(rect.bottom > rightBar) {
95 rect.top = rect.bottom-ledWidth;
96 if (rect.top < rightMost)
98 FillRect32(hdc, &rect, hbrBar);
99 rect.bottom = rect.top-LED_GAP;
102 while(rect.left < rightBar) {
103 rect.right = rect.left+ledWidth;
104 if (rect.right > rightMost)
105 rect.right = rightMost;
106 FillRect32(hdc, &rect, hbrBar);
107 rect.left = rect.right+LED_GAP;
111 /* delete bar brush */
112 if (infoPtr->ColorBar != CLR_DEFAULT)
113 DeleteObject32 (hbrBar);
115 /* delete background brush */
116 if (infoPtr->ColorBk != CLR_DEFAULT)
117 DeleteObject32 (hbrBk);
120 /***********************************************************************
122 * Draw the progress bar. The background need not be erased.
125 PROGRESS_Refresh (WND *wndPtr)
129 hdc = GetDC32 (wndPtr->hwndSelf);
130 PROGRESS_Draw (wndPtr, hdc);
131 ReleaseDC32 (wndPtr->hwndSelf, hdc);
134 /***********************************************************************
136 * Draw the progress bar. The background need not be erased.
137 * If dc!=0, it draws on it
140 PROGRESS_Paint (WND *wndPtr)
145 hdc = BeginPaint32 (wndPtr->hwndSelf, &ps);
146 PROGRESS_Draw (wndPtr, hdc);
147 EndPaint32 (wndPtr->hwndSelf, &ps);
151 /***********************************************************************
153 * Makes sure the current position (CUrVal) is within bounds.
155 static void PROGRESS_CoercePos(WND *wndPtr)
157 PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(wndPtr);
159 if(infoPtr->CurVal < infoPtr->MinVal)
160 infoPtr->CurVal = infoPtr->MinVal;
161 if(infoPtr->CurVal > infoPtr->MaxVal)
162 infoPtr->CurVal = infoPtr->MaxVal;
166 /***********************************************************************
168 * Set new Font for progress bar
171 PROGRESS_SetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
173 PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(wndPtr);
174 HFONT32 hOldFont = infoPtr->hFont;
176 infoPtr->hFont = (HFONT32)wParam;
178 PROGRESS_Refresh (wndPtr);
183 /***********************************************************************
186 LRESULT WINAPI ProgressWindowProc(HWND32 hwnd, UINT32 message,
187 WPARAM32 wParam, LPARAM lParam)
189 WND *wndPtr = WIN_FindWndPtr(hwnd);
190 PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(wndPtr);
196 wndPtr->dwExStyle |= WS_EX_STATICEDGE;
200 /* allocate memory for info struct */
202 (PROGRESS_INFO *)COMCTL32_Alloc (sizeof(PROGRESS_INFO));
203 wndPtr->wExtra[0] = (DWORD)infoPtr;
205 /* initialize the info struct */
210 infoPtr->ColorBar=CLR_DEFAULT;
211 infoPtr->ColorBk=CLR_DEFAULT;
212 infoPtr->hFont=(HANDLE32)NULL;
213 TRACE(progress, "Progress Ctrl creation, hwnd=%04x\n", hwnd);
217 TRACE (progress, "Progress Ctrl destruction, hwnd=%04x\n", hwnd);
218 COMCTL32_Free (infoPtr);
222 /* pretend to erase it here, but we will do it in the paint
223 function to avoid flicker */
227 return (LRESULT)infoPtr->hFont;
230 return PROGRESS_SetFont (wndPtr, wParam, lParam);
234 PROGRESS_Paint (wndPtr);
239 UNKNOWN_PARAM(PBM_DELTAPOS, wParam, lParam);
240 temp = infoPtr->CurVal;
242 infoPtr->CurVal += (UINT16)wParam;
243 PROGRESS_CoercePos(wndPtr);
244 PROGRESS_Refresh (wndPtr);
250 UNKNOWN_PARAM(PBM_SETPOS, wParam, lParam);
251 temp = infoPtr->CurVal;
253 infoPtr->CurVal = (UINT16)wParam;
254 PROGRESS_CoercePos(wndPtr);
255 PROGRESS_Refresh (wndPtr);
261 UNKNOWN_PARAM(PBM_SETRANGE, wParam, lParam);
262 temp = MAKELONG(infoPtr->MinVal, infoPtr->MaxVal);
264 infoPtr->MinVal = LOWORD(lParam);
265 infoPtr->MaxVal = HIWORD(lParam);
266 if(infoPtr->MaxVal <= infoPtr->MinVal)
267 infoPtr->MaxVal = infoPtr->MinVal+1;
268 PROGRESS_CoercePos(wndPtr);
269 PROGRESS_Refresh (wndPtr);
275 UNKNOWN_PARAM(PBM_SETSTEP, wParam, lParam);
276 temp = infoPtr->Step;
277 infoPtr->Step = (UINT16)wParam;
281 if (wParam || lParam)
282 UNKNOWN_PARAM(PBM_STEPIT, wParam, lParam);
283 temp = infoPtr->CurVal;
284 infoPtr->CurVal += infoPtr->Step;
285 if(infoPtr->CurVal > infoPtr->MaxVal)
286 infoPtr->CurVal = infoPtr->MinVal;
287 if(temp != infoPtr->CurVal)
288 PROGRESS_Refresh (wndPtr);
292 temp = MAKELONG(infoPtr->MinVal, infoPtr->MaxVal);
293 if((infoPtr->MinVal != (INT32)wParam) ||
294 (infoPtr->MaxVal != (INT32)lParam)) {
295 infoPtr->MinVal = (INT32)wParam;
296 infoPtr->MaxVal = (INT32)lParam;
297 if(infoPtr->MaxVal <= infoPtr->MinVal)
298 infoPtr->MaxVal = infoPtr->MinVal+1;
299 PROGRESS_CoercePos(wndPtr);
300 PROGRESS_Refresh (wndPtr);
306 ((PPBRANGE)lParam)->iLow = infoPtr->MinVal;
307 ((PPBRANGE)lParam)->iHigh = infoPtr->MaxVal;
309 return (wParam) ? infoPtr->MinVal : infoPtr->MaxVal;
312 if (wParam || lParam)
313 UNKNOWN_PARAM(PBM_STEPIT, wParam, lParam);
314 return (infoPtr->CurVal);
316 case PBM_SETBARCOLOR:
318 UNKNOWN_PARAM(PBM_SETBARCOLOR, wParam, lParam);
319 infoPtr->ColorBar = (COLORREF)lParam;
320 PROGRESS_Refresh (wndPtr);
325 UNKNOWN_PARAM(PBM_SETBKCOLOR, wParam, lParam);
326 infoPtr->ColorBk = (COLORREF)lParam;
327 PROGRESS_Refresh (wndPtr);
331 if (message >= WM_USER)
332 ERR(progress, "unknown msg %04x wp=%04x lp=%08lx\n",
333 message, wParam, lParam );
334 return DefWindowProc32A( hwnd, message, wParam, lParam );
341 /***********************************************************************
342 * PROGRESS_Register [Internal]
344 * Registers the progress bar window class.
348 PROGRESS_Register (VOID)
350 WNDCLASS32A wndClass;
352 if (GlobalFindAtom32A (PROGRESS_CLASS32A)) return;
354 ZeroMemory (&wndClass, sizeof( WNDCLASS32A));
355 wndClass.style = CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW;
356 wndClass.lpfnWndProc = (WNDPROC32)ProgressWindowProc;
357 wndClass.cbClsExtra = 0;
358 wndClass.cbWndExtra = sizeof (PROGRESS_INFO *);
359 wndClass.hCursor = LoadCursor32A (0, IDC_ARROW32A);
360 wndClass.lpszClassName = PROGRESS_CLASS32A;
362 RegisterClass32A (&wndClass);
366 /***********************************************************************
367 * PROGRESS_Unregister [Internal]
369 * Unregisters the progress bar window class.
373 PROGRESS_Unregister (VOID)
375 if (GlobalFindAtom32A (PROGRESS_CLASS32A))
376 UnregisterClass32A (PROGRESS_CLASS32A, (HINSTANCE32)NULL);