Release 980329
[wine/multimedia.git] / controls / progress.c
blob38812a0fdfec4a3e9d1cb43b6292c92e3cff8c66
1 /*
2 * Progress control
4 * Copyright 1997 Dimitrie O. Paun
6 * TODO:
7 * - I do not know what to to on WM_[SG]ET_FONT
8 * Problems:
9 * - I think I do not compute correctly the numer of leds to be drawn
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include "windows.h"
15 #include "sysmetrics.h"
16 #include "progress.h"
17 #include "graphics.h"
18 #include "heap.h"
19 #include "win.h"
20 #include "debug.h"
22 /* Control configuration constants */
24 #define LED_WIDTH 8
25 #define LED_GAP 2
27 /* Work constants */
29 #define UNKNOWN_PARAM(msg, wParam, lParam) WARN(progress, \
30 "Unknown parameter(s) for message " #msg \
31 "(%04x): wp=%04x lp=%08lx\n", msg, wParam, lParam);
33 #define PROGRESS_GetInfoPtr(wndPtr) ((PROGRESS_INFO *)wndPtr->wExtra)
36 /***********************************************************************
37 * PROGRESS_Paint
38 * Draw the arrows. The background need not be erased.
39 * If dc!=0, it draws on it
41 static void PROGRESS_Paint(WND *wndPtr, HDC32 dc)
43 PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(wndPtr);
44 HBRUSH32 ledBrush;
45 int rightBar, rightMost;
46 PAINTSTRUCT32 ps;
47 RECT32 rect;
48 HDC32 hdc;
50 TRACE(progress, "paint pos=%d min=%d, max=%d\n",
51 infoPtr->CurVal, infoPtr->MinVal, infoPtr->MaxVal);
53 /* get a dc */
54 hdc = dc==0 ? BeginPaint32(wndPtr->hwndSelf, &ps) : dc;
56 /* get the required brush */
57 ledBrush = GetSysColorBrush32(COLOR_HIGHLIGHT);
59 /* get rect for the bar, adjusted for the border */
60 GetClientRect32(wndPtr->hwndSelf, &rect);
62 /* draw the border */
63 DrawEdge32(hdc, &rect, BDR_SUNKENOUTER, BF_RECT|BF_ADJUST|BF_MIDDLE);
64 rect.left++; rect.right--; rect.top++; rect.bottom--;
65 rightMost = rect.right;
67 /* compute extent of progress bar */
68 rightBar = rect.left +
69 MulDiv32(infoPtr->CurVal-infoPtr->MinVal,
70 rect.right - rect.left,
71 infoPtr->MaxVal-infoPtr->MinVal);
73 /* now draw the bar */
74 while(rect.left < rightBar) {
75 rect.right = rect.left+LED_WIDTH;
76 FillRect32(hdc, &rect, ledBrush);
77 rect.left = rect.right+LED_GAP;
80 /* clean-up */
81 if(!dc)
82 EndPaint32(wndPtr->hwndSelf, &ps);
85 /***********************************************************************
86 * PROGRESS_CoercePos
87 * Makes sure the current position (CUrVal) is within bounds.
89 static void PROGRESS_CoercePos(WND *wndPtr)
91 PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(wndPtr);
93 if(infoPtr->CurVal < infoPtr->MinVal)
94 infoPtr->CurVal = infoPtr->MinVal;
95 if(infoPtr->CurVal > infoPtr->MaxVal)
96 infoPtr->CurVal = infoPtr->MaxVal;
99 /***********************************************************************
100 * ProgressWindowProc
102 LRESULT WINAPI ProgressWindowProc(HWND32 hwnd, UINT32 message,
103 WPARAM32 wParam, LPARAM lParam)
105 WND *wndPtr = WIN_FindWndPtr(hwnd);
106 PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(wndPtr);
107 UINT32 temp;
109 switch(message)
111 case WM_CREATE:
112 /* initialize the info struct */
113 infoPtr->MinVal=0;
114 infoPtr->MaxVal=100;
115 infoPtr->CurVal=0;
116 infoPtr->Step=10;
117 TRACE(updown, "Progress Ctrl creation, hwnd=%04x\n", hwnd);
118 break;
120 case WM_DESTROY:
121 TRACE(updown, "Progress Ctrl destruction, hwnd=%04x\n", hwnd);
122 break;
124 case WM_ERASEBKGND:
125 /* pretend to erase it here, but we will do it in the paint
126 function to avoid flicker */
127 return 1;
129 case WM_GETFONT:
130 /* FIXME: What do we need to do? */
131 break;
133 case WM_SETFONT:
134 /* FIXME: What do we need to do? */
135 break;
137 case WM_PAINT:
138 PROGRESS_Paint(wndPtr, wParam);
139 break;
141 case PBM_DELTAPOS:
142 if(lParam)
143 UNKNOWN_PARAM(PBM_DELTAPOS, wParam, lParam);
144 temp = infoPtr->CurVal;
145 if(wParam != 0){
146 infoPtr->CurVal += (UINT16)wParam;
147 PROGRESS_CoercePos(wndPtr);
148 PROGRESS_Paint(wndPtr, 0);
150 return temp;
152 case PBM_SETPOS:
153 if (lParam)
154 UNKNOWN_PARAM(PBM_SETPOS, wParam, lParam);
155 temp = infoPtr->CurVal;
156 if(temp != wParam){
157 infoPtr->CurVal = (UINT16)wParam;
158 PROGRESS_CoercePos(wndPtr);
159 PROGRESS_Paint(wndPtr, 0);
161 return temp;
163 case PBM_SETRANGE:
164 if (wParam)
165 UNKNOWN_PARAM(PBM_SETRANGE, wParam, lParam);
166 temp = MAKELONG(infoPtr->MinVal, infoPtr->MaxVal);
167 if(temp != lParam){
168 infoPtr->MinVal = LOWORD(lParam);
169 infoPtr->MaxVal = HIWORD(lParam);
170 if(infoPtr->MaxVal <= infoPtr->MinVal)
171 infoPtr->MaxVal = infoPtr->MinVal+1;
172 PROGRESS_CoercePos(wndPtr);
173 PROGRESS_Paint(wndPtr, 0);
175 return temp;
177 case PBM_SETSTEP:
178 if (lParam)
179 UNKNOWN_PARAM(PBM_SETSTEP, wParam, lParam);
180 temp = infoPtr->Step;
181 infoPtr->Step = (UINT16)wParam;
182 return temp;
184 case PBM_STEPIT:
185 if (wParam || lParam)
186 UNKNOWN_PARAM(PBM_STEPIT, wParam, lParam);
187 temp = infoPtr->CurVal;
188 infoPtr->CurVal += infoPtr->Step;
189 if(infoPtr->CurVal > infoPtr->MaxVal)
190 infoPtr->CurVal = infoPtr->MinVal;
191 if(temp != infoPtr->CurVal)
192 PROGRESS_Paint(wndPtr, 0);
193 return temp;
195 default:
196 if (message >= WM_USER)
197 ERR(progress, "unknown msg %04x wp=%04x lp=%08lx\n",
198 message, wParam, lParam );
199 return DefWindowProc32A( hwnd, message, wParam, lParam );
202 return 0;