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
);