4 * Copyright 1997 Dimitrie O. Paun
7 * - I do not know what to to on WM_[SG]ET_FONT
18 /* Control configuration constants */
24 #define UNKNOWN_PARAM(msg, wParam, lParam) WARN(progress, \
25 "Unknown parameter(s) for message " #msg \
26 "(%04x): wp=%04x lp=%08lx\n", msg, wParam, lParam);
28 #define PROGRESS_GetInfoPtr(wndPtr) ((PROGRESS_INFO *)wndPtr->wExtra[0])
31 /***********************************************************************
33 * Draws the progress bar.
36 PROGRESS_Draw (WND
*wndPtr
, HDC32 hdc
)
38 PROGRESS_INFO
*infoPtr
= PROGRESS_GetInfoPtr(wndPtr
);
39 HBRUSH32 hbrBar
, hbrBk
;
40 int rightBar
, rightMost
, ledWidth
;
43 TRACE(progress
, "refresh pos=%d min=%d, max=%d\n",
44 infoPtr
->CurVal
, infoPtr
->MinVal
, infoPtr
->MaxVal
);
46 /* get the required bar brush */
47 if (infoPtr
->ColorBar
== CLR_DEFAULT
)
48 hbrBar
= GetSysColorBrush32(COLOR_HIGHLIGHT
);
50 hbrBar
= CreateSolidBrush32 (infoPtr
->ColorBar
);
52 /* get the required background brush */
53 if (infoPtr
->ColorBk
== CLR_DEFAULT
)
54 hbrBk
= GetSysColorBrush32 (COLOR_3DFACE
);
56 hbrBk
= CreateSolidBrush32 (infoPtr
->ColorBk
);
58 /* get client rectangle */
59 GetClientRect32 (wndPtr
->hwndSelf
, &rect
);
61 /* draw the background */
62 FillRect32(hdc
, &rect
, hbrBk
);
64 rect
.left
++; rect
.right
--; rect
.top
++; rect
.bottom
--;
66 /* compute extent of progress bar */
67 if (wndPtr
->dwStyle
& PBS_VERTICAL
)
69 rightBar
= rect
.bottom
-
70 MulDiv32(infoPtr
->CurVal
-infoPtr
->MinVal
,
71 rect
.bottom
- rect
.top
,
72 infoPtr
->MaxVal
-infoPtr
->MinVal
);
73 ledWidth
= MulDiv32 ((rect
.right
- rect
.left
), 2, 3);
78 rightBar
= rect
.left
+
79 MulDiv32(infoPtr
->CurVal
-infoPtr
->MinVal
,
80 rect
.right
- rect
.left
,
81 infoPtr
->MaxVal
-infoPtr
->MinVal
);
82 ledWidth
= MulDiv32 ((rect
.bottom
- rect
.top
), 2, 3);
83 rightMost
= rect
.right
;
86 /* now draw the bar */
87 if (wndPtr
->dwStyle
& PBS_SMOOTH
)
89 if (wndPtr
->dwStyle
& PBS_VERTICAL
)
92 rect
.right
= rightBar
;
93 FillRect32(hdc
, &rect
, hbrBar
);
97 if (wndPtr
->dwStyle
& PBS_VERTICAL
)
98 while(rect
.bottom
> rightBar
) {
99 rect
.top
= rect
.bottom
-ledWidth
;
100 if (rect
.top
< rightMost
)
101 rect
.top
= rightMost
;
102 FillRect32(hdc
, &rect
, hbrBar
);
103 rect
.bottom
= rect
.top
-LED_GAP
;
106 while(rect
.left
< rightBar
) {
107 rect
.right
= rect
.left
+ledWidth
;
108 if (rect
.right
> rightMost
)
109 rect
.right
= rightMost
;
110 FillRect32(hdc
, &rect
, hbrBar
);
111 rect
.left
= rect
.right
+LED_GAP
;
115 /* delete bar brush */
116 if (infoPtr
->ColorBar
!= CLR_DEFAULT
)
117 DeleteObject32 (hbrBar
);
119 /* delete background brush */
120 if (infoPtr
->ColorBk
!= CLR_DEFAULT
)
121 DeleteObject32 (hbrBk
);
124 /***********************************************************************
126 * Draw the progress bar. The background need not be erased.
129 PROGRESS_Refresh (WND
*wndPtr
)
133 hdc
= GetDC32 (wndPtr
->hwndSelf
);
134 PROGRESS_Draw (wndPtr
, hdc
);
135 ReleaseDC32 (wndPtr
->hwndSelf
, hdc
);
138 /***********************************************************************
140 * Draw the progress bar. The background need not be erased.
141 * If dc!=0, it draws on it
144 PROGRESS_Paint (WND
*wndPtr
)
149 hdc
= BeginPaint32 (wndPtr
->hwndSelf
, &ps
);
150 PROGRESS_Draw (wndPtr
, hdc
);
151 EndPaint32 (wndPtr
->hwndSelf
, &ps
);
155 /***********************************************************************
157 * Makes sure the current position (CUrVal) is within bounds.
159 static void PROGRESS_CoercePos(WND
*wndPtr
)
161 PROGRESS_INFO
*infoPtr
= PROGRESS_GetInfoPtr(wndPtr
);
163 if(infoPtr
->CurVal
< infoPtr
->MinVal
)
164 infoPtr
->CurVal
= infoPtr
->MinVal
;
165 if(infoPtr
->CurVal
> infoPtr
->MaxVal
)
166 infoPtr
->CurVal
= infoPtr
->MaxVal
;
169 /***********************************************************************
172 LRESULT WINAPI
ProgressWindowProc(HWND32 hwnd
, UINT32 message
,
173 WPARAM32 wParam
, LPARAM lParam
)
175 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
176 PROGRESS_INFO
*infoPtr
= PROGRESS_GetInfoPtr(wndPtr
);
182 wndPtr
->dwExStyle
|= WS_EX_STATICEDGE
;
186 /* allocate memory for info struct */
188 (PROGRESS_INFO
*)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
,
189 sizeof(PROGRESS_INFO
));
190 wndPtr
->wExtra
[0] = (DWORD
)infoPtr
;
192 /* initialize the info struct */
197 infoPtr
->ColorBar
=CLR_DEFAULT
;
198 infoPtr
->ColorBk
=CLR_DEFAULT
;
199 TRACE(progress
, "Progress Ctrl creation, hwnd=%04x\n", hwnd
);
203 TRACE(progress
, "Progress Ctrl destruction, hwnd=%04x\n", hwnd
);
204 HeapFree (GetProcessHeap (), 0, infoPtr
);
208 /* pretend to erase it here, but we will do it in the paint
209 function to avoid flicker */
213 FIXME (progress
, "WM_GETFONT - empty message!\n");
214 /* FIXME: What do we need to do? */
218 FIXME (progress
, "WM_SETFONT - empty message!\n");
219 /* FIXME: What do we need to do? */
223 PROGRESS_Paint (wndPtr
);
228 UNKNOWN_PARAM(PBM_DELTAPOS
, wParam
, lParam
);
229 temp
= infoPtr
->CurVal
;
231 infoPtr
->CurVal
+= (UINT16
)wParam
;
232 PROGRESS_CoercePos(wndPtr
);
233 PROGRESS_Refresh (wndPtr
);
239 UNKNOWN_PARAM(PBM_SETPOS
, wParam
, lParam
);
240 temp
= infoPtr
->CurVal
;
242 infoPtr
->CurVal
= (UINT16
)wParam
;
243 PROGRESS_CoercePos(wndPtr
);
244 PROGRESS_Refresh (wndPtr
);
250 UNKNOWN_PARAM(PBM_SETRANGE
, wParam
, lParam
);
251 temp
= MAKELONG(infoPtr
->MinVal
, infoPtr
->MaxVal
);
253 infoPtr
->MinVal
= LOWORD(lParam
);
254 infoPtr
->MaxVal
= HIWORD(lParam
);
255 if(infoPtr
->MaxVal
<= infoPtr
->MinVal
)
256 infoPtr
->MaxVal
= infoPtr
->MinVal
+1;
257 PROGRESS_CoercePos(wndPtr
);
258 PROGRESS_Refresh (wndPtr
);
264 UNKNOWN_PARAM(PBM_SETSTEP
, wParam
, lParam
);
265 temp
= infoPtr
->Step
;
266 infoPtr
->Step
= (UINT16
)wParam
;
270 if (wParam
|| lParam
)
271 UNKNOWN_PARAM(PBM_STEPIT
, wParam
, lParam
);
272 temp
= infoPtr
->CurVal
;
273 infoPtr
->CurVal
+= infoPtr
->Step
;
274 if(infoPtr
->CurVal
> infoPtr
->MaxVal
)
275 infoPtr
->CurVal
= infoPtr
->MinVal
;
276 if(temp
!= infoPtr
->CurVal
)
277 PROGRESS_Refresh (wndPtr
);
281 temp
= MAKELONG(infoPtr
->MinVal
, infoPtr
->MaxVal
);
282 if((infoPtr
->MinVal
!= (INT32
)wParam
) ||
283 (infoPtr
->MaxVal
!= (INT32
)lParam
)) {
284 infoPtr
->MinVal
= (INT32
)wParam
;
285 infoPtr
->MaxVal
= (INT32
)lParam
;
286 if(infoPtr
->MaxVal
<= infoPtr
->MinVal
)
287 infoPtr
->MaxVal
= infoPtr
->MinVal
+1;
288 PROGRESS_CoercePos(wndPtr
);
289 PROGRESS_Refresh (wndPtr
);
295 ((PPBRANGE
)lParam
)->iLow
= infoPtr
->MinVal
;
296 ((PPBRANGE
)lParam
)->iHigh
= infoPtr
->MaxVal
;
298 return (wParam
) ? infoPtr
->MinVal
: infoPtr
->MaxVal
;
301 if (wParam
|| lParam
)
302 UNKNOWN_PARAM(PBM_STEPIT
, wParam
, lParam
);
303 return (infoPtr
->CurVal
);
305 case PBM_SETBARCOLOR
:
307 UNKNOWN_PARAM(PBM_SETBARCOLOR
, wParam
, lParam
);
308 infoPtr
->ColorBar
= (COLORREF
)lParam
;
309 PROGRESS_Refresh (wndPtr
);
314 UNKNOWN_PARAM(PBM_SETBKCOLOR
, wParam
, lParam
);
315 infoPtr
->ColorBk
= (COLORREF
)lParam
;
316 PROGRESS_Refresh (wndPtr
);
320 if (message
>= WM_USER
)
321 ERR(progress
, "unknown msg %04x wp=%04x lp=%08lx\n",
322 message
, wParam
, lParam
);
323 return DefWindowProc32A( hwnd
, message
, wParam
, lParam
);
330 /***********************************************************************
331 * PROGRESS_Register [Internal]
333 * Registers the progress bar window class.
337 PROGRESS_Register(void)
339 WNDCLASS32A wndClass
;
341 if( GlobalFindAtom32A( PROGRESS_CLASS32A
) ) return;
343 ZeroMemory( &wndClass
, sizeof( WNDCLASS32A
) );
344 wndClass
.style
= CS_GLOBALCLASS
| CS_VREDRAW
| CS_HREDRAW
;
345 wndClass
.lpfnWndProc
= (WNDPROC32
)ProgressWindowProc
;
346 wndClass
.cbClsExtra
= 0;
347 wndClass
.cbWndExtra
= sizeof(PROGRESS_INFO
*);
348 wndClass
.hCursor
= LoadCursor32A( 0, IDC_ARROW32A
);
349 wndClass
.lpszClassName
= PROGRESS_CLASS32A
;
351 RegisterClass32A( &wndClass
);