Release 980628
[wine] / controls / status.c
1 /*
2  * Interface code to StatusWindow widget/control
3  *
4  * Copyright 1996 Bruce Milner
5  * Copyright 1998 Eric Kohl
6  */
7
8 #include "windows.h"
9 #include "status.h"
10 #include "commctrl.h"
11 #include "heap.h"
12 #include "win.h"
13
14 /*
15  * Run tests using Waite Group Windows95 API Bible Vol. 1&2
16  * The second cdrom contains executables drawstat.exe,gettext.exe,
17  * simple.exe, getparts.exe, setparts.exe, statwnd.exe
18  */
19
20 /*
21  * Fixme/Todo
22  * 1) Don't hard code bar to bottom of window, allow CCS_TOP also.
23  + 2) Tooltip support.
24  */
25
26 #define _MAX(a,b) (((a)>(b))?(a):(b))
27 #define _MIN(a,b) (((a)>(b))?(b):(a))
28
29 #define HORZ_BORDER 0
30 #define VERT_BORDER 2
31 #define HORZ_GAP    2
32
33
34 static STATUSWINDOWINFO *GetStatusInfo(HWND32 hwnd)
35 {
36     WND *wndPtr;
37
38     wndPtr = WIN_FindWndPtr(hwnd);
39     return ((STATUSWINDOWINFO *) wndPtr->wExtra[0]);
40 }
41
42
43 static void
44 STATUS_DrawSizeGrip (HDC32 hdc, LPRECT32 lpRect)
45 {
46     HPEN32 hOldPen;
47     POINT32 pt;
48     INT32 i;
49
50     pt.x = lpRect->right - 1;
51     pt.y = lpRect->bottom - 1;
52
53     hOldPen = SelectObject32 (hdc, GetSysColorPen32 (COLOR_3DFACE));
54     MoveToEx32 (hdc, pt.x - 12, pt.y, NULL);
55     LineTo32 (hdc, pt.x, pt.y);
56     LineTo32 (hdc, pt.x, pt.y - 12);
57
58     pt.x--;
59     pt.y--;
60
61     SelectObject32 (hdc, GetSysColorPen32 (COLOR_3DSHADOW));
62     for (i = 1; i < 11; i += 4) {
63         MoveToEx32 (hdc, pt.x - i, pt.y, NULL);
64         LineTo32 (hdc, pt.x, pt.y - i);
65
66         MoveToEx32 (hdc, pt.x - i-1, pt.y, NULL);
67         LineTo32 (hdc, pt.x, pt.y - i-1);
68     }
69
70     SelectObject32 (hdc, GetSysColorPen32 (COLOR_3DHIGHLIGHT));
71     for (i = 3; i < 13; i += 4) {
72         MoveToEx32 (hdc, pt.x - i, pt.y, NULL);
73         LineTo32 (hdc, pt.x, pt.y - i);
74     }
75
76     SelectObject32 (hdc, hOldPen);
77 }
78
79
80 static void 
81 SB_DrawPart( HDC32 hdc, LPRECT32 lprc, HICON32 hIcon,
82              LPCSTR text, UINT32 style )
83 {
84     RECT32 r = *lprc;
85     UINT32 border = BDR_SUNKENOUTER;
86
87     if (style==SBT_POPOUT)
88       border = BDR_RAISEDOUTER;
89     else if (style==SBT_NOBORDERS)
90       border = 0;
91
92     DrawEdge32(hdc, &r, border, BF_RECT|BF_ADJUST);
93
94     /* draw the icon */
95     if (hIcon) {
96         INT32 cy = r.bottom - r.top;
97
98         r.left += 2;
99         DrawIconEx32 (hdc, r.left, r.top, hIcon, cy, cy, 0, 0, DI_NORMAL);
100         r.left += cy;
101     }
102
103     /* now draw text */
104     if (text) {
105       int oldbkmode = SetBkMode32(hdc, TRANSPARENT);
106       LPSTR p = (LPSTR)text;
107       UINT32 align = DT_LEFT;
108       if (*p == '\t') {
109         p++;
110         align = DT_CENTER;
111
112         if (*p == '\t') {
113           p++;
114           align = DT_RIGHT;
115         }
116       }
117       r.left += 3;
118       DrawText32A(hdc, p, lstrlen32A(p), &r, align|DT_VCENTER|DT_SINGLELINE);
119       if (oldbkmode != TRANSPARENT)
120         SetBkMode32(hdc, oldbkmode);
121     }
122 }
123
124
125 static BOOL32
126 SW_Refresh( HWND32 hwnd, HDC32 hdc, STATUSWINDOWINFO *self )
127 {
128     int      i;
129     RECT32   rect;
130     HBRUSH32 hbrBk;
131     HFONT32 hOldFont;
132     WND *wndPtr;
133
134     wndPtr = WIN_FindWndPtr(hwnd);
135
136     if (!IsWindowVisible32(hwnd)) {
137         return (TRUE);
138     }
139
140     GetClientRect32 (hwnd, &rect);
141
142     if (self->clrBk != CLR_DEFAULT)
143         hbrBk = CreateSolidBrush32 (self->clrBk);
144     else
145         hbrBk = GetSysColorBrush32 (COLOR_3DFACE);
146     FillRect32(hdc, &rect, hbrBk);
147
148     hOldFont = SelectObject32 (hdc, self->hFont ? self->hFont : self->hDefaultFont);
149
150     if (self->simple) {
151         SB_DrawPart (hdc,
152                      &self->part0.bound,
153                      self->part0.hIcon,
154                      self->part0.text,
155                      self->part0.style);
156     }
157     else {
158         for (i = 0; i < self->numParts; i++) {
159             if (self->parts[i].style == SBT_OWNERDRAW) {
160                 DRAWITEMSTRUCT32 dis;
161                 WND *wndPtr = WIN_FindWndPtr(hwnd);
162
163                 dis.CtlID = wndPtr->wIDmenu;
164                 dis.itemID = -1;
165                 dis.hwndItem = hwnd;
166                 dis.hDC = hdc;
167                 dis.rcItem = self->part0.bound;
168                 dis.itemData = (INT32)self->part0.text;
169                 SendMessage32A (GetParent32 (hwnd), WM_DRAWITEM, 
170                                 (WPARAM32)wndPtr->wIDmenu, (LPARAM)&dis);
171             }
172             else
173                 SB_DrawPart (hdc,
174                              &self->parts[i].bound,
175                              self->parts[i].hIcon,
176                              self->parts[i].text,
177                              self->parts[i].style);
178         }
179     }
180
181     SelectObject32 (hdc, hOldFont);
182
183     if (self->clrBk != CLR_DEFAULT)
184         DeleteObject32 (hbrBk);
185
186     if (wndPtr->dwStyle & SBARS_SIZEGRIP)
187         STATUS_DrawSizeGrip (hdc, &rect);
188
189     return TRUE;
190 }
191
192
193 static LRESULT
194 SW_GetBorders(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
195 {
196     LPINT32     out;
197
198     out = (LPINT32) lParam;
199     out[0] = HORZ_BORDER; /* horizontal border width */
200     out[1] = VERT_BORDER; /* vertical border width */
201     out[2] = HORZ_GAP; /* width of border between rectangles */
202     return TRUE;
203 }
204
205 static void
206 SW_SetPartBounds(HWND32 hwnd, STATUSWINDOWINFO *self)
207 {
208     int i;
209     RECT32      rect, *r;
210     STATUSWINDOWPART *part;
211
212     /* get our window size */
213     GetClientRect32(hwnd, &rect);
214
215     rect.top += VERT_BORDER;
216
217     /* set bounds for simple rectangle */
218     self->part0.bound = rect;
219
220     /* set bounds for non-simple rectangles */
221     for (i = 0; i < self->numParts; i++) {
222         part = &self->parts[i];
223         r = &self->parts[i].bound;
224         r->top = rect.top;
225         r->bottom = rect.bottom;
226         if (i == 0)
227             r->left = 0;
228         else
229             r->left = self->parts[i-1].bound.right + HORZ_GAP;
230         if (part->x == -1)
231             r->right = rect.right;
232         else
233             r->right = part->x;
234     }
235 }
236
237 static LRESULT
238 SW_SetText(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
239 {
240     int part_num;
241     int style;
242     LPSTR       text;
243     int len;
244     STATUSWINDOWPART *part;
245
246     text = (LPSTR) lParam;
247     part_num = ((INT32) wParam) & 0x00ff;
248     style = ((INT32) wParam) & 0xff00;
249
250     if ((self->simple) || (self->parts==NULL) || (part_num==255))
251         part = &self->part0;
252     else
253         part = &self->parts[part_num];
254     if (!part) return FALSE;
255     part->style = style;
256     if (style == SBT_OWNERDRAW) {
257         part->text = text;
258     }
259     else {
260         /* duplicate string */
261         if (part->text)
262             HeapFree(SystemHeap, 0, part->text);
263         part->text = 0;
264         if (text && (len = lstrlen32A(text))) {
265             part->text = HeapAlloc(SystemHeap, 0, len+1);
266             lstrcpy32A(part->text, text);
267         }
268     }
269     InvalidateRect32(hwnd, &part->bound, FALSE);
270 //    SW_RefreshPart (hdc, part);
271     return TRUE;
272 }
273
274 static LRESULT
275 SW_SetParts(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
276 {
277     HDC32       hdc;
278     LPINT32 parts;
279     STATUSWINDOWPART *  tmp;
280     int i;
281     int oldNumParts;
282
283     if (self->simple) {
284         self->simple = FALSE;
285     }
286     oldNumParts = self->numParts;
287     self->numParts = (INT32) wParam;
288     parts = (LPINT32) lParam;
289     if (oldNumParts > self->numParts) {
290         for (i = self->numParts ; i < oldNumParts; i++) {
291             if (self->parts[i].text && (self->parts[i].style != SBT_OWNERDRAW))
292                 HeapFree(SystemHeap, 0, self->parts[i].text);
293         }
294     }
295     else if (oldNumParts < self->numParts) {
296         tmp = HeapAlloc(SystemHeap, HEAP_ZERO_MEMORY,
297                         sizeof(STATUSWINDOWPART) * self->numParts);
298         for (i = 0; i < oldNumParts; i++) {
299             tmp[i] = self->parts[i];
300         }
301         if (self->parts)
302             HeapFree(SystemHeap, 0, self->parts);
303         self->parts = tmp;
304     }
305     
306     for (i = 0; i < self->numParts; i++) {
307         self->parts[i].x = parts[i];
308     }
309     SW_SetPartBounds(hwnd, self);
310
311     hdc = GetDC32(hwnd);
312     SW_Refresh(hwnd, hdc, self);
313     ReleaseDC32(hwnd, hdc);
314     return TRUE;
315 }
316
317 static LRESULT
318 SW_GetParts(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
319 {
320     LPINT32 parts;
321     INT32       num_parts;
322     int i;
323
324     self = GetStatusInfo(hwnd);
325     num_parts = (INT32) wParam;
326     parts = (LPINT32) lParam;
327     if (parts) {
328         return (self->numParts);
329         for (i = 0; i < num_parts; i++) {
330             parts[i] = self->parts[i].x;
331         }
332     }
333     return (self->numParts);
334 }
335
336 static LRESULT
337 SW_Create(HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
338 {
339     LPCREATESTRUCT32A lpCreate = (LPCREATESTRUCT32A) lParam;
340     NONCLIENTMETRICS32A nclm;
341     RECT32      rect;
342     int         width, len;
343     HDC32       hdc;
344     HWND32      parent;
345     WND *wndPtr;
346     STATUSWINDOWINFO *self;
347
348     wndPtr = WIN_FindWndPtr(hwnd);
349     self = (STATUSWINDOWINFO*)HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
350                                          sizeof(STATUSWINDOWINFO));
351     wndPtr->wExtra[0] = (DWORD)self;
352
353     self->numParts = 1;
354     self->parts = 0;
355     self->simple = FALSE;
356     self->clrBk = CLR_DEFAULT;
357     self->hFont = 0;
358     GetClientRect32(hwnd, &rect);
359
360     nclm.cbSize = sizeof(NONCLIENTMETRICS32A);
361     SystemParametersInfo32A (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
362     self->hDefaultFont = CreateFontIndirect32A (&nclm.lfStatusFont);
363
364     /* initialize simple case */
365     self->part0.bound = rect;
366     self->part0.text = 0;
367     self->part0.x = 0;
368     self->part0.style = 0;
369     self->part0.hIcon = 0;
370
371     /* initialize first part */
372     self->parts = HeapAlloc (SystemHeap, HEAP_ZERO_MEMORY,
373                              sizeof(STATUSWINDOWPART));
374     self->parts[0].bound = rect;
375     self->parts[0].text = 0;
376     self->parts[0].x = -1;
377     self->parts[0].style = 0;
378     self->parts[0].hIcon = 0;
379
380     if ((len = lstrlen32A (lpCreate->lpszName))) {
381         self->parts[0].text = HeapAlloc (SystemHeap, 0, len + 1);
382         lstrcpy32A (self->parts[0].text, lpCreate->lpszName);
383     }
384
385     if ((hdc = GetDC32 (0))) {
386         TEXTMETRIC32A tm;
387         HFONT32 hOldFont;
388
389         hOldFont = SelectObject32 (hdc,self->hDefaultFont);
390         GetTextMetrics32A(hdc, &tm);
391         self->textHeight = tm.tmHeight;
392         SelectObject32 (hdc, hOldFont);
393         ReleaseDC32(0, hdc);
394     }
395
396     parent = GetParent32 (hwnd);
397     GetClientRect32 (parent, &rect);
398     width = rect.right - rect.left;
399     self->height = self->textHeight + 4 + VERT_BORDER;
400     MoveWindow32 (hwnd, lpCreate->x, lpCreate->y-1, width, self->height, FALSE);
401     SW_SetPartBounds (hwnd, self);
402     return 0;
403 }
404
405 static LRESULT
406 SW_GetRect(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
407 {
408     int part_num;
409     LPRECT32  rect;
410
411     part_num = ((INT32) wParam) & 0x00ff;
412     rect = (LPRECT32) lParam;
413     if (self->simple)
414         *rect = self->part0.bound;
415     else
416         *rect = self->parts[part_num].bound;
417     return TRUE;
418 }
419
420 static LRESULT
421 SW_GetText(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
422 {
423     int part_num;
424     LRESULT     result;
425     STATUSWINDOWPART *part;
426     LPSTR       out_text;
427
428     part_num = ((INT32) wParam) & 0x00ff;
429     out_text = (LPSTR) lParam;
430     if (self->simple)
431         part = &self->part0;
432     else
433         part = &self->parts[part_num];
434
435     if (part->style == SBT_OWNERDRAW)
436         result = (LRESULT) part->text;
437     else {
438         result = part->text ? lstrlen32A(part->text) : 0;
439         result |= (part->style << 16);
440         if (out_text) {
441             lstrcpy32A(out_text, part->text);
442         }
443     }
444     return result;
445 }
446
447 static LRESULT
448 SW_GetTextLength(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
449 {
450     int part_num;
451     STATUSWINDOWPART *part;
452     DWORD       result;
453
454     part_num = ((INT32) wParam) & 0x00ff;
455
456     if (self->simple)
457         part = &self->part0;
458     else
459         part = &self->parts[part_num];
460
461     if (part->text)
462         result = lstrlen32A(part->text);
463     else
464         result = 0;
465
466     result |= (part->style << 16);
467     return result;
468 }
469
470 static LRESULT
471 SW_SetMinHeight(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
472 {
473     INT32       width, x, y;
474     RECT32      parent_rect;
475     HWND32      parent;
476
477     if (IsWindowVisible32 (hwnd)) {
478         parent = GetParent32(hwnd);
479         GetClientRect32(parent, &parent_rect);
480         self->height = (INT32)wParam + VERT_BORDER;
481         width = parent_rect.right - parent_rect.left;
482         x = parent_rect.left;
483         y = parent_rect.bottom - self->height;
484         MoveWindow32(hwnd, parent_rect.left, parent_rect.bottom - self->height,
485                      width, self->height, TRUE);
486         SW_SetPartBounds(hwnd, self);
487     }
488
489     return TRUE;
490 }
491
492 static LRESULT
493 SW_SetBkColor(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
494 {
495     COLORREF oldBkColor;
496     HDC32    hdc;
497
498     oldBkColor = self->clrBk;
499     self->clrBk = (COLORREF)lParam;
500     hdc = GetDC32(hwnd);
501     SW_Refresh(hwnd, hdc, self);
502     ReleaseDC32(hwnd, hdc);
503     return oldBkColor;
504 }
505
506
507 static LRESULT
508 SW_SetIcon (STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
509 {
510     INT32  nPart = (INT32)wParam & 0x00ff;
511
512     if ((nPart < -1) || (nPart >= self->numParts)) return FALSE;
513
514     if (nPart == -1) {
515         self->part0.hIcon = (HICON32)lParam;
516         if (self->simple) 
517             InvalidateRect32(hwnd, &self->part0.bound, FALSE);
518     }
519     else {
520         self->parts[nPart].hIcon = (HICON32)lParam;
521         if (!(self->simple))
522             InvalidateRect32(hwnd, &self->parts[nPart].bound, FALSE);
523     }
524     return TRUE;
525 }
526
527 static LRESULT
528 SW_GetIcon(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
529 {
530     INT32    nPart;
531
532     nPart = (INT32)wParam & 0x00ff;
533     if ((nPart < -1) || (nPart >= self->numParts)) return 0;
534
535     if (nPart == -1)
536         return (self->part0.hIcon);
537     else
538         return (self->parts[nPart].hIcon);
539 }
540
541 static LRESULT
542 SW_Simple(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
543 {
544     WND *wndPtr;
545     BOOL32 simple;
546     HDC32  hdc;
547     NMHDR  nmhdr;
548
549     wndPtr = WIN_FindWndPtr(hwnd);
550
551     simple = (BOOL32) wParam;
552     self->simple = simple;
553
554     /* send notification */
555     nmhdr.hwndFrom = hwnd;
556     nmhdr.idFrom = wndPtr->wIDmenu;
557     nmhdr.code = SBN_SIMPLEMODECHANGE;
558     SendMessage32A (GetParent32 (hwnd), WM_NOTIFY, 0, (LPARAM)&nmhdr);
559
560     hdc = GetDC32(hwnd);
561     SW_Refresh(hwnd, hdc, self);
562     ReleaseDC32(hwnd, hdc);
563
564     return TRUE;
565 }
566
567
568 static LRESULT
569 SW_Destroy(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
570 {
571     int i;
572
573     for (i = 0; i < self->numParts; i++) {
574         if (self->parts[i].text && (self->parts[i].style != SBT_OWNERDRAW))
575             HeapFree(SystemHeap, 0, self->parts[i].text);
576     }
577     if (self->part0.text && (self->part0.style != SBT_OWNERDRAW))
578         HeapFree(SystemHeap, 0, self->part0.text);
579     HeapFree(SystemHeap, 0, self->parts);
580
581     /* delete default font */
582     if (self->hDefaultFont)
583         DeleteObject32 (self->hDefaultFont);
584
585     HeapFree(SystemHeap, 0, self);
586     return 0;
587 }
588
589
590 static LRESULT
591 SW_WMGetText (STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
592 {
593     INT32 len;
594
595     if (!(self->parts[0].text))
596         return 0;
597     len = lstrlen32A (self->parts[0].text);
598     if (wParam > len) {
599         lstrcpy32A ((LPSTR)lParam, self->parts[0].text);
600         return len;
601     }
602     else
603         return -1;
604 }
605
606
607 static LRESULT
608 SW_WMGetTextLength (STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
609 {
610     if (!(self->parts[0].text))
611         return 0;
612     return (lstrlen32A (self->parts[0].text));
613 }
614
615
616 static LRESULT
617 SW_NcHitTest (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
618 {
619     RECT32  rect;
620     POINT32 pt;
621
622     if (wndPtr->dwStyle & SBARS_SIZEGRIP) {
623         GetClientRect32 (wndPtr->hwndSelf, &rect);
624
625         pt.x = (INT32)LOWORD(lParam);
626         pt.y = (INT32)HIWORD(lParam);
627         ScreenToClient32 (wndPtr->hwndSelf, &pt);
628
629         rect.left = rect.right - 13;
630         rect.top += 2;
631
632         if (PtInRect32 (&rect, pt))
633             return HTBOTTOMRIGHT;
634     }
635
636     return DefWindowProc32A (wndPtr->hwndSelf, WM_NCHITTEST, wParam, lParam);
637 }
638
639
640 static LRESULT
641 SW_NcLButtonDown (HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
642 {
643     PostMessage32A (GetParent32 (hwnd), WM_NCLBUTTONDOWN,
644                     wParam, lParam);
645     return 0;
646 }
647
648
649 static LRESULT
650 SW_NcLButtonUp (HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
651 {
652     PostMessage32A (GetParent32 (hwnd), WM_NCLBUTTONUP,
653                     wParam, lParam);
654     return 0;
655 }
656
657
658 static LRESULT
659 SW_Paint(STATUSWINDOWINFO *self, HWND32 hwnd)
660 {
661     HDC32 hdc;
662     PAINTSTRUCT32       ps;
663
664     hdc = BeginPaint32(hwnd, &ps);
665     SW_Refresh(hwnd, hdc, self);
666     EndPaint32(hwnd, &ps);
667     return 0;
668 }
669
670
671 static LRESULT
672 SW_WMSetFont (STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
673 {
674     HDC32 hdc;
675
676     self->hFont = (HFONT32)wParam;
677     if (LOWORD(lParam) == TRUE) {
678         hdc = GetDC32(hwnd);
679         SW_Refresh(hwnd, hdc, self);
680         ReleaseDC32(hwnd, hdc);
681     }
682     return 0;
683 }
684
685
686 static LRESULT
687 SW_WMSetText (STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
688 {
689     int len;
690     STATUSWINDOWPART *part;
691
692     if (self->numParts == 0) return FALSE;
693
694     part = &self->parts[0];
695     /* duplicate string */
696     if (part->text)
697         HeapFree(SystemHeap, 0, part->text);
698     part->text = 0;
699     if (lParam && (len = lstrlen32A((LPCSTR)lParam))) {
700         part->text = HeapAlloc (SystemHeap, 0, len+1);
701         lstrcpy32A (part->text, (LPCSTR)lParam);
702     }
703     InvalidateRect32(hwnd, &part->bound, FALSE);
704 //    SW_RefreshPart (hdc, part);
705
706     return TRUE;
707 }
708
709
710 static LRESULT
711 SW_Size(STATUSWINDOWINFO *self, HWND32 hwnd, WPARAM32 wParam, LPARAM lParam)
712 {
713     /* Need to resize width to match parent */
714     INT32       width, x, y;
715     RECT32      parent_rect;
716     HWND32      parent;
717
718     INT32       flags;
719
720     flags = (INT32) wParam;
721
722     /* FIXME for flags =
723      * SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED, SIZE_RESTORED
724      */
725
726     if (flags == SIZE_RESTORED) {
727         /* width and height don't apply */
728         parent = GetParent32(hwnd);
729         GetClientRect32(parent, &parent_rect);
730         width = parent_rect.right - parent_rect.left;
731         x = parent_rect.left;
732         y = parent_rect.bottom - self->height;
733         MoveWindow32(hwnd, parent_rect.left, parent_rect.bottom - self->height,
734                      width, self->height, TRUE);
735         SW_SetPartBounds(hwnd, self);
736     }
737     return 0;
738 }
739
740
741 static LRESULT
742 SW_SendNotify (HWND32 hwnd, UINT32 code)
743 {
744     WND    *wndPtr;
745     NMHDR  nmhdr;
746
747     wndPtr = WIN_FindWndPtr(hwnd);
748     nmhdr.hwndFrom = hwnd;
749     nmhdr.idFrom = wndPtr->wIDmenu;
750     nmhdr.code = code;
751     SendMessage32A (GetParent32 (hwnd), WM_NOTIFY, 0, (LPARAM)&nmhdr);
752
753     return 0;
754 }
755
756
757
758 LRESULT WINAPI
759 StatusWindowProc (HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
760 {
761     STATUSWINDOWINFO *self;
762     WND *wndPtr;
763
764     wndPtr = WIN_FindWndPtr(hwnd);
765     self = GetStatusInfo(hwnd);
766
767     switch (msg) {
768     case SB_GETBORDERS:
769         return SW_GetBorders(self, hwnd, wParam, lParam);
770     case SB_GETICON:
771         return SW_GetIcon(self, hwnd, wParam, lParam);
772     case SB_GETPARTS:
773         return SW_GetParts(self, hwnd, wParam, lParam);
774     case SB_GETRECT:
775         return SW_GetRect(self, hwnd, wParam, lParam);
776     case SB_GETTEXT32A:
777         return SW_GetText(self, hwnd, wParam, lParam);
778     case SB_GETTEXTLENGTH32A:
779         return SW_GetTextLength(self, hwnd, wParam, lParam);
780     case SB_ISSIMPLE:
781         return self->simple;
782     case SB_SETBKCOLOR:
783         return SW_SetBkColor(self, hwnd, wParam, lParam);
784     case SB_SETICON:
785         return SW_SetIcon(self, hwnd, wParam, lParam);
786     case SB_SETMINHEIGHT:
787         return SW_SetMinHeight(self, hwnd, wParam, lParam);
788     case SB_SETPARTS:   
789         return SW_SetParts(self, hwnd, wParam, lParam);
790     case SB_SETTEXT32A:
791         return SW_SetText(self, hwnd, wParam, lParam);
792     case SB_SIMPLE:
793         return SW_Simple(self, hwnd, wParam, lParam);
794
795     case WM_CREATE:
796         return SW_Create(hwnd, wParam, lParam);
797     case WM_DESTROY:
798         return SW_Destroy(self, hwnd, wParam, lParam);
799     case WM_GETFONT:
800         return self->hFont;
801     case WM_GETTEXT:
802         return SW_WMGetText(self, hwnd, wParam, lParam);
803     case WM_GETTEXTLENGTH:
804         return SW_WMGetTextLength(self, hwnd, wParam, lParam);
805
806     case WM_LBUTTONDBLCLK:
807         return SW_SendNotify (hwnd, NM_DBLCLK);
808
809     case WM_LBUTTONUP:
810         return SW_SendNotify (hwnd, NM_CLICK);
811
812     case WM_NCHITTEST:
813         return SW_NcHitTest (wndPtr, wParam, lParam);
814
815     case WM_NCLBUTTONDOWN:
816         return SW_NcLButtonDown (hwnd, wParam, lParam);
817
818     case WM_NCLBUTTONUP:
819         return SW_NcLButtonUp (hwnd, wParam, lParam);
820
821     case WM_PAINT:
822         return SW_Paint(self, hwnd);
823     case WM_RBUTTONDBLCLK:
824         return SW_SendNotify (hwnd, NM_RDBLCLK);
825     case WM_RBUTTONUP:
826         return SW_SendNotify (hwnd, NM_RCLICK);
827     case WM_SETFONT:
828         return SW_WMSetFont(self, hwnd, wParam, lParam);
829     case WM_SETTEXT:
830         return SW_WMSetText(self, hwnd, wParam, lParam);
831     case WM_SIZE:
832         return SW_Size(self, hwnd, wParam, lParam);
833     default:
834         return DefWindowProc32A (hwnd, msg, wParam, lParam);
835     }
836     return 0;
837 }
838
839
840 /***********************************************************************
841  * STATUS_Register [Internal]
842  *
843  * Registers the status window class.
844  */
845 void STATUS_Register (void)
846 {
847     WNDCLASS32A wndClass;
848
849     if (GlobalFindAtom32A (STATUSCLASSNAME32A)) return;
850
851     ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
852     wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW;
853     wndClass.lpfnWndProc   = (WNDPROC32)StatusWindowProc;
854     wndClass.cbClsExtra    = 0;
855     wndClass.cbWndExtra    = sizeof(STATUSWINDOWINFO *);
856     wndClass.hCursor       = LoadCursor32A (0, IDC_ARROW32A);
857     wndClass.hbrBackground = (HBRUSH32)(COLOR_3DFACE + 1);
858     wndClass.lpszClassName = STATUSCLASSNAME32A;
859  
860     RegisterClass32A (&wndClass);
861 }
862