source: trunk/src/comctl32/progress.c@ 94

Last change on this file since 94 was 94, checked in by achimha, 26 years ago

Added CVS tag to many files (comctl32 and headers) .

File size: 9.7 KB
Line 
1/* $Id: progress.c,v 1.2 1999-06-10 16:22:01 achimha Exp $ */
2/*
3 * Progress control
4 *
5 * Copyright 1997 Dimitrie O. Paun
6 * Copyright 1998, 1999 Eric Kohl
7 * Copyright 1999 Achim Hasenmueller
8 *
9 */
10
11#include "winbase.h"
12#include "commctrl.h"
13#include "progress.h"
14#include "comctl32.h"
15
16
17/* Control configuration constants */
18
19#define LED_GAP 2
20
21/* Work constants */
22
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);
26#define UNKNOWN_PARAM(msg, wParam, lParam)
27
28#define PROGRESS_GetInfoPtr(hwnd) ((PROGRESS_INFO *)GetWindowLongA(hwnd, 0))
29
30
31/***********************************************************************
32 * PROGRESS_Draw
33 * Draws the progress bar.
34 */
35static void
36PROGRESS_Draw (HWND hwnd, HDC hdc)
37{
38 PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(hwnd);
39 HBRUSH hbrBar, hbrBk;
40 int rightBar, rightMost, ledWidth;
41 RECT rect;
42 DWORD dwStyle;
43
44// TRACE(progress, "refresh pos=%d min=%d, max=%d\n",
45// infoPtr->CurVal, infoPtr->MinVal, infoPtr->MaxVal);
46
47 /* get the required bar brush */
48 if (infoPtr->ColorBar == CLR_DEFAULT)
49 hbrBar = GetSysColorBrush(COLOR_HIGHLIGHT);
50 else
51 hbrBar = CreateSolidBrush (infoPtr->ColorBar);
52
53 /* get the required background brush */
54 if (infoPtr->ColorBk == CLR_DEFAULT)
55 hbrBk = GetSysColorBrush (COLOR_3DFACE);
56 else
57 hbrBk = CreateSolidBrush (infoPtr->ColorBk);
58
59 /* get client rectangle */
60 GetClientRect (hwnd, &rect);
61
62 /* draw the background */
63 FillRect(hdc, &rect, hbrBk);
64
65 rect.left++; rect.right--; rect.top++; rect.bottom--;
66
67 /* get the window style */
68 dwStyle = GetWindowLongA(hwnd, GWL_STYLE);
69
70 /* compute extent of progress bar */
71 if (dwStyle & PBS_VERTICAL)
72 {
73 rightBar = rect.bottom -
74 MulDiv(infoPtr->CurVal-infoPtr->MinVal,
75 rect.bottom - rect.top,
76 infoPtr->MaxVal-infoPtr->MinVal);
77 ledWidth = MulDiv ((rect.right - rect.left), 2, 3);
78 rightMost = rect.top;
79 }
80 else
81 {
82 rightBar = rect.left +
83 MulDiv(infoPtr->CurVal-infoPtr->MinVal,
84 rect.right - rect.left,
85 infoPtr->MaxVal-infoPtr->MinVal);
86 ledWidth = MulDiv ((rect.bottom - rect.top), 2, 3);
87 rightMost = rect.right;
88 }
89
90 /* now draw the bar */
91 if (dwStyle & PBS_SMOOTH)
92 {
93 if (dwStyle & PBS_VERTICAL)
94 rect.top = rightBar;
95 else
96 rect.right = rightBar;
97 FillRect(hdc, &rect, hbrBar);
98 }
99 else
100 {
101 if (dwStyle & PBS_VERTICAL)
102 {
103 while(rect.bottom > rightBar) {
104 rect.top = rect.bottom-ledWidth;
105 if (rect.top < rightMost)
106 rect.top = rightMost;
107 FillRect(hdc, &rect, hbrBar);
108 rect.bottom = rect.top-LED_GAP;
109 }
110 }
111 else {
112 while(rect.left < rightBar) {
113 rect.right = rect.left+ledWidth;
114 if (rect.right > rightMost)
115 rect.right = rightMost;
116 FillRect(hdc, &rect, hbrBar);
117 rect.left = rect.right+LED_GAP;
118 }
119 }
120 }
121
122 /* delete bar brush */
123 if (infoPtr->ColorBar != CLR_DEFAULT)
124 DeleteObject (hbrBar);
125
126 /* delete background brush */
127 if (infoPtr->ColorBk != CLR_DEFAULT)
128 DeleteObject (hbrBk);
129}
130
131/***********************************************************************
132 * PROGRESS_Refresh
133 * Draw the progress bar. The background need not be erased.
134 */
135static void
136PROGRESS_Refresh (HWND hwnd)
137{
138 HDC hdc;
139
140 hdc = GetDC (hwnd);
141 PROGRESS_Draw (hwnd, hdc);
142 ReleaseDC (hwnd, hdc);
143}
144
145/***********************************************************************
146 * PROGRESS_Paint
147 * Draw the progress bar. The background need not be erased.
148 * If dc!=0, it draws on it
149 */
150static void
151PROGRESS_Paint (HWND hwnd)
152{
153 PAINTSTRUCT ps;
154 HDC hdc;
155
156 hdc = BeginPaint (hwnd, &ps);
157 PROGRESS_Draw (hwnd, hdc);
158 EndPaint (hwnd, &ps);
159}
160
161
162/***********************************************************************
163 * PROGRESS_CoercePos
164 * Makes sure the current position (CUrVal) is within bounds.
165 */
166static void PROGRESS_CoercePos(HWND hwnd)
167{
168 PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(hwnd);
169
170 if(infoPtr->CurVal < infoPtr->MinVal)
171 infoPtr->CurVal = infoPtr->MinVal;
172 if(infoPtr->CurVal > infoPtr->MaxVal)
173 infoPtr->CurVal = infoPtr->MaxVal;
174}
175
176
177/***********************************************************************
178 * PROGRESS_SetFont
179 * Set new Font for progress bar
180 */
181static HFONT
182PROGRESS_SetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
183{
184 PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(hwnd);
185 HFONT hOldFont = infoPtr->hFont;
186
187 infoPtr->hFont = (HFONT)wParam;
188 if (LOWORD(lParam))
189 PROGRESS_Refresh (hwnd);
190 return hOldFont;
191}
192
193
194/***********************************************************************
195 * ProgressWindowProc
196 */
197LRESULT WINAPI ProgressWindowProc(HWND hwnd, UINT message,
198 WPARAM wParam, LPARAM lParam)
199{
200 PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(hwnd);
201 UINT temp;
202
203 switch(message)
204 {
205 case WM_NCCREATE:
206 {
207 DWORD dwExStyle;
208 dwExStyle = GetWindowLongA(hwnd, GWL_EXSTYLE);
209 SetWindowLongA(hwnd, GWL_EXSTYLE, dwExStyle | WS_EX_STATICEDGE);
210 }
211 return TRUE;
212
213 case WM_CREATE:
214 /* allocate memory for info struct */
215 infoPtr =
216 (PROGRESS_INFO *)COMCTL32_Alloc (sizeof(PROGRESS_INFO));
217 SetWindowLongA(hwnd, 0, (DWORD)infoPtr);
218
219 /* initialize the info struct */
220 infoPtr->MinVal=0;
221 infoPtr->MaxVal=100;
222 infoPtr->CurVal=0;
223 infoPtr->Step=10;
224 infoPtr->ColorBar=CLR_DEFAULT;
225 infoPtr->ColorBk=CLR_DEFAULT;
226 infoPtr->hFont=(HANDLE)NULL;
227// TRACE(progress, "Progress Ctrl creation, hwnd=%04x\n", hwnd);
228 break;
229
230 case WM_DESTROY:
231// TRACE (progress, "Progress Ctrl destruction, hwnd=%04x\n", hwnd);
232 COMCTL32_Free (infoPtr);
233 break;
234
235 case WM_ERASEBKGND:
236 /* pretend to erase it here, but we will do it in the paint
237 function to avoid flicker */
238 return 1;
239
240 case WM_GETFONT:
241 return (LRESULT)infoPtr->hFont;
242
243 case WM_SETFONT:
244 return PROGRESS_SetFont (hwnd, wParam, lParam);
245
246 case WM_PAINT:
247 PROGRESS_Paint (hwnd);
248 break;
249
250 case PBM_DELTAPOS:
251 if(lParam)
252 UNKNOWN_PARAM(PBM_DELTAPOS, wParam, lParam);
253 temp = infoPtr->CurVal;
254 if(wParam != 0){
255 infoPtr->CurVal += (UINT16)wParam;
256 PROGRESS_CoercePos (hwnd);
257 PROGRESS_Refresh (hwnd);
258 }
259 return temp;
260
261 case PBM_SETPOS:
262 if (lParam)
263 UNKNOWN_PARAM(PBM_SETPOS, wParam, lParam);
264 temp = infoPtr->CurVal;
265 if(temp != wParam){
266 infoPtr->CurVal = (UINT16)wParam;
267 PROGRESS_CoercePos(hwnd);
268 PROGRESS_Refresh (hwnd);
269 }
270 return temp;
271
272 case PBM_SETRANGE:
273 if (wParam)
274 UNKNOWN_PARAM(PBM_SETRANGE, wParam, lParam);
275 temp = MAKELONG(infoPtr->MinVal, infoPtr->MaxVal);
276 if(temp != lParam){
277 infoPtr->MinVal = LOWORD(lParam);
278 infoPtr->MaxVal = HIWORD(lParam);
279 if(infoPtr->MaxVal <= infoPtr->MinVal)
280 infoPtr->MaxVal = infoPtr->MinVal+1;
281 PROGRESS_CoercePos(hwnd);
282 PROGRESS_Refresh (hwnd);
283 }
284 return temp;
285
286 case PBM_SETSTEP:
287 if (lParam)
288 UNKNOWN_PARAM(PBM_SETSTEP, wParam, lParam);
289 temp = infoPtr->Step;
290 infoPtr->Step = (UINT16)wParam;
291 return temp;
292
293 case PBM_STEPIT:
294 if (wParam || lParam)
295 UNKNOWN_PARAM(PBM_STEPIT, wParam, lParam);
296 temp = infoPtr->CurVal;
297 infoPtr->CurVal += infoPtr->Step;
298 if(infoPtr->CurVal > infoPtr->MaxVal)
299 infoPtr->CurVal = infoPtr->MinVal;
300 if(temp != infoPtr->CurVal)
301 PROGRESS_Refresh (hwnd);
302 return temp;
303
304 case PBM_SETRANGE32:
305 temp = MAKELONG(infoPtr->MinVal, infoPtr->MaxVal);
306 if((infoPtr->MinVal != (INT)wParam) ||
307 (infoPtr->MaxVal != (INT)lParam)) {
308 infoPtr->MinVal = (INT)wParam;
309 infoPtr->MaxVal = (INT)lParam;
310 if(infoPtr->MaxVal <= infoPtr->MinVal)
311 infoPtr->MaxVal = infoPtr->MinVal+1;
312 PROGRESS_CoercePos(hwnd);
313 PROGRESS_Refresh (hwnd);
314 }
315 return temp;
316
317 case PBM_GETRANGE:
318 if (lParam){
319 ((PPBRANGE)lParam)->iLow = infoPtr->MinVal;
320 ((PPBRANGE)lParam)->iHigh = infoPtr->MaxVal;
321 }
322 return (wParam) ? infoPtr->MinVal : infoPtr->MaxVal;
323
324 case PBM_GETPOS:
325 if (wParam || lParam)
326 UNKNOWN_PARAM(PBM_STEPIT, wParam, lParam);
327 return (infoPtr->CurVal);
328
329 case PBM_SETBARCOLOR:
330 if (wParam)
331 UNKNOWN_PARAM(PBM_SETBARCOLOR, wParam, lParam);
332 infoPtr->ColorBar = (COLORREF)lParam;
333 PROGRESS_Refresh (hwnd);
334 break;
335
336 case PBM_SETBKCOLOR:
337 if (wParam)
338 UNKNOWN_PARAM(PBM_SETBKCOLOR, wParam, lParam);
339 infoPtr->ColorBk = (COLORREF)lParam;
340 PROGRESS_Refresh (hwnd);
341 break;
342
343 default:
344// if (message >= WM_USER)
345// ERR(progress, "unknown msg %04x wp=%04x lp=%08lx\n",
346// message, wParam, lParam );
347 return DefWindowProcA( hwnd, message, wParam, lParam );
348 }
349
350 return 0;
351}
352
353
354/***********************************************************************
355 * PROGRESS_Register [Internal]
356 *
357 * Registers the progress bar window class.
358 */
359
360VOID
361PROGRESS_Register (VOID)
362{
363 WNDCLASSA wndClass;
364
365 if (GlobalFindAtomA(PROGRESS_CLASSA)) return;
366
367 ZeroMemory (&wndClass, sizeof( WNDCLASSA));
368 wndClass.style = CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW;
369 wndClass.lpfnWndProc = (WNDPROC)ProgressWindowProc;
370 wndClass.cbClsExtra = 0;
371 wndClass.cbWndExtra = sizeof (PROGRESS_INFO *);
372 wndClass.hCursor = LoadCursorA(0, IDC_ARROWA);
373 wndClass.lpszClassName = PROGRESS_CLASSA;
374
375 RegisterClassA(&wndClass);
376}
377
378
379/***********************************************************************
380 * PROGRESS_Unregister [Internal]
381 *
382 * Unregisters the progress bar window class.
383 */
384
385VOID
386PROGRESS_Unregister (VOID)
387{
388 if (GlobalFindAtomA(PROGRESS_CLASSA))
389 UnregisterClassA(PROGRESS_CLASSA, (HINSTANCE)NULL);
390}
391
Note: See TracBrowser for help on using the repository browser.