4 * Copyright 1997 Dimitrie O. Paun
5 * Copyright 1998, 1999 Eric Kohl
11 #include "debugtools.h"
13 DEFAULT_DEBUG_CHANNEL(progress);
17 INT CurVal; /* Current progress value */
18 INT MinVal; /* Minimum progress value */
19 INT MaxVal; /* Maximum progress value */
20 INT Step; /* Step to use on PMB_STEPIT */
21 COLORREF ColorBar; /* Bar color */
22 COLORREF ColorBk; /* Background color */
23 HFONT hFont; /* Handle to font (not unused) */
26 /* Control configuration constants */
32 #define UNKNOWN_PARAM(msg, wParam, lParam) WARN(\
33 "Unknown parameter(s) for message " #msg \
34 "(%04x): wp=%04x lp=%08lx\n", msg, wParam, lParam);
36 #define PROGRESS_GetInfoPtr(hwnd) ((PROGRESS_INFO *)GetWindowLongA(hwnd, 0))
39 /***********************************************************************
41 * Draws the progress bar.
44 PROGRESS_Draw (HWND hwnd, HDC hdc)
46 PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(hwnd);
48 int rightBar, rightMost, ledWidth;
52 TRACE("refresh pos=%d min=%d, max=%d\n",
53 infoPtr->CurVal, infoPtr->MinVal, infoPtr->MaxVal);
55 /* get the required bar brush */
56 if (infoPtr->ColorBar == CLR_DEFAULT)
57 hbrBar = GetSysColorBrush(COLOR_HIGHLIGHT);
59 hbrBar = CreateSolidBrush (infoPtr->ColorBar);
61 /* get the required background brush */
62 if (infoPtr->ColorBk == CLR_DEFAULT)
63 hbrBk = GetSysColorBrush (COLOR_3DFACE);
65 hbrBk = CreateSolidBrush (infoPtr->ColorBk);
67 /* get client rectangle */
68 GetClientRect (hwnd, &rect);
70 /* draw the background */
71 FillRect(hdc, &rect, hbrBk);
73 rect.left++; rect.right--; rect.top++; rect.bottom--;
75 /* get the window style */
76 dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
78 /* compute extent of progress bar */
79 if (dwStyle & PBS_VERTICAL)
81 rightBar = rect.bottom -
82 MulDiv(infoPtr->CurVal-infoPtr->MinVal,
83 rect.bottom - rect.top,
84 infoPtr->MaxVal-infoPtr->MinVal);
85 ledWidth = MulDiv ((rect.right - rect.left), 2, 3);
90 rightBar = rect.left +
91 MulDiv(infoPtr->CurVal-infoPtr->MinVal,
92 rect.right - rect.left,
93 infoPtr->MaxVal-infoPtr->MinVal);
94 ledWidth = MulDiv ((rect.bottom - rect.top), 2, 3);
95 rightMost = rect.right;
98 /* now draw the bar */
99 if (dwStyle & PBS_SMOOTH)
101 if (dwStyle & PBS_VERTICAL)
104 rect.right = rightBar;
105 FillRect(hdc, &rect, hbrBar);
109 if (dwStyle & PBS_VERTICAL)
111 while(rect.bottom > rightBar) {
112 rect.top = rect.bottom-ledWidth;
113 if (rect.top < rightMost)
114 rect.top = rightMost;
115 FillRect(hdc, &rect, hbrBar);
116 rect.bottom = rect.top-LED_GAP;
120 while(rect.left < rightBar) {
121 rect.right = rect.left+ledWidth;
122 if (rect.right > rightMost)
123 rect.right = rightMost;
124 FillRect(hdc, &rect, hbrBar);
125 rect.left = rect.right+LED_GAP;
130 /* delete bar brush */
131 if (infoPtr->ColorBar != CLR_DEFAULT)
132 DeleteObject (hbrBar);
134 /* delete background brush */
135 if (infoPtr->ColorBk != CLR_DEFAULT)
136 DeleteObject (hbrBk);
139 /***********************************************************************
141 * Draw the progress bar. The background need not be erased.
144 PROGRESS_Refresh (HWND hwnd)
149 PROGRESS_Draw (hwnd, hdc);
150 ReleaseDC (hwnd, hdc);
153 /***********************************************************************
155 * Draw the progress bar. The background need not be erased.
156 * If dc!=0, it draws on it
159 PROGRESS_Paint (HWND hwnd)
164 hdc = BeginPaint (hwnd, &ps);
165 PROGRESS_Draw (hwnd, hdc);
166 EndPaint (hwnd, &ps);
170 /***********************************************************************
172 * Makes sure the current position (CUrVal) is within bounds.
174 static void PROGRESS_CoercePos(HWND hwnd)
176 PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(hwnd);
178 if(infoPtr->CurVal < infoPtr->MinVal)
179 infoPtr->CurVal = infoPtr->MinVal;
180 if(infoPtr->CurVal > infoPtr->MaxVal)
181 infoPtr->CurVal = infoPtr->MaxVal;
185 /***********************************************************************
187 * Set new Font for progress bar
190 PROGRESS_SetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
192 PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(hwnd);
193 HFONT hOldFont = infoPtr->hFont;
195 infoPtr->hFont = (HFONT)wParam;
197 PROGRESS_Refresh (hwnd);
202 /***********************************************************************
205 static LRESULT WINAPI ProgressWindowProc(HWND hwnd, UINT message,
206 WPARAM wParam, LPARAM lParam)
208 PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(hwnd);
210 if (!infoPtr && (message != WM_CREATE))
211 return DefWindowProcA( hwnd, message, wParam, lParam );
217 dwExStyle = GetWindowLongA (hwnd, GWL_EXSTYLE);
218 SetWindowLongA (hwnd, GWL_EXSTYLE, dwExStyle | WS_EX_STATICEDGE);
223 /* allocate memory for info struct */
225 (PROGRESS_INFO *)COMCTL32_Alloc (sizeof(PROGRESS_INFO));
226 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
228 /* initialize the info struct */
233 infoPtr->ColorBar=CLR_DEFAULT;
234 infoPtr->ColorBk=CLR_DEFAULT;
235 infoPtr->hFont=(HANDLE)NULL;
236 TRACE("Progress Ctrl creation, hwnd=%04x\n", hwnd);
240 TRACE("Progress Ctrl destruction, hwnd=%04x\n", hwnd);
241 COMCTL32_Free (infoPtr);
242 SetWindowLongA(hwnd, 0, 0);
246 /* pretend to erase it here, but we will do it in the paint
247 function to avoid flicker */
251 return (LRESULT)infoPtr->hFont;
254 return PROGRESS_SetFont (hwnd, wParam, lParam);
257 PROGRESS_Paint (hwnd);
262 UNKNOWN_PARAM(PBM_DELTAPOS, wParam, lParam);
263 temp = infoPtr->CurVal;
265 infoPtr->CurVal += (WORD)wParam;
266 PROGRESS_CoercePos (hwnd);
267 PROGRESS_Refresh (hwnd);
273 UNKNOWN_PARAM(PBM_SETPOS, wParam, lParam);
274 temp = infoPtr->CurVal;
276 infoPtr->CurVal = (WORD)wParam;
277 PROGRESS_CoercePos(hwnd);
278 PROGRESS_Refresh (hwnd);
284 UNKNOWN_PARAM(PBM_SETRANGE, wParam, lParam);
285 temp = MAKELONG(infoPtr->MinVal, infoPtr->MaxVal);
287 infoPtr->MinVal = LOWORD(lParam);
288 infoPtr->MaxVal = HIWORD(lParam);
289 if(infoPtr->MaxVal <= infoPtr->MinVal)
290 infoPtr->MaxVal = infoPtr->MinVal+1;
291 PROGRESS_CoercePos(hwnd);
292 PROGRESS_Refresh (hwnd);
298 UNKNOWN_PARAM(PBM_SETSTEP, wParam, lParam);
299 temp = infoPtr->Step;
300 infoPtr->Step = (WORD)wParam;
304 if (wParam || lParam)
305 UNKNOWN_PARAM(PBM_STEPIT, wParam, lParam);
306 temp = infoPtr->CurVal;
307 infoPtr->CurVal += infoPtr->Step;
308 if(infoPtr->CurVal > infoPtr->MaxVal)
309 infoPtr->CurVal = infoPtr->MinVal;
310 if(temp != infoPtr->CurVal)
311 PROGRESS_Refresh (hwnd);
315 temp = MAKELONG(infoPtr->MinVal, infoPtr->MaxVal);
316 if((infoPtr->MinVal != (INT)wParam) ||
317 (infoPtr->MaxVal != (INT)lParam)) {
318 infoPtr->MinVal = (INT)wParam;
319 infoPtr->MaxVal = (INT)lParam;
320 if(infoPtr->MaxVal <= infoPtr->MinVal)
321 infoPtr->MaxVal = infoPtr->MinVal+1;
322 PROGRESS_CoercePos(hwnd);
323 PROGRESS_Refresh (hwnd);
329 ((PPBRANGE)lParam)->iLow = infoPtr->MinVal;
330 ((PPBRANGE)lParam)->iHigh = infoPtr->MaxVal;
332 return (wParam) ? infoPtr->MinVal : infoPtr->MaxVal;
335 if (wParam || lParam)
336 UNKNOWN_PARAM(PBM_STEPIT, wParam, lParam);
337 return (infoPtr->CurVal);
339 case PBM_SETBARCOLOR:
341 UNKNOWN_PARAM(PBM_SETBARCOLOR, wParam, lParam);
342 infoPtr->ColorBar = (COLORREF)lParam;
343 PROGRESS_Refresh (hwnd);
348 UNKNOWN_PARAM(PBM_SETBKCOLOR, wParam, lParam);
349 infoPtr->ColorBk = (COLORREF)lParam;
350 PROGRESS_Refresh (hwnd);
354 if (message >= WM_USER)
355 ERR("unknown msg %04x wp=%04x lp=%08lx\n",
356 message, wParam, lParam );
357 return DefWindowProcA( hwnd, message, wParam, lParam );
364 /***********************************************************************
365 * PROGRESS_Register [Internal]
367 * Registers the progress bar window class.
371 PROGRESS_Register (void)
375 ZeroMemory (&wndClass, sizeof( WNDCLASSA));
376 wndClass.style = CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW;
377 wndClass.lpfnWndProc = (WNDPROC)ProgressWindowProc;
378 wndClass.cbClsExtra = 0;
379 wndClass.cbWndExtra = sizeof (PROGRESS_INFO *);
380 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
381 wndClass.lpszClassName = PROGRESS_CLASSA;
383 RegisterClassA (&wndClass);
387 /***********************************************************************
388 * PROGRESS_Unregister [Internal]
390 * Unregisters the progress bar window class.
394 PROGRESS_Unregister (void)
396 UnregisterClassA (PROGRESS_CLASSA, (HINSTANCE)NULL);