4 * Copyright 1997 Dimitrie O. Paun
5 * Copyright 1998, 1999 Eric Kohl
12 #include "debugtools.h"
14 DEFAULT_DEBUG_CHANNEL(progress
)
17 /* Control configuration constants */
23 #define UNKNOWN_PARAM(msg, wParam, lParam) WARN(\
24 "Unknown parameter(s) for message " #msg \
25 "(%04x): wp=%04x lp=%08lx\n", msg, wParam, lParam);
27 #define PROGRESS_GetInfoPtr(hwnd) ((PROGRESS_INFO *)GetWindowLongA(hwnd, 0))
30 /***********************************************************************
32 * Draws the progress bar.
35 PROGRESS_Draw (HWND hwnd
, HDC hdc
)
37 PROGRESS_INFO
*infoPtr
= PROGRESS_GetInfoPtr(hwnd
);
39 int rightBar
, rightMost
, ledWidth
;
43 TRACE("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
= GetSysColorBrush(COLOR_HIGHLIGHT
);
50 hbrBar
= CreateSolidBrush (infoPtr
->ColorBar
);
52 /* get the required background brush */
53 if (infoPtr
->ColorBk
== CLR_DEFAULT
)
54 hbrBk
= GetSysColorBrush (COLOR_3DFACE
);
56 hbrBk
= CreateSolidBrush (infoPtr
->ColorBk
);
58 /* get client rectangle */
59 GetClientRect (hwnd
, &rect
);
61 /* draw the background */
62 FillRect(hdc
, &rect
, hbrBk
);
64 rect
.left
++; rect
.right
--; rect
.top
++; rect
.bottom
--;
66 /* get the window style */
67 dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
69 /* compute extent of progress bar */
70 if (dwStyle
& PBS_VERTICAL
)
72 rightBar
= rect
.bottom
-
73 MulDiv(infoPtr
->CurVal
-infoPtr
->MinVal
,
74 rect
.bottom
- rect
.top
,
75 infoPtr
->MaxVal
-infoPtr
->MinVal
);
76 ledWidth
= MulDiv ((rect
.right
- rect
.left
), 2, 3);
81 rightBar
= rect
.left
+
82 MulDiv(infoPtr
->CurVal
-infoPtr
->MinVal
,
83 rect
.right
- rect
.left
,
84 infoPtr
->MaxVal
-infoPtr
->MinVal
);
85 ledWidth
= MulDiv ((rect
.bottom
- rect
.top
), 2, 3);
86 rightMost
= rect
.right
;
89 /* now draw the bar */
90 if (dwStyle
& PBS_SMOOTH
)
92 if (dwStyle
& PBS_VERTICAL
)
95 rect
.right
= rightBar
;
96 FillRect(hdc
, &rect
, hbrBar
);
100 if (dwStyle
& PBS_VERTICAL
)
102 while(rect
.bottom
> rightBar
) {
103 rect
.top
= rect
.bottom
-ledWidth
;
104 if (rect
.top
< rightMost
)
105 rect
.top
= rightMost
;
106 FillRect(hdc
, &rect
, hbrBar
);
107 rect
.bottom
= rect
.top
-LED_GAP
;
111 while(rect
.left
< rightBar
) {
112 rect
.right
= rect
.left
+ledWidth
;
113 if (rect
.right
> rightMost
)
114 rect
.right
= rightMost
;
115 FillRect(hdc
, &rect
, hbrBar
);
116 rect
.left
= rect
.right
+LED_GAP
;
121 /* delete bar brush */
122 if (infoPtr
->ColorBar
!= CLR_DEFAULT
)
123 DeleteObject (hbrBar
);
125 /* delete background brush */
126 if (infoPtr
->ColorBk
!= CLR_DEFAULT
)
127 DeleteObject (hbrBk
);
130 /***********************************************************************
132 * Draw the progress bar. The background need not be erased.
135 PROGRESS_Refresh (HWND hwnd
)
140 PROGRESS_Draw (hwnd
, hdc
);
141 ReleaseDC (hwnd
, hdc
);
144 /***********************************************************************
146 * Draw the progress bar. The background need not be erased.
147 * If dc!=0, it draws on it
150 PROGRESS_Paint (HWND hwnd
)
155 hdc
= BeginPaint (hwnd
, &ps
);
156 PROGRESS_Draw (hwnd
, hdc
);
157 EndPaint (hwnd
, &ps
);
161 /***********************************************************************
163 * Makes sure the current position (CUrVal) is within bounds.
165 static void PROGRESS_CoercePos(HWND hwnd
)
167 PROGRESS_INFO
*infoPtr
= PROGRESS_GetInfoPtr(hwnd
);
169 if(infoPtr
->CurVal
< infoPtr
->MinVal
)
170 infoPtr
->CurVal
= infoPtr
->MinVal
;
171 if(infoPtr
->CurVal
> infoPtr
->MaxVal
)
172 infoPtr
->CurVal
= infoPtr
->MaxVal
;
176 /***********************************************************************
178 * Set new Font for progress bar
181 PROGRESS_SetFont (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
183 PROGRESS_INFO
*infoPtr
= PROGRESS_GetInfoPtr(hwnd
);
184 HFONT hOldFont
= infoPtr
->hFont
;
186 infoPtr
->hFont
= (HFONT
)wParam
;
188 PROGRESS_Refresh (hwnd
);
193 /***********************************************************************
196 static LRESULT WINAPI
ProgressWindowProc(HWND hwnd
, UINT message
,
197 WPARAM wParam
, LPARAM lParam
)
199 PROGRESS_INFO
*infoPtr
= PROGRESS_GetInfoPtr(hwnd
);
207 dwExStyle
= GetWindowLongA (hwnd
, GWL_EXSTYLE
);
208 SetWindowLongA (hwnd
, GWL_EXSTYLE
, dwExStyle
| WS_EX_STATICEDGE
);
213 /* allocate memory for info struct */
215 (PROGRESS_INFO
*)COMCTL32_Alloc (sizeof(PROGRESS_INFO
));
216 SetWindowLongA (hwnd
, 0, (DWORD
)infoPtr
);
218 /* initialize the info struct */
223 infoPtr
->ColorBar
=CLR_DEFAULT
;
224 infoPtr
->ColorBk
=CLR_DEFAULT
;
225 infoPtr
->hFont
=(HANDLE
)NULL
;
226 TRACE("Progress Ctrl creation, hwnd=%04x\n", hwnd
);
230 TRACE("Progress Ctrl destruction, hwnd=%04x\n", hwnd
);
231 COMCTL32_Free (infoPtr
);
235 /* pretend to erase it here, but we will do it in the paint
236 function to avoid flicker */
240 return (LRESULT
)infoPtr
->hFont
;
243 return PROGRESS_SetFont (hwnd
, wParam
, lParam
);
246 PROGRESS_Paint (hwnd
);
251 UNKNOWN_PARAM(PBM_DELTAPOS
, wParam
, lParam
);
252 temp
= infoPtr
->CurVal
;
254 infoPtr
->CurVal
+= (UINT16
)wParam
;
255 PROGRESS_CoercePos (hwnd
);
256 PROGRESS_Refresh (hwnd
);
262 UNKNOWN_PARAM(PBM_SETPOS
, wParam
, lParam
);
263 temp
= infoPtr
->CurVal
;
265 infoPtr
->CurVal
= (UINT16
)wParam
;
266 PROGRESS_CoercePos(hwnd
);
267 PROGRESS_Refresh (hwnd
);
273 UNKNOWN_PARAM(PBM_SETRANGE
, wParam
, lParam
);
274 temp
= MAKELONG(infoPtr
->MinVal
, infoPtr
->MaxVal
);
276 infoPtr
->MinVal
= LOWORD(lParam
);
277 infoPtr
->MaxVal
= HIWORD(lParam
);
278 if(infoPtr
->MaxVal
<= infoPtr
->MinVal
)
279 infoPtr
->MaxVal
= infoPtr
->MinVal
+1;
280 PROGRESS_CoercePos(hwnd
);
281 PROGRESS_Refresh (hwnd
);
287 UNKNOWN_PARAM(PBM_SETSTEP
, wParam
, lParam
);
288 temp
= infoPtr
->Step
;
289 infoPtr
->Step
= (UINT16
)wParam
;
293 if (wParam
|| lParam
)
294 UNKNOWN_PARAM(PBM_STEPIT
, wParam
, lParam
);
295 temp
= infoPtr
->CurVal
;
296 infoPtr
->CurVal
+= infoPtr
->Step
;
297 if(infoPtr
->CurVal
> infoPtr
->MaxVal
)
298 infoPtr
->CurVal
= infoPtr
->MinVal
;
299 if(temp
!= infoPtr
->CurVal
)
300 PROGRESS_Refresh (hwnd
);
304 temp
= MAKELONG(infoPtr
->MinVal
, infoPtr
->MaxVal
);
305 if((infoPtr
->MinVal
!= (INT
)wParam
) ||
306 (infoPtr
->MaxVal
!= (INT
)lParam
)) {
307 infoPtr
->MinVal
= (INT
)wParam
;
308 infoPtr
->MaxVal
= (INT
)lParam
;
309 if(infoPtr
->MaxVal
<= infoPtr
->MinVal
)
310 infoPtr
->MaxVal
= infoPtr
->MinVal
+1;
311 PROGRESS_CoercePos(hwnd
);
312 PROGRESS_Refresh (hwnd
);
318 ((PPBRANGE
)lParam
)->iLow
= infoPtr
->MinVal
;
319 ((PPBRANGE
)lParam
)->iHigh
= infoPtr
->MaxVal
;
321 return (wParam
) ? infoPtr
->MinVal
: infoPtr
->MaxVal
;
324 if (wParam
|| lParam
)
325 UNKNOWN_PARAM(PBM_STEPIT
, wParam
, lParam
);
326 return (infoPtr
->CurVal
);
328 case PBM_SETBARCOLOR
:
330 UNKNOWN_PARAM(PBM_SETBARCOLOR
, wParam
, lParam
);
331 infoPtr
->ColorBar
= (COLORREF
)lParam
;
332 PROGRESS_Refresh (hwnd
);
337 UNKNOWN_PARAM(PBM_SETBKCOLOR
, wParam
, lParam
);
338 infoPtr
->ColorBk
= (COLORREF
)lParam
;
339 PROGRESS_Refresh (hwnd
);
343 if (message
>= WM_USER
)
344 ERR("unknown msg %04x wp=%04x lp=%08lx\n",
345 message
, wParam
, lParam
);
346 return DefWindowProcA( hwnd
, message
, wParam
, lParam
);
353 /***********************************************************************
354 * PROGRESS_Register [Internal]
356 * Registers the progress bar window class.
360 PROGRESS_Register (void)
364 ZeroMemory (&wndClass
, sizeof( WNDCLASSA
));
365 wndClass
.style
= CS_GLOBALCLASS
| CS_VREDRAW
| CS_HREDRAW
;
366 wndClass
.lpfnWndProc
= (WNDPROC
)ProgressWindowProc
;
367 wndClass
.cbClsExtra
= 0;
368 wndClass
.cbWndExtra
= sizeof (PROGRESS_INFO
*);
369 wndClass
.hCursor
= LoadCursorA (0, IDC_ARROWA
);
370 wndClass
.lpszClassName
= PROGRESS_CLASSA
;
372 RegisterClassA (&wndClass
);
376 /***********************************************************************
377 * PROGRESS_Unregister [Internal]
379 * Unregisters the progress bar window class.
383 PROGRESS_Unregister (void)
385 UnregisterClassA (PROGRESS_CLASSA
, (HINSTANCE
)NULL
);