4 * Copyright 1997 Dimitrie O. Paun
7 * - I do not know what to to on WM_[SG]ET_FONT
17 /* Control configuration constants */
23 #define UNKNOWN_PARAM(msg, wParam, lParam) WARN(progress, \
24 "Unknown parameter(s) for message " #msg \
25 "(%04x): wp=%04x lp=%08lx\n", msg, wParam, lParam);
27 #define PROGRESS_GetInfoPtr(wndPtr) ((PROGRESS_INFO *)wndPtr->wExtra[0])
30 /***********************************************************************
32 * Draws the progress bar.
35 PROGRESS_Draw (WND
*wndPtr
, HDC32 hdc
)
37 PROGRESS_INFO
*infoPtr
= PROGRESS_GetInfoPtr(wndPtr
);
38 HBRUSH32 hbrBar
, hbrBk
;
39 int rightBar
, rightMost
, ledWidth
;
42 TRACE(progress
, "refresh pos=%d min=%d, max=%d\n",
43 infoPtr
->CurVal
, infoPtr
->MinVal
, infoPtr
->MaxVal
);
45 /* get the required bar brush */
46 if (infoPtr
->ColorBar
== CLR_DEFAULT
)
47 hbrBar
= GetSysColorBrush32(COLOR_HIGHLIGHT
);
49 hbrBar
= CreateSolidBrush32 (infoPtr
->ColorBar
);
51 /* get the required background brush */
52 if (infoPtr
->ColorBk
== CLR_DEFAULT
)
53 hbrBk
= GetSysColorBrush32 (COLOR_3DFACE
);
55 hbrBk
= CreateSolidBrush32 (infoPtr
->ColorBk
);
57 /* get client rectangle */
58 GetClientRect32 (wndPtr
->hwndSelf
, &rect
);
60 /* draw the background */
61 FillRect32(hdc
, &rect
, hbrBk
);
63 rect
.left
++; rect
.right
--; rect
.top
++; rect
.bottom
--;
65 /* compute extent of progress bar */
66 if (wndPtr
->dwStyle
& PBS_VERTICAL
)
68 rightBar
= rect
.bottom
-
69 MulDiv32(infoPtr
->CurVal
-infoPtr
->MinVal
,
70 rect
.bottom
- rect
.top
,
71 infoPtr
->MaxVal
-infoPtr
->MinVal
);
72 ledWidth
= MulDiv32 ((rect
.right
- rect
.left
), 2, 3);
77 rightBar
= rect
.left
+
78 MulDiv32(infoPtr
->CurVal
-infoPtr
->MinVal
,
79 rect
.right
- rect
.left
,
80 infoPtr
->MaxVal
-infoPtr
->MinVal
);
81 ledWidth
= MulDiv32 ((rect
.bottom
- rect
.top
), 2, 3);
82 rightMost
= rect
.right
;
85 /* now draw the bar */
86 if (wndPtr
->dwStyle
& PBS_SMOOTH
)
88 if (wndPtr
->dwStyle
& PBS_VERTICAL
)
91 rect
.right
= rightBar
;
92 FillRect32(hdc
, &rect
, hbrBar
);
96 if (wndPtr
->dwStyle
& PBS_VERTICAL
)
97 while(rect
.bottom
> rightBar
) {
98 rect
.top
= rect
.bottom
-ledWidth
;
99 if (rect
.top
< rightMost
)
100 rect
.top
= rightMost
;
101 FillRect32(hdc
, &rect
, hbrBar
);
102 rect
.bottom
= rect
.top
-LED_GAP
;
105 while(rect
.left
< rightBar
) {
106 rect
.right
= rect
.left
+ledWidth
;
107 if (rect
.right
> rightMost
)
108 rect
.right
= rightMost
;
109 FillRect32(hdc
, &rect
, hbrBar
);
110 rect
.left
= rect
.right
+LED_GAP
;
114 /* delete bar brush */
115 if (infoPtr
->ColorBar
!= CLR_DEFAULT
)
116 DeleteObject32 (hbrBar
);
118 /* delete background brush */
119 if (infoPtr
->ColorBk
!= CLR_DEFAULT
)
120 DeleteObject32 (hbrBk
);
123 /***********************************************************************
125 * Draw the progress bar. The background need not be erased.
128 PROGRESS_Refresh (WND
*wndPtr
)
132 hdc
= GetDC32 (wndPtr
->hwndSelf
);
133 PROGRESS_Draw (wndPtr
, hdc
);
134 ReleaseDC32 (wndPtr
->hwndSelf
, hdc
);
137 /***********************************************************************
139 * Draw the progress bar. The background need not be erased.
140 * If dc!=0, it draws on it
143 PROGRESS_Paint (WND
*wndPtr
)
148 hdc
= BeginPaint32 (wndPtr
->hwndSelf
, &ps
);
149 PROGRESS_Draw (wndPtr
, hdc
);
150 EndPaint32 (wndPtr
->hwndSelf
, &ps
);
154 /***********************************************************************
156 * Makes sure the current position (CUrVal) is within bounds.
158 static void PROGRESS_CoercePos(WND
*wndPtr
)
160 PROGRESS_INFO
*infoPtr
= PROGRESS_GetInfoPtr(wndPtr
);
162 if(infoPtr
->CurVal
< infoPtr
->MinVal
)
163 infoPtr
->CurVal
= infoPtr
->MinVal
;
164 if(infoPtr
->CurVal
> infoPtr
->MaxVal
)
165 infoPtr
->CurVal
= infoPtr
->MaxVal
;
168 /***********************************************************************
171 LRESULT WINAPI
ProgressWindowProc(HWND32 hwnd
, UINT32 message
,
172 WPARAM32 wParam
, LPARAM lParam
)
174 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
175 PROGRESS_INFO
*infoPtr
= PROGRESS_GetInfoPtr(wndPtr
);
181 wndPtr
->dwExStyle
|= WS_EX_STATICEDGE
;
185 /* allocate memory for info struct */
187 (PROGRESS_INFO
*)COMCTL32_Alloc (sizeof(PROGRESS_INFO
));
188 wndPtr
->wExtra
[0] = (DWORD
)infoPtr
;
190 /* initialize the info struct */
195 infoPtr
->ColorBar
=CLR_DEFAULT
;
196 infoPtr
->ColorBk
=CLR_DEFAULT
;
197 TRACE(progress
, "Progress Ctrl creation, hwnd=%04x\n", hwnd
);
201 TRACE (progress
, "Progress Ctrl destruction, hwnd=%04x\n", hwnd
);
202 COMCTL32_Free (infoPtr
);
206 /* pretend to erase it here, but we will do it in the paint
207 function to avoid flicker */
211 FIXME (progress
, "WM_GETFONT - empty message!\n");
212 /* FIXME: What do we need to do? */
216 FIXME (progress
, "WM_SETFONT - empty message!\n");
217 /* FIXME: What do we need to do? */
221 PROGRESS_Paint (wndPtr
);
226 UNKNOWN_PARAM(PBM_DELTAPOS
, wParam
, lParam
);
227 temp
= infoPtr
->CurVal
;
229 infoPtr
->CurVal
+= (UINT16
)wParam
;
230 PROGRESS_CoercePos(wndPtr
);
231 PROGRESS_Refresh (wndPtr
);
237 UNKNOWN_PARAM(PBM_SETPOS
, wParam
, lParam
);
238 temp
= infoPtr
->CurVal
;
240 infoPtr
->CurVal
= (UINT16
)wParam
;
241 PROGRESS_CoercePos(wndPtr
);
242 PROGRESS_Refresh (wndPtr
);
248 UNKNOWN_PARAM(PBM_SETRANGE
, wParam
, lParam
);
249 temp
= MAKELONG(infoPtr
->MinVal
, infoPtr
->MaxVal
);
251 infoPtr
->MinVal
= LOWORD(lParam
);
252 infoPtr
->MaxVal
= HIWORD(lParam
);
253 if(infoPtr
->MaxVal
<= infoPtr
->MinVal
)
254 infoPtr
->MaxVal
= infoPtr
->MinVal
+1;
255 PROGRESS_CoercePos(wndPtr
);
256 PROGRESS_Refresh (wndPtr
);
262 UNKNOWN_PARAM(PBM_SETSTEP
, wParam
, lParam
);
263 temp
= infoPtr
->Step
;
264 infoPtr
->Step
= (UINT16
)wParam
;
268 if (wParam
|| lParam
)
269 UNKNOWN_PARAM(PBM_STEPIT
, wParam
, lParam
);
270 temp
= infoPtr
->CurVal
;
271 infoPtr
->CurVal
+= infoPtr
->Step
;
272 if(infoPtr
->CurVal
> infoPtr
->MaxVal
)
273 infoPtr
->CurVal
= infoPtr
->MinVal
;
274 if(temp
!= infoPtr
->CurVal
)
275 PROGRESS_Refresh (wndPtr
);
279 temp
= MAKELONG(infoPtr
->MinVal
, infoPtr
->MaxVal
);
280 if((infoPtr
->MinVal
!= (INT32
)wParam
) ||
281 (infoPtr
->MaxVal
!= (INT32
)lParam
)) {
282 infoPtr
->MinVal
= (INT32
)wParam
;
283 infoPtr
->MaxVal
= (INT32
)lParam
;
284 if(infoPtr
->MaxVal
<= infoPtr
->MinVal
)
285 infoPtr
->MaxVal
= infoPtr
->MinVal
+1;
286 PROGRESS_CoercePos(wndPtr
);
287 PROGRESS_Refresh (wndPtr
);
293 ((PPBRANGE
)lParam
)->iLow
= infoPtr
->MinVal
;
294 ((PPBRANGE
)lParam
)->iHigh
= infoPtr
->MaxVal
;
296 return (wParam
) ? infoPtr
->MinVal
: infoPtr
->MaxVal
;
299 if (wParam
|| lParam
)
300 UNKNOWN_PARAM(PBM_STEPIT
, wParam
, lParam
);
301 return (infoPtr
->CurVal
);
303 case PBM_SETBARCOLOR
:
305 UNKNOWN_PARAM(PBM_SETBARCOLOR
, wParam
, lParam
);
306 infoPtr
->ColorBar
= (COLORREF
)lParam
;
307 PROGRESS_Refresh (wndPtr
);
312 UNKNOWN_PARAM(PBM_SETBKCOLOR
, wParam
, lParam
);
313 infoPtr
->ColorBk
= (COLORREF
)lParam
;
314 PROGRESS_Refresh (wndPtr
);
318 if (message
>= WM_USER
)
319 ERR(progress
, "unknown msg %04x wp=%04x lp=%08lx\n",
320 message
, wParam
, lParam
);
321 return DefWindowProc32A( hwnd
, message
, wParam
, lParam
);
328 /***********************************************************************
329 * PROGRESS_Register [Internal]
331 * Registers the progress bar window class.
335 PROGRESS_Register (VOID
)
337 WNDCLASS32A wndClass
;
339 if (GlobalFindAtom32A (PROGRESS_CLASS32A
)) return;
341 ZeroMemory (&wndClass
, sizeof( WNDCLASS32A
));
342 wndClass
.style
= CS_GLOBALCLASS
| CS_VREDRAW
| CS_HREDRAW
;
343 wndClass
.lpfnWndProc
= (WNDPROC32
)ProgressWindowProc
;
344 wndClass
.cbClsExtra
= 0;
345 wndClass
.cbWndExtra
= sizeof (PROGRESS_INFO
*);
346 wndClass
.hCursor
= LoadCursor32A (0, IDC_ARROW32A
);
347 wndClass
.lpszClassName
= PROGRESS_CLASS32A
;
349 RegisterClass32A (&wndClass
);
353 /***********************************************************************
354 * PROGRESS_Unregister [Internal]
356 * Unregisters the progress bar window class.
360 PROGRESS_Unregister (VOID
)
362 if (GlobalFindAtom32A (PROGRESS_CLASS32A
))
363 UnregisterClass32A (PROGRESS_CLASS32A
, (HINSTANCE32
)NULL
);