Release 971130
[wine/hacks.git] / controls / status.c
blob395ebce5e06d2cf945435f4ef1f405248be70fb7
1 /*
2 * Interface code to StatusWindow widget/control
4 * Copyright 1996 Bruce Milner
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "windows.h"
10 #include "status.h"
11 #include "commctrl.h"
12 #include "heap.h"
13 #include "win.h"
16 * Run tests using Waite Group Windows95 API Bible Vol. 1&2
17 * The second cdrom contains executables drawstat.exe,gettext.exe,
18 * simple.exe, getparts.exe, setparts.exe, statwnd.exe
22 * Fixme/Todo
23 * 1) Add size grip to status bar - SBARS_SIZEGRIP
24 * 2) Don't hard code bar to bottom of window, allow CCS_TOP also
25 * 3) Fix SBT_OWNERDRAW
26 * 4) Add DrawStatusText32A funtion
29 static STATUSWINDOWINFO *GetStatusInfo(HWND32 hwnd)
31 WND *wndPtr;
33 wndPtr = WIN_FindWndPtr(hwnd);
34 return ((STATUSWINDOWINFO *) &wndPtr->wExtra[0]);
37 static BOOL32 SW_Refresh( HWND32 hwnd, HDC32 hdc, STATUSWINDOWINFO *self )
39 int i;
41 if (!IsWindowVisible32(hwnd)) {
42 return (TRUE);
45 if (self->simple) {
46 DrawStatusText32A(hdc,
47 &self->part0.bound,
48 self->part0.text,
49 self->part0.style);
51 else {
52 for (i = 0; i < self->numParts; i++) {
53 DrawStatusText32A(hdc,
54 &self->parts[i].bound,
55 self->parts[i].text,
56 self->parts[i].style);
60 return TRUE;
64 static LRESULT
65 SW_GetBorders(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
67 LPINT32 out;
69 /* FIXME for sizegrips */
70 out = (LPINT32) lParam;
71 out[0] = 1; /* vertical border width */
72 out[1] = 1; /* horizontal border width */
73 out[2] = 1; /* width of border between rectangles */
74 return TRUE;
77 static void
78 SW_SetPartBounds(HWND32 hwnd, STATUSWINDOWINFO *self)
80 int i;
81 RECT32 rect, *r;
82 STATUSWINDOWPART *part;
83 int sep = 1;
85 /* get our window size */
86 GetClientRect32(hwnd, &rect);
88 /* set bounds for simple rectangle */
89 self->part0.bound = rect;
91 /* set bounds for non-simple rectangles */
92 for (i = 0; i < self->numParts; i++) {
93 part = &self->parts[i];
94 r = &self->parts[i].bound;
95 r->top = rect.top;
96 r->bottom = rect.bottom;
97 if (i == 0)
98 r->left = 0;
99 else
100 r->left = self->parts[i-1].bound.right+sep;
101 if (part->x == -1)
102 r->right = rect.right;
103 else
104 r->right = part->x;
108 static LRESULT
109 SW_SetText(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
111 int part_num;
112 int style;
113 LPSTR text;
114 int len;
115 STATUSWINDOWPART *part;
117 text = (LPSTR) lParam;
118 part_num = ((INT32) wParam) & 0x00ff;
119 style = ((INT32) wParam) & 0xff00;
121 if ((self->simple) || (self->parts==NULL) || (part_num==255))
122 part = &self->part0;
123 else
124 part = &self->parts[part_num];
125 if (!part) return FALSE;
126 part->style = style;
127 if (style == SBT_OWNERDRAW) {
128 part->text = text;
130 else {
131 /* duplicate string */
132 if (part->text)
133 HeapFree(SystemHeap, 0, part->text);
134 part->text = 0;
135 if (text && (len = lstrlen32A(text))) {
136 part->text = HeapAlloc(SystemHeap, 0, len+1);
137 lstrcpy32A(part->text, text);
140 InvalidateRect32(hwnd, &part->bound, FALSE);
141 return TRUE;
144 static LRESULT
145 SW_SetParts(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
147 HDC32 hdc;
148 LPINT32 parts;
149 STATUSWINDOWPART * tmp;
150 int i;
151 int oldNumParts;
153 if (self->simple) {
154 self->simple = FALSE;
156 oldNumParts = self->numParts;
157 self->numParts = (INT32) wParam;
158 parts = (LPINT32) lParam;
159 if (oldNumParts > self->numParts) {
160 for (i = self->numParts ; i < oldNumParts; i++) {
161 if (self->parts[i].text && (self->parts[i].style != SBT_OWNERDRAW))
162 HeapFree(SystemHeap, 0, self->parts[i].text);
165 else if (oldNumParts < self->numParts) {
166 tmp = HeapAlloc(SystemHeap, HEAP_ZERO_MEMORY,
167 sizeof(STATUSWINDOWPART) * self->numParts);
168 for (i = 0; i < oldNumParts; i++) {
169 tmp[i] = self->parts[i];
171 if (self->parts)
172 HeapFree(SystemHeap, 0, self->parts);
173 self->parts = tmp;
176 for (i = 0; i < self->numParts; i++) {
177 self->parts[i].x = parts[i];
179 SW_SetPartBounds(hwnd, self);
181 hdc = GetDC32(hwnd);
182 SW_Refresh(hwnd, hdc, self);
183 ReleaseDC32(hwnd, hdc);
184 return TRUE;
187 static LRESULT
188 SW_GetParts(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
190 LPINT32 parts;
191 INT32 num_parts;
192 int i;
194 self = GetStatusInfo(hwnd);
195 num_parts = (INT32) wParam;
196 parts = (LPINT32) lParam;
197 if (parts) {
198 return (self->numParts);
199 for (i = 0; i < num_parts; i++) {
200 parts[i] = self->parts[i].x;
203 return (self->numParts);
206 static LRESULT
207 SW_Create(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
209 RECT32 rect;
210 LPCREATESTRUCT32A lpCreate = (LPCREATESTRUCT32A) lParam;
211 int height, width;
212 HDC32 hdc;
213 HWND32 parent;
215 self->numParts = 0;
216 self->parts = 0;
217 self->simple = TRUE;
218 GetClientRect32(hwnd, &rect);
220 /* initialize simple case */
221 self->part0.bound = rect;
222 self->part0.text = 0;
223 self->part0.x = 0;
224 self->part0.style = 0;
226 height = 40;
227 if ((hdc = GetDC32(0))) {
228 TEXTMETRIC32A tm;
229 GetTextMetrics32A(hdc, &tm);
230 self->textHeight = tm.tmHeight;
231 ReleaseDC32(0, hdc);
234 parent = GetParent32(hwnd);
235 GetClientRect32(parent, &rect);
236 width = rect.right - rect.left;
237 height = (self->textHeight * 3)/2;
238 MoveWindow32(hwnd, lpCreate->x, lpCreate->y-1, width, height, FALSE);
239 SW_SetPartBounds(hwnd, self);
240 return 0;
243 static LRESULT
244 SW_GetRect(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
246 int part_num;
247 LPRECT32 rect;
249 part_num = ((INT32) wParam) & 0x00ff;
250 rect = (LPRECT32) lParam;
251 if (self->simple)
252 *rect = self->part0.bound;
253 else
254 *rect = self->parts[part_num].bound;
255 return TRUE;
258 static LRESULT
259 SW_GetText(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
261 int part_num;
262 LRESULT result;
263 STATUSWINDOWPART *part;
264 LPSTR out_text;
266 part_num = ((INT32) wParam) & 0x00ff;
267 out_text = (LPSTR) lParam;
268 if (self->simple)
269 part = &self->part0;
270 else
271 part = &self->parts[part_num];
273 if (part->style == SBT_OWNERDRAW)
274 result = (LRESULT) part->text;
275 else {
276 result = part->text ? lstrlen32A(part->text) : 0;
277 result |= (part->style << 16);
278 if (out_text) {
279 lstrcpy32A(out_text, part->text);
282 return result;
285 static LRESULT
286 SW_GetTextLength(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
288 int part_num;
289 STATUSWINDOWPART *part;
290 DWORD result;
292 part_num = ((INT32) wParam) & 0x00ff;
294 if (self->simple)
295 part = &self->part0;
296 else
297 part = &self->parts[part_num];
299 if (part->text)
300 result = lstrlen32A(part->text);
301 else
302 result = 0;
304 result |= (part->style << 16);
305 return result;
308 static LRESULT
309 SW_SetMinHeight(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
311 /* FIXME */
312 /* size is wParam | 2*pixels_of_horz_border */
313 return TRUE;
316 static LRESULT
317 SW_Simple(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
319 BOOL32 simple;
320 HDC32 hdc;
322 simple = (BOOL32) wParam;
323 self->simple = simple;
324 hdc = GetDC32(hwnd);
325 SW_Refresh(hwnd, hdc, self);
326 ReleaseDC32(hwnd, hdc);
327 return TRUE;
330 static LRESULT
331 SW_Size(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
333 /* Need to resize width to match parent */
334 INT32 width, height, x, y;
335 RECT32 parent_rect;
336 HWND32 parent;
338 INT32 flags;
340 flags = (INT32) wParam;
342 /* FIXME for flags =
343 * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED, SIZE_RESTORED
346 if (flags == SIZE_RESTORED) {
347 /* width and height don't apply */
348 parent = GetParent32(hwnd);
349 GetClientRect32(parent, &parent_rect);
350 height = (self->textHeight * 3)/2;
351 width = parent_rect.right - parent_rect.left;
352 x = parent_rect.left;
353 y = parent_rect.bottom - height;
354 MoveWindow32(hwnd, parent_rect.left, parent_rect.bottom - height - 1,
355 width, height, TRUE);
356 SW_SetPartBounds(hwnd, self);
358 return 0;
361 static LRESULT
362 SW_Destroy(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
364 int i;
366 for (i = 0; i < self->numParts; i++) {
367 if (self->parts[i].text && (self->parts[i].style != SBT_OWNERDRAW))
368 HeapFree(SystemHeap, 0, self->parts[i].text);
370 if (self->part0.text && (self->part0.style != SBT_OWNERDRAW))
371 HeapFree(SystemHeap, 0, self->part0.text);
372 HeapFree(SystemHeap, 0, self->parts);
373 return 0;
378 static LRESULT
379 SW_Paint(STATUSWINDOWINFO *self, HWND32 hwnd)
381 HDC32 hdc;
382 PAINTSTRUCT32 ps;
384 hdc = BeginPaint32(hwnd, &ps);
385 SW_Refresh(hwnd, hdc, self);
386 EndPaint32(hwnd, &ps);
387 return 0;
390 LRESULT WINAPI StatusWindowProc( HWND32 hwnd, UINT32 msg,
391 WPARAM32 wParam, LPARAM lParam )
393 STATUSWINDOWINFO *self;
395 self = GetStatusInfo(hwnd);
397 switch (msg) {
398 case SB_GETBORDERS:
399 return SW_GetBorders(self, hwnd, wParam, lParam);
400 case SB_GETPARTS:
401 return SW_GetParts(self, hwnd, wParam, lParam);
402 case SB_GETRECT:
403 return SW_GetRect(self, hwnd, wParam, lParam);
404 case SB_GETTEXT32A:
405 return SW_GetText(self, hwnd, wParam, lParam);
406 case SB_GETTEXTLENGTH32A:
407 return SW_GetTextLength(self, hwnd, wParam, lParam);
408 case SB_SETMINHEIGHT:
409 return SW_SetMinHeight(self, hwnd, wParam, lParam);
410 case SB_SETPARTS:
411 return SW_SetParts(self, hwnd, wParam, lParam);
412 case SB_SETTEXT32A:
413 return SW_SetText(self, hwnd, wParam, lParam);
414 case SB_SIMPLE:
415 return SW_Simple(self, hwnd, wParam, lParam);
417 case WM_CREATE:
418 return SW_Create(self, hwnd, wParam, lParam);
419 case WM_DESTROY:
420 return SW_Destroy(self, hwnd, wParam, lParam);
421 case WM_PAINT:
422 return SW_Paint(self, hwnd);
423 case WM_SIZE:
424 return SW_Size(self, hwnd, wParam, lParam);
425 default:
426 return DefWindowProc32A(hwnd, msg, wParam, lParam);
428 return 0;