Protect against use of comctl32 private control memory after it has
[wine] / dlls / comctl32 / rebar.c
1 /*
2  * Rebar control
3  *
4  * Copyright 1998, 1999 Eric Kohl
5  *
6  * NOTES
7  *   An author is needed! Any volunteers?
8  *   I will only improve this control once in a while.
9  *     Eric <ekohl@abo.rhein-zeitung.de>
10  *
11  * TODO:
12  *   - vertical placement
13  *   - ComboBox and ComboBoxEx placement
14  *   - center image 
15  *   - Layout code.
16  *   - Display code.
17  *   - Some messages.
18  *   - All notifications.
19  */
20
21 #include <string.h>
22
23 #include "winbase.h"
24 #include "wingdi.h"
25 #include "commctrl.h"
26 #include "rebar.h"
27 #include "debugtools.h"
28
29 DEFAULT_DEBUG_CHANNEL(rebar)
30
31
32 /* fDraw flags */
33 #define DRAW_GRIPPER    1
34 #define DRAW_IMAGE      2
35 #define DRAW_TEXT       4
36 #define DRAW_CHILD      8
37
38 #define GRIPPER_WIDTH   13
39
40
41 #define REBAR_GetInfoPtr(wndPtr) ((REBAR_INFO *)GetWindowLongA (hwnd, 0))
42
43
44 static VOID
45 REBAR_DrawBand (HDC hdc, REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
46 {
47
48     DrawEdge (hdc, &lpBand->rcBand, BDR_RAISEDINNER, BF_MIDDLE);
49
50     /* draw background */
51
52     /* draw gripper */
53     if (lpBand->fDraw & DRAW_GRIPPER)
54         DrawEdge (hdc, &lpBand->rcGripper, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE);
55
56     /* draw caption image */
57     if (lpBand->fDraw & DRAW_IMAGE) {
58         /* FIXME: center image */
59         POINT pt;
60
61         pt.y = (lpBand->rcCapImage.bottom + lpBand->rcCapImage.top - infoPtr->imageSize.cy)/2;
62         pt.x = (lpBand->rcCapImage.right + lpBand->rcCapImage.left - infoPtr->imageSize.cx)/2;
63
64         ImageList_Draw (infoPtr->himl, lpBand->iImage, hdc,
65 /*                      lpBand->rcCapImage.left, lpBand->rcCapImage.top, */
66                         pt.x, pt.y,
67                         ILD_TRANSPARENT);
68     }
69
70     /* draw caption text */
71     if (lpBand->fDraw & DRAW_TEXT) {
72         HFONT hOldFont = SelectObject (hdc, infoPtr->hFont);
73         INT oldBkMode = SetBkMode (hdc, TRANSPARENT);
74         DrawTextW (hdc, lpBand->lpText, -1, &lpBand->rcCapText,
75                      DT_CENTER | DT_VCENTER | DT_SINGLELINE);
76         if (oldBkMode != TRANSPARENT)
77             SetBkMode (hdc, oldBkMode);
78         SelectObject (hdc, hOldFont);
79     }
80 }
81
82
83 static VOID
84 REBAR_Refresh (HWND hwnd, HDC hdc)
85 {
86     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
87     REBAR_BAND *lpBand;
88     UINT i;
89
90     for (i = 0; i < infoPtr->uNumBands; i++) {
91         lpBand = &infoPtr->bands[i];
92
93         if ((lpBand->fStyle & RBBS_HIDDEN) || 
94             ((GetWindowLongA (hwnd, GWL_STYLE) & CCS_VERT) &&
95              (lpBand->fStyle & RBBS_NOVERT)))
96             continue;
97
98         REBAR_DrawBand (hdc, infoPtr, lpBand);
99
100     }
101 }
102
103
104 static VOID
105 REBAR_CalcHorzBand (REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
106 {
107     lpBand->fDraw = 0;
108
109     /* set initial caption image rectangle */
110     SetRect (&lpBand->rcCapImage, 0, 0, 0, 0);
111
112     /* image is visible */
113     if ((lpBand->iImage > -1) && (infoPtr->himl)) {
114         lpBand->fDraw |= DRAW_IMAGE;
115
116         lpBand->rcCapImage.right  = lpBand->rcCapImage.left + infoPtr->imageSize.cx;
117         lpBand->rcCapImage.bottom = lpBand->rcCapImage.top + infoPtr->imageSize.cy;
118
119         /* update band height */
120         if (lpBand->uMinHeight < infoPtr->imageSize.cy + 2) {
121             lpBand->uMinHeight = infoPtr->imageSize.cy + 2;
122             lpBand->rcBand.bottom = lpBand->rcBand.top + lpBand->uMinHeight;
123         }
124     }
125
126     /* set initial caption text rectangle */
127     lpBand->rcCapText.left   = lpBand->rcCapImage.right;
128     lpBand->rcCapText.top    = lpBand->rcBand.top + 1;
129     lpBand->rcCapText.right  = lpBand->rcCapText.left;
130     lpBand->rcCapText.bottom = lpBand->rcBand.bottom - 1;
131
132     /* text is visible */
133     if (lpBand->lpText) {
134         HDC hdc = GetDC (0);
135         HFONT hOldFont = SelectObject (hdc, infoPtr->hFont);
136         SIZE size;
137
138         lpBand->fDraw |= DRAW_TEXT;
139         GetTextExtentPoint32W (hdc, lpBand->lpText,
140                                lstrlenW (lpBand->lpText), &size);
141         lpBand->rcCapText.right += size.cx;
142
143         SelectObject (hdc, hOldFont);
144         ReleaseDC (0, hdc);
145     }
146
147     /* set initial child window rectangle */
148     if (lpBand->fStyle & RBBS_FIXEDSIZE) {
149         lpBand->rcChild.left   = lpBand->rcCapText.right;
150         lpBand->rcChild.top    = lpBand->rcBand.top;
151         lpBand->rcChild.right  = lpBand->rcBand.right;
152         lpBand->rcChild.bottom = lpBand->rcBand.bottom;
153     }
154     else {
155         lpBand->rcChild.left   = lpBand->rcCapText.right + 4;
156         lpBand->rcChild.top    = lpBand->rcBand.top + 2;
157         lpBand->rcChild.right  = lpBand->rcBand.right - 4;
158         lpBand->rcChild.bottom = lpBand->rcBand.bottom - 2;
159     }
160
161     /* calculate gripper rectangle */
162     if ((!(lpBand->fStyle & RBBS_NOGRIPPER)) &&
163         (!(lpBand->fStyle & RBBS_FIXEDSIZE)) &&
164         ((lpBand->fStyle & RBBS_GRIPPERALWAYS) || 
165          (infoPtr->uNumBands > 1))) {
166         lpBand->fDraw |= DRAW_GRIPPER;
167         lpBand->rcGripper.left   = lpBand->rcBand.left + 3;
168         lpBand->rcGripper.right  = lpBand->rcGripper.left + 3;
169         lpBand->rcGripper.top    = lpBand->rcBand.top + 3;
170         lpBand->rcGripper.bottom = lpBand->rcBand.bottom - 3;
171
172         /* move caption rectangles */
173         OffsetRect (&lpBand->rcCapImage, GRIPPER_WIDTH, 0);
174         OffsetRect (&lpBand->rcCapText, GRIPPER_WIDTH, 0);
175
176         /* adjust child rectangle */
177         lpBand->rcChild.left += GRIPPER_WIDTH;
178     }
179
180
181 }
182
183
184 static VOID
185 REBAR_CalcVertBand (HWND hwnd, REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
186 {
187     lpBand->fDraw = 0;
188
189     /* set initial caption image rectangle */
190     SetRect (&lpBand->rcCapImage, 0, 0, 0, 0);
191
192     /* image is visible */
193     if ((lpBand->iImage > -1) && (infoPtr->himl)) {
194         lpBand->fDraw |= DRAW_IMAGE;
195
196         lpBand->rcCapImage.right  = lpBand->rcCapImage.left + infoPtr->imageSize.cx;
197         lpBand->rcCapImage.bottom = lpBand->rcCapImage.top + infoPtr->imageSize.cy;
198
199         /* update band width */
200         if (lpBand->uMinHeight < infoPtr->imageSize.cx + 2) {
201             lpBand->uMinHeight = infoPtr->imageSize.cx + 2;
202             lpBand->rcBand.right = lpBand->rcBand.left + lpBand->uMinHeight;
203         }
204     }
205
206     /* set initial caption text rectangle */
207     lpBand->rcCapText.left   = lpBand->rcBand.left + 1;
208     lpBand->rcCapText.top    = lpBand->rcCapImage.bottom;
209     lpBand->rcCapText.right  = lpBand->rcBand.right - 1;
210     lpBand->rcCapText.bottom = lpBand->rcCapText.top;
211
212     /* text is visible */
213     if (lpBand->lpText) {
214         HDC hdc = GetDC (0);
215         HFONT hOldFont = SelectObject (hdc, infoPtr->hFont);
216         SIZE size;
217
218         lpBand->fDraw |= DRAW_TEXT;
219         GetTextExtentPoint32W (hdc, lpBand->lpText,
220                                lstrlenW (lpBand->lpText), &size);
221 /*      lpBand->rcCapText.right += size.cx; */
222         lpBand->rcCapText.bottom += size.cy;
223
224         SelectObject (hdc, hOldFont);
225         ReleaseDC (0, hdc);
226     }
227
228     /* set initial child window rectangle */
229     if (lpBand->fStyle & RBBS_FIXEDSIZE) {
230         lpBand->rcChild.left   = lpBand->rcBand.left;
231         lpBand->rcChild.top    = lpBand->rcCapText.bottom;
232         lpBand->rcChild.right  = lpBand->rcBand.right;
233         lpBand->rcChild.bottom = lpBand->rcBand.bottom;
234     }
235     else {
236         lpBand->rcChild.left   = lpBand->rcBand.left + 2;
237         lpBand->rcChild.top    = lpBand->rcCapText.bottom + 4;
238         lpBand->rcChild.right  = lpBand->rcBand.right - 2;
239         lpBand->rcChild.bottom = lpBand->rcBand.bottom - 4;
240     }
241
242     /* calculate gripper rectangle */
243     if ((!(lpBand->fStyle & RBBS_NOGRIPPER)) &&
244         (!(lpBand->fStyle & RBBS_FIXEDSIZE)) &&
245         ((lpBand->fStyle & RBBS_GRIPPERALWAYS) || 
246          (infoPtr->uNumBands > 1))) {
247         lpBand->fDraw |= DRAW_GRIPPER;
248
249         if (GetWindowLongA (hwnd, GWL_STYLE) & RBS_VERTICALGRIPPER) {
250             /* adjust band width */
251             lpBand->rcBand.right += GRIPPER_WIDTH;
252             lpBand->uMinHeight += GRIPPER_WIDTH;
253
254             lpBand->rcGripper.left   = lpBand->rcBand.left + 3;
255             lpBand->rcGripper.right  = lpBand->rcGripper.left + 3;
256             lpBand->rcGripper.top    = lpBand->rcBand.top + 3;
257             lpBand->rcGripper.bottom = lpBand->rcBand.bottom - 3;
258
259             /* move caption rectangles */
260             OffsetRect (&lpBand->rcCapImage, GRIPPER_WIDTH, 0);
261             OffsetRect (&lpBand->rcCapText, GRIPPER_WIDTH, 0);
262  
263             /* adjust child rectangle */
264             lpBand->rcChild.left += GRIPPER_WIDTH;
265         }
266         else {
267             lpBand->rcGripper.left   = lpBand->rcBand.left + 3;
268             lpBand->rcGripper.right  = lpBand->rcBand.right - 3;
269             lpBand->rcGripper.top    = lpBand->rcBand.top + 3;
270             lpBand->rcGripper.bottom = lpBand->rcGripper.top + 3;
271
272             /* move caption rectangles */
273             OffsetRect (&lpBand->rcCapImage, 0, GRIPPER_WIDTH);
274             OffsetRect (&lpBand->rcCapText, 0, GRIPPER_WIDTH);
275  
276             /* adjust child rectangle */
277             lpBand->rcChild.top += GRIPPER_WIDTH;
278         }
279     }
280 }
281
282
283 static VOID
284 REBAR_Layout (HWND hwnd, LPRECT lpRect)
285 {
286     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
287     DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
288     REBAR_BAND *lpBand;
289     RECT rcClient;
290     INT x, y, cx, cy;
291     UINT i;
292
293     if (lpRect)
294         rcClient = *lpRect;
295     else
296         GetClientRect (hwnd, &rcClient);
297
298     x = 0;
299     y = 0;
300
301     if (dwStyle & CCS_VERT) {
302         cx = 20;    /* FIXME: fixed height */
303         cy = rcClient.bottom - rcClient.top;
304     }
305     else {
306         cx = rcClient.right - rcClient.left;
307         cy = 20;    /* FIXME: fixed height */
308     }
309
310     for (i = 0; i < infoPtr->uNumBands; i++) {
311         lpBand = &infoPtr->bands[i];
312
313         if ((lpBand->fStyle & RBBS_HIDDEN) || 
314             ((dwStyle & CCS_VERT) && (lpBand->fStyle & RBBS_NOVERT)))
315             continue;
316
317
318         if (dwStyle & CCS_VERT) {
319             if (lpBand->fStyle & RBBS_VARIABLEHEIGHT)
320                 cx = lpBand->cyMaxChild;
321             else if (lpBand->fStyle & RBBIM_CHILDSIZE)
322                 cx = lpBand->cyMinChild;
323             else
324                 cx = 20; /* FIXME */
325
326             lpBand->rcBand.left   = x;
327             lpBand->rcBand.right  = x + cx;
328             lpBand->rcBand.top    = y;
329             lpBand->rcBand.bottom = y + cy;
330             lpBand->uMinHeight = cx;
331         }
332         else {
333             if (lpBand->fStyle & RBBS_VARIABLEHEIGHT)
334                 cy = lpBand->cyMaxChild;
335             else if (lpBand->fStyle & RBBIM_CHILDSIZE)
336                 cy = lpBand->cyMinChild;
337             else
338                 cy = 20; /* FIXME */
339
340             lpBand->rcBand.left   = x;
341             lpBand->rcBand.right  = x + cx;
342             lpBand->rcBand.top    = y;
343             lpBand->rcBand.bottom = y + cy;
344             lpBand->uMinHeight = cy;
345         }
346
347         if (dwStyle & CCS_VERT) {
348             REBAR_CalcVertBand (hwnd, infoPtr, lpBand);
349             x += lpBand->uMinHeight;
350         }
351         else {
352             REBAR_CalcHorzBand (infoPtr, lpBand);
353             y += lpBand->uMinHeight;
354         }
355     }
356
357     if (dwStyle & CCS_VERT) {
358         infoPtr->calcSize.cx = x;
359         infoPtr->calcSize.cy = rcClient.bottom - rcClient.top;
360     }
361     else {
362         infoPtr->calcSize.cx = rcClient.right - rcClient.left;
363         infoPtr->calcSize.cy = y;
364     }
365 }
366
367
368 static VOID
369 REBAR_ForceResize (HWND hwnd)
370 {
371     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
372     RECT rc;
373
374     TRACE(" to [%d x %d]!\n",
375            infoPtr->calcSize.cx, infoPtr->calcSize.cy);
376
377     infoPtr->bAutoResize = TRUE;
378
379     rc.left = 0;
380     rc.top = 0;
381     rc.right  = infoPtr->calcSize.cx;
382     rc.bottom = infoPtr->calcSize.cy;
383
384     if (GetWindowLongA (hwnd, GWL_STYLE) & WS_BORDER) {
385         InflateRect (&rc, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
386     }
387
388     SetWindowPos (hwnd, 0, 0, 0,
389                     rc.right - rc.left, rc.bottom - rc.top,
390                     SWP_NOMOVE | SWP_NOZORDER | SWP_SHOWWINDOW);
391 }
392
393
394 static VOID
395 REBAR_MoveChildWindows (HWND hwnd)
396 {
397     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
398     REBAR_BAND *lpBand;
399     CHAR szClassName[40];
400     UINT i;
401
402     for (i = 0; i < infoPtr->uNumBands; i++) {
403         lpBand = &infoPtr->bands[i];
404
405         if (lpBand->fStyle & RBBS_HIDDEN)
406             continue;
407         if (lpBand->hwndChild) {
408             TRACE("hwndChild = %x\n", lpBand->hwndChild);
409
410             GetClassNameA (lpBand->hwndChild, szClassName, 40);
411             if (!lstrcmpA (szClassName, "ComboBox")) {
412                 INT nEditHeight, yPos;
413                 RECT rc;
414
415                 /* special placement code for combo box */
416
417
418                 /* get size of edit line */
419                 GetWindowRect (lpBand->hwndChild, &rc);
420                 nEditHeight = rc.bottom - rc.top;
421                 yPos = (lpBand->rcChild.bottom + lpBand->rcChild.top - nEditHeight)/2;
422
423                 /* center combo box inside child area */
424                 SetWindowPos (lpBand->hwndChild, HWND_TOP,
425                             lpBand->rcChild.left, /*lpBand->rcChild.top*/ yPos,
426                             lpBand->rcChild.right - lpBand->rcChild.left,
427                             nEditHeight,
428                             SWP_SHOWWINDOW);
429             }
430 #if 0
431             else if (!lstrcmpA (szClassName, WC_COMBOBOXEXA)) {
432                 INT nEditHeight, yPos;
433                 RECT rc;
434                 HWND hwndEdit;
435
436                 /* special placement code for extended combo box */
437
438                 /* get size of edit line */
439                 hwndEdit = SendMessageA (lpBand->hwndChild, CBEM_GETEDITCONTROL, 0, 0);
440                 GetWindowRect (hwndEdit, &rc);
441                 nEditHeight = rc.bottom - rc.top;
442                 yPos = (lpBand->rcChild.bottom + lpBand->rcChild.top - nEditHeight)/2;
443
444                 /* center combo box inside child area */
445                 SetWindowPos (lpBand->hwndChild, HWND_TOP,
446                             lpBand->rcChild.left, /*lpBand->rcChild.top*/ yPos,
447                             lpBand->rcChild.right - lpBand->rcChild.left,
448                             nEditHeight,
449                             SWP_SHOWWINDOW);
450
451             }
452 #endif
453             else {
454                 SetWindowPos (lpBand->hwndChild, HWND_TOP,
455                             lpBand->rcChild.left, lpBand->rcChild.top,
456                             lpBand->rcChild.right - lpBand->rcChild.left,
457                             lpBand->rcChild.bottom - lpBand->rcChild.top,
458                             SWP_SHOWWINDOW);
459             }
460         }
461     }
462 }
463
464
465 static void
466 REBAR_InternalHitTest (HWND hwnd, LPPOINT lpPt, UINT *pFlags, INT *pBand)
467 {
468     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
469     REBAR_BAND *lpBand;
470     RECT rect;
471     INT  iCount;
472
473     GetClientRect (hwnd, &rect);
474
475     *pFlags = RBHT_NOWHERE;
476     if (PtInRect (&rect, *lpPt))
477     {
478         if (infoPtr->uNumBands == 0) {
479             *pFlags = RBHT_NOWHERE;
480             if (pBand)
481                 *pBand = -1;
482             TRACE("NOWHERE\n");
483             return;
484         }
485         else {
486             /* somewhere inside */
487             for (iCount = 0; iCount < infoPtr->uNumBands; iCount++) {
488                 lpBand = &infoPtr->bands[iCount];
489                 if (PtInRect (&lpBand->rcBand, *lpPt)) {
490                     if (pBand)
491                         *pBand = iCount;
492                     if (PtInRect (&lpBand->rcGripper, *lpPt)) {
493                         *pFlags = RBHT_GRABBER;
494                         TRACE("ON GRABBER %d\n", iCount);
495                         return;
496                     }
497                     else if (PtInRect (&lpBand->rcCapImage, *lpPt)) {
498                         *pFlags = RBHT_CAPTION;
499                         TRACE("ON CAPTION %d\n", iCount);
500                         return;
501                     }
502                     else if (PtInRect (&lpBand->rcCapText, *lpPt)) {
503                         *pFlags = RBHT_CAPTION;
504                         TRACE("ON CAPTION %d\n", iCount);
505                         return;
506                     }
507                     else if (PtInRect (&lpBand->rcChild, *lpPt)) {
508                         *pFlags = RBHT_CLIENT;
509                         TRACE("ON CLIENT %d\n", iCount);
510                         return;
511                     }
512                     else {
513                         *pFlags = RBHT_NOWHERE;
514                         TRACE("NOWHERE %d\n", iCount);
515                         return;
516                     }
517                 }
518             }
519
520             *pFlags = RBHT_NOWHERE;
521             if (pBand)
522                 *pBand = -1;
523
524             TRACE("NOWHERE\n");
525             return;
526         }
527     }
528     else {
529         *pFlags = RBHT_NOWHERE;
530         if (pBand)
531             *pBand = -1;
532         TRACE("NOWHERE\n");
533         return;
534     }
535
536     TRACE("flags=0x%X\n", *pFlags);
537     return;
538 }
539
540
541
542 /* << REBAR_BeginDrag >> */
543
544
545 static LRESULT
546 REBAR_DeleteBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
547 {
548     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
549     UINT uBand = (UINT)wParam;
550
551     if (uBand >= infoPtr->uNumBands)
552         return FALSE;
553
554     TRACE("deleting band %u!\n", uBand);
555
556     if (infoPtr->uNumBands == 1) {
557         TRACE(" simple delete!\n");
558         COMCTL32_Free (infoPtr->bands);
559         infoPtr->bands = NULL;
560         infoPtr->uNumBands = 0;
561     }
562     else {
563         REBAR_BAND *oldBands = infoPtr->bands;
564         TRACE("complex delete! [uBand=%u]\n", uBand);
565
566         infoPtr->uNumBands--;
567         infoPtr->bands = COMCTL32_Alloc (sizeof (REBAR_BAND) * infoPtr->uNumBands);
568         if (uBand > 0) {
569             memcpy (&infoPtr->bands[0], &oldBands[0],
570                     uBand * sizeof(REBAR_BAND));
571         }
572
573         if (uBand < infoPtr->uNumBands) {
574             memcpy (&infoPtr->bands[uBand], &oldBands[uBand+1],
575                     (infoPtr->uNumBands - uBand) * sizeof(REBAR_BAND));
576         }
577
578         COMCTL32_Free (oldBands);
579     }
580
581     REBAR_Layout (hwnd, NULL);
582     REBAR_ForceResize (hwnd);
583     REBAR_MoveChildWindows (hwnd);
584
585     return TRUE;
586 }
587
588
589 /* << REBAR_DragMove >> */
590 /* << REBAR_EndDrag >> */
591
592
593 static LRESULT
594 REBAR_GetBandBorders (HWND hwnd, WPARAM wParam, LPARAM lParam)
595 {
596     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
597     /* LPRECT32 lpRect = (LPRECT32)lParam; */
598     REBAR_BAND *lpBand;
599
600     if (!lParam)
601         return 0;
602     if ((UINT)wParam >= infoPtr->uNumBands)
603         return 0;
604
605     lpBand = &infoPtr->bands[(UINT)wParam];
606     if (GetWindowLongA (hwnd, GWL_STYLE) & RBS_BANDBORDERS) {
607
608     }
609     else {
610
611     }
612
613     return 0;
614 }
615
616
617 inline static LRESULT
618 REBAR_GetBandCount (HWND hwnd)
619 {
620     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
621
622     TRACE("band count %u!\n", infoPtr->uNumBands);
623
624     return infoPtr->uNumBands;
625 }
626
627
628 static LRESULT
629 REBAR_GetBandInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
630 {
631     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
632     LPREBARBANDINFOA lprbbi = (LPREBARBANDINFOA)lParam;
633     REBAR_BAND *lpBand;
634
635     if (lprbbi == NULL)
636         return FALSE;
637     if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEA)
638         return FALSE;
639     if ((UINT)wParam >= infoPtr->uNumBands)
640         return FALSE;
641
642     TRACE("index %u\n", (UINT)wParam);
643
644     /* copy band information */
645     lpBand = &infoPtr->bands[(UINT)wParam];
646
647     if (lprbbi->fMask & RBBIM_STYLE)
648         lprbbi->fStyle = lpBand->fStyle;
649
650     if (lprbbi->fMask & RBBIM_COLORS) {
651         lprbbi->clrFore = lpBand->clrFore;
652         lprbbi->clrBack = lpBand->clrBack;
653     }
654
655     if ((lprbbi->fMask & RBBIM_TEXT) && 
656         (lprbbi->lpText) && (lpBand->lpText)) {
657             lstrcpynWtoA (lprbbi->lpText, lpBand->lpText, lprbbi->cch);
658     }
659
660     if (lprbbi->fMask & RBBIM_IMAGE)
661         lprbbi->iImage = lpBand->iImage;
662
663     if (lprbbi->fMask & RBBIM_CHILD)
664         lprbbi->hwndChild = lpBand->hwndChild;
665
666     if (lprbbi->fMask & RBBIM_CHILDSIZE) {
667         lprbbi->cxMinChild = lpBand->cxMinChild;
668         lprbbi->cyMinChild = lpBand->cyMinChild;
669         lprbbi->cyMaxChild = lpBand->cyMaxChild;
670         lprbbi->cyChild    = lpBand->cyChild;
671         lprbbi->cyIntegral = lpBand->cyIntegral;
672     }
673
674     if (lprbbi->fMask & RBBIM_SIZE)
675         lprbbi->cx = lpBand->cx;
676
677     if (lprbbi->fMask & RBBIM_BACKGROUND)
678         lprbbi->hbmBack = lpBand->hbmBack;
679
680     if (lprbbi->fMask & RBBIM_ID)
681         lprbbi->wID = lpBand->wID;
682
683     /* check for additional data */
684     if (lprbbi->cbSize >= sizeof (REBARBANDINFOA)) {
685         if (lprbbi->fMask & RBBIM_IDEALSIZE)
686             lprbbi->cxIdeal = lpBand->cxIdeal;
687
688         if (lprbbi->fMask & RBBIM_LPARAM)
689             lprbbi->lParam = lpBand->lParam;
690
691         if (lprbbi->fMask & RBBIM_HEADERSIZE)
692             lprbbi->cxHeader = lpBand->cxHeader;
693     }
694
695     return TRUE;
696 }
697
698
699 static LRESULT
700 REBAR_GetBandInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
701 {
702     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
703     LPREBARBANDINFOW lprbbi = (LPREBARBANDINFOW)lParam;
704     REBAR_BAND *lpBand;
705
706     if (lprbbi == NULL)
707         return FALSE;
708     if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEW)
709         return FALSE;
710     if ((UINT)wParam >= infoPtr->uNumBands)
711         return FALSE;
712
713     TRACE("index %u\n", (UINT)wParam);
714
715     /* copy band information */
716     lpBand = &infoPtr->bands[(UINT)wParam];
717
718     if (lprbbi->fMask & RBBIM_STYLE)
719         lprbbi->fStyle = lpBand->fStyle;
720
721     if (lprbbi->fMask & RBBIM_COLORS) {
722         lprbbi->clrFore = lpBand->clrFore;
723         lprbbi->clrBack = lpBand->clrBack;
724     }
725
726     if ((lprbbi->fMask & RBBIM_TEXT) && 
727         (lprbbi->lpText) && (lpBand->lpText)) {
728             lstrcpynW (lprbbi->lpText, lpBand->lpText, lprbbi->cch);
729     }
730
731     if (lprbbi->fMask & RBBIM_IMAGE)
732         lprbbi->iImage = lpBand->iImage;
733
734     if (lprbbi->fMask & RBBIM_CHILD)
735         lprbbi->hwndChild = lpBand->hwndChild;
736
737     if (lprbbi->fMask & RBBIM_CHILDSIZE) {
738         lprbbi->cxMinChild = lpBand->cxMinChild;
739         lprbbi->cyMinChild = lpBand->cyMinChild;
740         lprbbi->cyMaxChild = lpBand->cyMaxChild;
741         lprbbi->cyChild    = lpBand->cyChild;
742         lprbbi->cyIntegral = lpBand->cyIntegral;
743     }
744
745     if (lprbbi->fMask & RBBIM_SIZE)
746         lprbbi->cx = lpBand->cx;
747
748     if (lprbbi->fMask & RBBIM_BACKGROUND)
749         lprbbi->hbmBack = lpBand->hbmBack;
750
751     if (lprbbi->fMask & RBBIM_ID)
752         lprbbi->wID = lpBand->wID;
753
754     /* check for additional data */
755     if (lprbbi->cbSize >= sizeof (REBARBANDINFOA)) {
756         if (lprbbi->fMask & RBBIM_IDEALSIZE)
757             lprbbi->cxIdeal = lpBand->cxIdeal;
758
759         if (lprbbi->fMask & RBBIM_LPARAM)
760             lprbbi->lParam = lpBand->lParam;
761
762         if (lprbbi->fMask & RBBIM_HEADERSIZE)
763             lprbbi->cxHeader = lpBand->cxHeader;
764     }
765
766     return TRUE;
767 }
768
769
770 static LRESULT
771 REBAR_GetBarHeight (HWND hwnd, WPARAM wParam, LPARAM lParam)
772 {
773     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
774     INT nHeight;
775
776     REBAR_Layout (hwnd, NULL);
777     nHeight = infoPtr->calcSize.cy;
778
779     if (GetWindowLongA (hwnd, GWL_STYLE) & WS_BORDER)
780         nHeight += (2 * GetSystemMetrics(SM_CYEDGE));
781
782
783     FIXME("height = %d\n", nHeight);
784
785     return nHeight;
786 }
787
788
789 static LRESULT
790 REBAR_GetBarInfo (HWND hwnd, WPARAM wParam, LPARAM lParam)
791 {
792     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
793     LPREBARINFO lpInfo = (LPREBARINFO)lParam;
794
795     if (lpInfo == NULL)
796         return FALSE;
797
798     if (lpInfo->cbSize < sizeof (REBARINFO))
799         return FALSE;
800
801     TRACE("getting bar info!\n");
802
803     if (infoPtr->himl) {
804         lpInfo->himl = infoPtr->himl;
805         lpInfo->fMask |= RBIM_IMAGELIST;
806     }
807
808     return TRUE;
809 }
810
811
812 inline static LRESULT
813 REBAR_GetBkColor (HWND hwnd)
814 {
815     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
816
817     TRACE("background color 0x%06lx!\n", infoPtr->clrBk);
818
819     return infoPtr->clrBk;
820 }
821
822
823 /* << REBAR_GetColorScheme >> */
824 /* << REBAR_GetDropTarget >> */
825
826
827 static LRESULT
828 REBAR_GetPalette (HWND hwnd, WPARAM wParam, LPARAM lParam)
829 {
830     FIXME("empty stub!\n");
831
832     return 0;
833 }
834
835
836 static LRESULT
837 REBAR_GetRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
838 {
839     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
840     INT iBand = (INT)wParam;
841     LPRECT lprc = (LPRECT)lParam;
842     REBAR_BAND *lpBand;
843
844     if ((iBand < 0) && ((UINT)iBand >= infoPtr->uNumBands))
845         return FALSE;
846     if (!lprc)
847         return FALSE;
848
849     TRACE("band %d\n", iBand);
850
851     lpBand = &infoPtr->bands[iBand];
852     CopyRect (lprc, &lpBand->rcBand);
853 /*
854     lprc->left   = lpBand->rcBand.left;
855     lprc->top    = lpBand->rcBand.top;
856     lprc->right  = lpBand->rcBand.right;
857     lprc->bottom = lpBand->rcBand.bottom;
858 */
859
860     return TRUE;
861 }
862
863
864 inline static LRESULT
865 REBAR_GetRowCount (HWND hwnd)
866 {
867     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
868
869     FIXME("%u : semi stub!\n", infoPtr->uNumBands);
870
871     return infoPtr->uNumBands;
872 }
873
874
875 static LRESULT
876 REBAR_GetRowHeight (HWND hwnd, WPARAM wParam, LPARAM lParam)
877 {
878 /*    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */
879
880     FIXME("-- height = 20: semi stub!\n");
881
882     return 20;
883 }
884
885
886 inline static LRESULT
887 REBAR_GetTextColor (HWND hwnd)
888 {
889     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
890
891     TRACE("text color 0x%06lx!\n", infoPtr->clrText);
892
893     return infoPtr->clrText;
894 }
895
896
897 inline static LRESULT
898 REBAR_GetToolTips (HWND hwnd)
899 {
900     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
901     return infoPtr->hwndToolTip;
902 }
903
904
905 inline static LRESULT
906 REBAR_GetUnicodeFormat (HWND hwnd)
907 {
908     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
909     return infoPtr->bUnicode;
910 }
911
912
913 inline static LRESULT
914 REBAR_GetVersion (HWND hwnd)
915 {
916     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
917     return infoPtr->iVersion;
918 }
919
920
921 static LRESULT
922 REBAR_HitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
923 {
924     /* REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */
925     LPRBHITTESTINFO lprbht = (LPRBHITTESTINFO)lParam; 
926
927     if (!lprbht)
928         return -1;
929
930     REBAR_InternalHitTest (hwnd, &lprbht->pt, &lprbht->flags, &lprbht->iBand);
931
932     return lprbht->iBand;
933 }
934
935
936 static LRESULT
937 REBAR_IdToIndex (HWND hwnd, WPARAM wParam, LPARAM lParam)
938 {
939     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
940     UINT i;
941
942     if (infoPtr == NULL)
943         return -1;
944
945     if (infoPtr->uNumBands < 1)
946         return -1;
947
948     TRACE("id %u\n", (UINT)wParam);
949
950     for (i = 0; i < infoPtr->uNumBands; i++) {
951         if (infoPtr->bands[i].wID == (UINT)wParam) {
952             TRACE("band %u found!\n", i);
953             return i;
954         }
955     }
956
957     TRACE("no band found!\n");
958     return -1;
959 }
960
961
962 static LRESULT
963 REBAR_InsertBandA (HWND hwnd, WPARAM wParam, LPARAM lParam)
964 {
965     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
966     LPREBARBANDINFOA lprbbi = (LPREBARBANDINFOA)lParam;
967     UINT uIndex = (UINT)wParam;
968     REBAR_BAND *lpBand;
969
970     if (infoPtr == NULL)
971         return FALSE;
972     if (lprbbi == NULL)
973         return FALSE;
974     if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEA)
975         return FALSE;
976
977     TRACE("insert band at %u!\n", uIndex);
978
979     if (infoPtr->uNumBands == 0) {
980         infoPtr->bands = (REBAR_BAND *)COMCTL32_Alloc (sizeof (REBAR_BAND));
981         uIndex = 0;
982     }
983     else {
984         REBAR_BAND *oldBands = infoPtr->bands;
985         infoPtr->bands =
986             (REBAR_BAND *)COMCTL32_Alloc ((infoPtr->uNumBands+1)*sizeof(REBAR_BAND));
987         if (((INT)uIndex == -1) || (uIndex > infoPtr->uNumBands))
988             uIndex = infoPtr->uNumBands;
989
990         /* pre insert copy */
991         if (uIndex > 0) {
992             memcpy (&infoPtr->bands[0], &oldBands[0],
993                     uIndex * sizeof(REBAR_BAND));
994         }
995
996         /* post copy */
997         if (uIndex < infoPtr->uNumBands - 1) {
998             memcpy (&infoPtr->bands[uIndex+1], &oldBands[uIndex],
999                     (infoPtr->uNumBands - uIndex - 1) * sizeof(REBAR_BAND));
1000         }
1001
1002         COMCTL32_Free (oldBands);
1003     }
1004
1005     infoPtr->uNumBands++;
1006
1007     TRACE("index %u!\n", uIndex);
1008
1009     /* initialize band (infoPtr->bands[uIndex])*/
1010     lpBand = &infoPtr->bands[uIndex];
1011
1012     if (lprbbi->fMask & RBBIM_STYLE)
1013         lpBand->fStyle = lprbbi->fStyle;
1014
1015     if (lprbbi->fMask & RBBIM_COLORS) {
1016         lpBand->clrFore = lprbbi->clrFore;
1017         lpBand->clrBack = lprbbi->clrBack;
1018     }
1019     else {
1020         lpBand->clrFore = CLR_NONE;
1021         lpBand->clrBack = CLR_NONE;
1022     }
1023
1024     if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) {
1025         INT len = lstrlenA (lprbbi->lpText);
1026         if (len > 0) {
1027             lpBand->lpText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
1028             lstrcpyAtoW (lpBand->lpText, lprbbi->lpText);
1029         }
1030     }
1031
1032     if (lprbbi->fMask & RBBIM_IMAGE)
1033         lpBand->iImage = lprbbi->iImage;
1034     else
1035         lpBand->iImage = -1;
1036
1037     if (lprbbi->fMask & RBBIM_CHILD) {
1038         TRACE("hwndChild = %x\n", lprbbi->hwndChild);
1039         lpBand->hwndChild = lprbbi->hwndChild;
1040         lpBand->hwndPrevParent =
1041             SetParent (lpBand->hwndChild, hwnd);
1042     }
1043
1044     if (lprbbi->fMask & RBBIM_CHILDSIZE) {
1045         lpBand->cxMinChild = lprbbi->cxMinChild;
1046         lpBand->cyMinChild = lprbbi->cyMinChild;
1047         lpBand->cyMaxChild = lprbbi->cyMaxChild;
1048         lpBand->cyChild    = lprbbi->cyChild;
1049         lpBand->cyIntegral = lprbbi->cyIntegral;
1050     }
1051     else {
1052         lpBand->cxMinChild = -1;
1053         lpBand->cyMinChild = -1;
1054         lpBand->cyMaxChild = -1;
1055         lpBand->cyChild    = -1;
1056         lpBand->cyIntegral = -1;
1057     }
1058
1059     if (lprbbi->fMask & RBBIM_SIZE)
1060         lpBand->cx = lprbbi->cx;
1061     else
1062         lpBand->cx = -1;
1063
1064     if (lprbbi->fMask & RBBIM_BACKGROUND)
1065         lpBand->hbmBack = lprbbi->hbmBack;
1066
1067     if (lprbbi->fMask & RBBIM_ID)
1068         lpBand->wID = lprbbi->wID;
1069
1070     /* check for additional data */
1071     if (lprbbi->cbSize >= sizeof (REBARBANDINFOA)) {
1072         if (lprbbi->fMask & RBBIM_IDEALSIZE)
1073             lpBand->cxIdeal = lprbbi->cxIdeal;
1074
1075         if (lprbbi->fMask & RBBIM_LPARAM)
1076             lpBand->lParam = lprbbi->lParam;
1077
1078         if (lprbbi->fMask & RBBIM_HEADERSIZE)
1079             lpBand->cxHeader = lprbbi->cxHeader;
1080     }
1081
1082
1083     REBAR_Layout (hwnd, NULL);
1084     REBAR_ForceResize (hwnd);
1085     REBAR_MoveChildWindows (hwnd);
1086
1087     return TRUE;
1088 }
1089
1090
1091 static LRESULT
1092 REBAR_InsertBandW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1093 {
1094     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1095     LPREBARBANDINFOW lprbbi = (LPREBARBANDINFOW)lParam;
1096     UINT uIndex = (UINT)wParam;
1097     REBAR_BAND *lpBand;
1098
1099     if (infoPtr == NULL)
1100         return FALSE;
1101     if (lprbbi == NULL)
1102         return FALSE;
1103     if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEW)
1104         return FALSE;
1105
1106     TRACE("insert band at %u!\n", uIndex);
1107
1108     if (infoPtr->uNumBands == 0) {
1109         infoPtr->bands = (REBAR_BAND *)COMCTL32_Alloc (sizeof (REBAR_BAND));
1110         uIndex = 0;
1111     }
1112     else {
1113         REBAR_BAND *oldBands = infoPtr->bands;
1114         infoPtr->bands =
1115             (REBAR_BAND *)COMCTL32_Alloc ((infoPtr->uNumBands+1)*sizeof(REBAR_BAND));
1116         if (((INT)uIndex == -1) || (uIndex > infoPtr->uNumBands))
1117             uIndex = infoPtr->uNumBands;
1118
1119         /* pre insert copy */
1120         if (uIndex > 0) {
1121             memcpy (&infoPtr->bands[0], &oldBands[0],
1122                     uIndex * sizeof(REBAR_BAND));
1123         }
1124
1125         /* post copy */
1126         if (uIndex < infoPtr->uNumBands - 1) {
1127             memcpy (&infoPtr->bands[uIndex+1], &oldBands[uIndex],
1128                     (infoPtr->uNumBands - uIndex - 1) * sizeof(REBAR_BAND));
1129         }
1130
1131         COMCTL32_Free (oldBands);
1132     }
1133
1134     infoPtr->uNumBands++;
1135
1136     TRACE("index %u!\n", uIndex);
1137
1138     /* initialize band (infoPtr->bands[uIndex])*/
1139     lpBand = &infoPtr->bands[uIndex];
1140
1141     if (lprbbi->fMask & RBBIM_STYLE)
1142         lpBand->fStyle = lprbbi->fStyle;
1143
1144     if (lprbbi->fMask & RBBIM_COLORS) {
1145         lpBand->clrFore = lprbbi->clrFore;
1146         lpBand->clrBack = lprbbi->clrBack;
1147     }
1148     else {
1149         lpBand->clrFore = CLR_NONE;
1150         lpBand->clrBack = CLR_NONE;
1151     }
1152
1153     if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) {
1154         INT len = lstrlenW (lprbbi->lpText);
1155         if (len > 0) {
1156             lpBand->lpText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
1157             lstrcpyW (lpBand->lpText, lprbbi->lpText);
1158         }
1159     }
1160
1161     if (lprbbi->fMask & RBBIM_IMAGE)
1162         lpBand->iImage = lprbbi->iImage;
1163     else
1164         lpBand->iImage = -1;
1165
1166     if (lprbbi->fMask & RBBIM_CHILD) {
1167         TRACE("hwndChild = %x\n", lprbbi->hwndChild);
1168         lpBand->hwndChild = lprbbi->hwndChild;
1169         lpBand->hwndPrevParent =
1170             SetParent (lpBand->hwndChild, hwnd);
1171     }
1172
1173     if (lprbbi->fMask & RBBIM_CHILDSIZE) {
1174         lpBand->cxMinChild = lprbbi->cxMinChild;
1175         lpBand->cyMinChild = lprbbi->cyMinChild;
1176         lpBand->cyMaxChild = lprbbi->cyMaxChild;
1177         lpBand->cyChild    = lprbbi->cyChild;
1178         lpBand->cyIntegral = lprbbi->cyIntegral;
1179     }
1180     else {
1181         lpBand->cxMinChild = -1;
1182         lpBand->cyMinChild = -1;
1183         lpBand->cyMaxChild = -1;
1184         lpBand->cyChild    = -1;
1185         lpBand->cyIntegral = -1;
1186     }
1187
1188     if (lprbbi->fMask & RBBIM_SIZE)
1189         lpBand->cx = lprbbi->cx;
1190     else
1191         lpBand->cx = -1;
1192
1193     if (lprbbi->fMask & RBBIM_BACKGROUND)
1194         lpBand->hbmBack = lprbbi->hbmBack;
1195
1196     if (lprbbi->fMask & RBBIM_ID)
1197         lpBand->wID = lprbbi->wID;
1198
1199     /* check for additional data */
1200     if (lprbbi->cbSize >= sizeof (REBARBANDINFOW)) {
1201         if (lprbbi->fMask & RBBIM_IDEALSIZE)
1202             lpBand->cxIdeal = lprbbi->cxIdeal;
1203
1204         if (lprbbi->fMask & RBBIM_LPARAM)
1205             lpBand->lParam = lprbbi->lParam;
1206
1207         if (lprbbi->fMask & RBBIM_HEADERSIZE)
1208             lpBand->cxHeader = lprbbi->cxHeader;
1209     }
1210
1211
1212     REBAR_Layout (hwnd, NULL);
1213     REBAR_ForceResize (hwnd);
1214     REBAR_MoveChildWindows (hwnd);
1215
1216     return TRUE;
1217 }
1218
1219
1220 static LRESULT
1221 REBAR_MaximizeBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
1222 {
1223 /*    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */
1224
1225     FIXME("(uBand = %u fIdeal = %s)\n",
1226            (UINT)wParam, lParam ? "TRUE" : "FALSE");
1227
1228  
1229     return 0;
1230 }
1231
1232
1233 static LRESULT
1234 REBAR_MinimizeBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
1235 {
1236 /*    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */
1237
1238     FIXME("(uBand = %u)\n", (UINT)wParam);
1239
1240  
1241     return 0;
1242 }
1243
1244
1245 static LRESULT
1246 REBAR_MoveBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
1247 {
1248 /*    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */
1249
1250     FIXME("(iFrom = %u iTof = %u)\n",
1251            (UINT)wParam, (UINT)lParam);
1252
1253  
1254     return FALSE;
1255 }
1256
1257
1258 static LRESULT
1259 REBAR_SetBandInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1260 {
1261     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1262     LPREBARBANDINFOA lprbbi = (LPREBARBANDINFOA)lParam;
1263     REBAR_BAND *lpBand;
1264
1265     if (lprbbi == NULL)
1266         return FALSE;
1267     if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEA)
1268         return FALSE;
1269     if ((UINT)wParam >= infoPtr->uNumBands)
1270         return FALSE;
1271
1272     TRACE("index %u\n", (UINT)wParam);
1273
1274     /* set band information */
1275     lpBand = &infoPtr->bands[(UINT)wParam];
1276
1277     if (lprbbi->fMask & RBBIM_STYLE)
1278         lpBand->fStyle = lprbbi->fStyle;
1279
1280     if (lprbbi->fMask & RBBIM_COLORS) {
1281         lpBand->clrFore = lprbbi->clrFore;
1282         lpBand->clrBack = lprbbi->clrBack;
1283     }
1284
1285     if (lprbbi->fMask & RBBIM_TEXT) {
1286         if (lpBand->lpText) {
1287             COMCTL32_Free (lpBand->lpText);
1288             lpBand->lpText = NULL;
1289         }
1290         if (lprbbi->lpText) {
1291             INT len = lstrlenA (lprbbi->lpText);
1292             lpBand->lpText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
1293             lstrcpyAtoW (lpBand->lpText, lprbbi->lpText);
1294         }
1295     }
1296
1297     if (lprbbi->fMask & RBBIM_IMAGE)
1298         lpBand->iImage = lprbbi->iImage;
1299
1300     if (lprbbi->fMask & RBBIM_CHILD) {
1301         if (lprbbi->hwndChild) {
1302             lpBand->hwndChild = lprbbi->hwndChild;
1303             lpBand->hwndPrevParent =
1304                 SetParent (lpBand->hwndChild, hwnd);
1305         }
1306         else {
1307             TRACE("child: 0x%x  prev parent: 0x%x\n",
1308                    lpBand->hwndChild, lpBand->hwndPrevParent);
1309             lpBand->hwndChild = 0;
1310             lpBand->hwndPrevParent = 0;
1311         }
1312     }
1313
1314     if (lprbbi->fMask & RBBIM_CHILDSIZE) {
1315         lpBand->cxMinChild = lprbbi->cxMinChild;
1316         lpBand->cyMinChild = lprbbi->cyMinChild;
1317         lpBand->cyMaxChild = lprbbi->cyMaxChild;
1318         lpBand->cyChild    = lprbbi->cyChild;
1319         lpBand->cyIntegral = lprbbi->cyIntegral;
1320     }
1321
1322     if (lprbbi->fMask & RBBIM_SIZE)
1323         lpBand->cx = lprbbi->cx;
1324
1325     if (lprbbi->fMask & RBBIM_BACKGROUND)
1326         lpBand->hbmBack = lprbbi->hbmBack;
1327
1328     if (lprbbi->fMask & RBBIM_ID)
1329         lpBand->wID = lprbbi->wID;
1330
1331     /* check for additional data */
1332     if (lprbbi->cbSize >= sizeof (REBARBANDINFOA)) {
1333         if (lprbbi->fMask & RBBIM_IDEALSIZE)
1334             lpBand->cxIdeal = lprbbi->cxIdeal;
1335
1336         if (lprbbi->fMask & RBBIM_LPARAM)
1337             lpBand->lParam = lprbbi->lParam;
1338
1339         if (lprbbi->fMask & RBBIM_HEADERSIZE)
1340             lpBand->cxHeader = lprbbi->cxHeader;
1341     }
1342
1343     REBAR_Layout (hwnd, NULL);
1344     REBAR_ForceResize (hwnd);
1345     REBAR_MoveChildWindows (hwnd);
1346
1347     return TRUE;
1348 }
1349
1350
1351 static LRESULT
1352 REBAR_SetBandInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1353 {
1354     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1355     LPREBARBANDINFOW lprbbi = (LPREBARBANDINFOW)lParam;
1356     REBAR_BAND *lpBand;
1357
1358     if (lprbbi == NULL)
1359         return FALSE;
1360     if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEW)
1361         return FALSE;
1362     if ((UINT)wParam >= infoPtr->uNumBands)
1363         return FALSE;
1364
1365     TRACE("index %u\n", (UINT)wParam);
1366
1367     /* set band information */
1368     lpBand = &infoPtr->bands[(UINT)wParam];
1369
1370     if (lprbbi->fMask & RBBIM_STYLE)
1371         lpBand->fStyle = lprbbi->fStyle;
1372
1373     if (lprbbi->fMask & RBBIM_COLORS) {
1374         lpBand->clrFore = lprbbi->clrFore;
1375         lpBand->clrBack = lprbbi->clrBack;
1376     }
1377
1378     if (lprbbi->fMask & RBBIM_TEXT) {
1379         if (lpBand->lpText) {
1380             COMCTL32_Free (lpBand->lpText);
1381             lpBand->lpText = NULL;
1382         }
1383         if (lprbbi->lpText) {
1384             INT len = lstrlenW (lprbbi->lpText);
1385             lpBand->lpText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
1386             lstrcpyW (lpBand->lpText, lprbbi->lpText);
1387         }
1388     }
1389
1390     if (lprbbi->fMask & RBBIM_IMAGE)
1391         lpBand->iImage = lprbbi->iImage;
1392
1393     if (lprbbi->fMask & RBBIM_CHILD) {
1394         if (lprbbi->hwndChild) {
1395             lpBand->hwndChild = lprbbi->hwndChild;
1396             lpBand->hwndPrevParent =
1397                 SetParent (lpBand->hwndChild, hwnd);
1398         }
1399         else {
1400             TRACE("child: 0x%x  prev parent: 0x%x\n",
1401                    lpBand->hwndChild, lpBand->hwndPrevParent);
1402             lpBand->hwndChild = 0;
1403             lpBand->hwndPrevParent = 0;
1404         }
1405     }
1406
1407     if (lprbbi->fMask & RBBIM_CHILDSIZE) {
1408         lpBand->cxMinChild = lprbbi->cxMinChild;
1409         lpBand->cyMinChild = lprbbi->cyMinChild;
1410         lpBand->cyMaxChild = lprbbi->cyMaxChild;
1411         lpBand->cyChild    = lprbbi->cyChild;
1412         lpBand->cyIntegral = lprbbi->cyIntegral;
1413     }
1414
1415     if (lprbbi->fMask & RBBIM_SIZE)
1416         lpBand->cx = lprbbi->cx;
1417
1418     if (lprbbi->fMask & RBBIM_BACKGROUND)
1419         lpBand->hbmBack = lprbbi->hbmBack;
1420
1421     if (lprbbi->fMask & RBBIM_ID)
1422         lpBand->wID = lprbbi->wID;
1423
1424     /* check for additional data */
1425     if (lprbbi->cbSize >= sizeof (REBARBANDINFOW)) {
1426         if (lprbbi->fMask & RBBIM_IDEALSIZE)
1427             lpBand->cxIdeal = lprbbi->cxIdeal;
1428
1429         if (lprbbi->fMask & RBBIM_LPARAM)
1430             lpBand->lParam = lprbbi->lParam;
1431
1432         if (lprbbi->fMask & RBBIM_HEADERSIZE)
1433             lpBand->cxHeader = lprbbi->cxHeader;
1434     }
1435
1436     REBAR_Layout (hwnd, NULL);
1437     REBAR_ForceResize (hwnd);
1438     REBAR_MoveChildWindows (hwnd);
1439
1440     return TRUE;
1441 }
1442
1443
1444 static LRESULT
1445 REBAR_SetBarInfo (HWND hwnd, WPARAM wParam, LPARAM lParam)
1446 {
1447     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1448     LPREBARINFO lpInfo = (LPREBARINFO)lParam;
1449
1450     if (lpInfo == NULL)
1451         return FALSE;
1452
1453     if (lpInfo->cbSize < sizeof (REBARINFO))
1454         return FALSE;
1455
1456     TRACE("setting bar info!\n");
1457
1458     if (lpInfo->fMask & RBIM_IMAGELIST) {
1459         infoPtr->himl = lpInfo->himl;
1460         if (infoPtr->himl) {
1461             ImageList_GetIconSize (infoPtr->himl, &infoPtr->imageSize.cx,
1462                                    &infoPtr->imageSize.cy);
1463         }
1464         else {
1465             infoPtr->imageSize.cx = 0;
1466             infoPtr->imageSize.cy = 0;
1467         }
1468     }
1469
1470     return TRUE;
1471 }
1472
1473
1474 static LRESULT
1475 REBAR_SetBkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
1476 {
1477     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1478     COLORREF clrTemp;
1479
1480     clrTemp = infoPtr->clrBk;
1481     infoPtr->clrBk = (COLORREF)lParam;
1482
1483     TRACE("background color 0x%06lx!\n", infoPtr->clrBk);
1484
1485     return clrTemp;
1486 }
1487
1488
1489 /* << REBAR_SetColorScheme >> */
1490 /* << REBAR_SetPalette >> */
1491
1492
1493 static LRESULT
1494 REBAR_SetParent (HWND hwnd, WPARAM wParam, LPARAM lParam)
1495 {
1496     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1497     HWND hwndTemp = infoPtr->hwndNotify;
1498
1499     infoPtr->hwndNotify = (HWND)wParam;
1500
1501     return (LRESULT)hwndTemp;
1502 }
1503
1504
1505 static LRESULT
1506 REBAR_SetTextColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
1507 {
1508     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1509     COLORREF clrTemp;
1510
1511     clrTemp = infoPtr->clrText;
1512     infoPtr->clrText = (COLORREF)lParam;
1513
1514     TRACE("text color 0x%06lx!\n", infoPtr->clrText);
1515
1516     return clrTemp;
1517 }
1518
1519
1520 /* << REBAR_SetTooltips >> */
1521
1522
1523 inline static LRESULT
1524 REBAR_SetUnicodeFormat (HWND hwnd, WPARAM wParam)
1525 {
1526     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1527     BOOL bTemp = infoPtr->bUnicode;
1528     infoPtr->bUnicode = (BOOL)wParam;
1529     return bTemp;
1530 }
1531
1532
1533 static LRESULT
1534 REBAR_SetVersion (HWND hwnd, INT iVersion)
1535 {
1536     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1537     INT iOldVersion = infoPtr->iVersion;
1538
1539     if (iVersion > COMCTL32_VERSION)
1540         return -1;
1541
1542     infoPtr->iVersion = iVersion;
1543
1544     return iOldVersion;
1545 }
1546
1547
1548 static LRESULT
1549 REBAR_ShowBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
1550 {
1551     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1552     REBAR_BAND *lpBand;
1553
1554     if (((INT)wParam < 0) || ((INT)wParam > infoPtr->uNumBands))
1555         return FALSE;
1556
1557     lpBand = &infoPtr->bands[(INT)wParam];
1558
1559     if ((BOOL)lParam) {
1560         TRACE("show band %d\n", (INT)wParam);
1561         lpBand->fStyle = lpBand->fStyle & ~RBBS_HIDDEN;
1562         if (IsWindow (lpBand->hwndChild))
1563             ShowWindow (lpBand->hwndChild, SW_SHOW);
1564     }
1565     else {
1566         TRACE("hide band %d\n", (INT)wParam);
1567         lpBand->fStyle = lpBand->fStyle | RBBS_HIDDEN;
1568         if (IsWindow (lpBand->hwndChild))
1569             ShowWindow (lpBand->hwndChild, SW_SHOW);
1570     }
1571
1572     REBAR_Layout (hwnd, NULL);
1573     REBAR_ForceResize (hwnd);
1574     REBAR_MoveChildWindows (hwnd);
1575
1576     return TRUE;
1577 }
1578
1579
1580 static LRESULT
1581 REBAR_SizeToRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
1582 {
1583     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1584     LPRECT lpRect = (LPRECT)lParam;
1585
1586     if (lpRect == NULL)
1587         return FALSE;
1588
1589     FIXME("layout change not implemented!\n");
1590     FIXME("[%d %d %d %d]\n",
1591            lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
1592
1593 #if 0
1594     SetWindowPos (hwnd, 0, lpRect->left, lpRect->top,
1595                     lpRect->right - lpRect->left, lpRect->bottom - lpRect->top,
1596                     SWP_NOZORDER);
1597 #endif
1598
1599     infoPtr->calcSize.cx = lpRect->right - lpRect->left;
1600     infoPtr->calcSize.cy = lpRect->bottom - lpRect->top;
1601
1602     REBAR_ForceResize (hwnd);
1603     return TRUE;
1604 }
1605
1606
1607
1608 static LRESULT
1609 REBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
1610 {
1611     REBAR_INFO *infoPtr;
1612
1613     /* allocate memory for info structure */
1614     infoPtr = (REBAR_INFO *)COMCTL32_Alloc (sizeof(REBAR_INFO));
1615     SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
1616
1617     /* initialize info structure */
1618     infoPtr->iVersion = 0;
1619     infoPtr->clrBk = CLR_NONE;
1620     infoPtr->clrText = RGB(0, 0, 0);
1621
1622     infoPtr->bAutoResize = FALSE;
1623     infoPtr->hcurArrow = LoadCursorA (0, IDC_ARROWA);
1624     infoPtr->hcurHorz  = LoadCursorA (0, IDC_SIZEWEA);
1625     infoPtr->hcurVert  = LoadCursorA (0, IDC_SIZENSA);
1626     infoPtr->hcurDrag  = LoadCursorA (0, IDC_SIZEA);
1627
1628     infoPtr->bUnicode = IsWindowUnicode (hwnd);
1629
1630     if (GetWindowLongA (hwnd, GWL_STYLE) & RBS_AUTOSIZE)
1631         FIXME("style RBS_AUTOSIZE set!\n");
1632
1633 #if 0
1634     SendMessageA (hwnd, WM_NOTIFYFORMAT, (WPARAM)hwnd, NF_QUERY);
1635 #endif
1636
1637     TRACE("created!\n");
1638     return 0;
1639 }
1640
1641
1642 static LRESULT
1643 REBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
1644 {
1645     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1646     REBAR_BAND *lpBand;
1647     INT i;
1648
1649
1650     /* free rebar bands */
1651     if ((infoPtr->uNumBands > 0) && infoPtr->bands) {
1652         /* clean up each band */
1653         for (i = 0; i < infoPtr->uNumBands; i++) {
1654             lpBand = &infoPtr->bands[i];
1655
1656             /* delete text strings */
1657             if (lpBand->lpText) {
1658                 COMCTL32_Free (lpBand->lpText);
1659                 lpBand->lpText = NULL;
1660             }
1661             /* destroy child window */
1662             DestroyWindow (lpBand->hwndChild);
1663         }
1664
1665         /* free band array */
1666         COMCTL32_Free (infoPtr->bands);
1667         infoPtr->bands = NULL;
1668     }
1669
1670
1671
1672
1673     DeleteObject (infoPtr->hcurArrow);
1674     DeleteObject (infoPtr->hcurHorz);
1675     DeleteObject (infoPtr->hcurVert);
1676     DeleteObject (infoPtr->hcurDrag);
1677
1678
1679
1680
1681     /* free rebar info data */
1682     COMCTL32_Free (infoPtr);
1683     SetWindowLongA (hwnd, 0, 0);
1684     TRACE("destroyed!\n");
1685     return 0;
1686 }
1687
1688
1689 static LRESULT
1690 REBAR_GetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
1691 {
1692     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1693
1694     return (LRESULT)infoPtr->hFont;
1695 }
1696
1697
1698 #if 0
1699 static LRESULT
1700 REBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
1701 {
1702     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1703
1704     return 0;
1705 }
1706 #endif
1707
1708
1709 inline static LRESULT
1710 REBAR_NCCalcSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1711 {
1712     if (GetWindowLongA (hwnd, GWL_STYLE) & WS_BORDER) {
1713         ((LPRECT)lParam)->left   += GetSystemMetrics(SM_CXEDGE);
1714         ((LPRECT)lParam)->top    += GetSystemMetrics(SM_CYEDGE);
1715         ((LPRECT)lParam)->right  -= GetSystemMetrics(SM_CXEDGE);
1716         ((LPRECT)lParam)->bottom -= GetSystemMetrics(SM_CYEDGE);
1717     }
1718
1719     return 0;
1720 }
1721
1722
1723 static LRESULT
1724 REBAR_NCPaint (HWND hwnd, WPARAM wParam, LPARAM lParam)
1725 {
1726     DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1727     RECT rcWindow;
1728     HDC hdc;
1729
1730     if (dwStyle & WS_MINIMIZE)
1731         return 0; /* Nothing to do */
1732
1733     DefWindowProcA (hwnd, WM_NCPAINT, wParam, lParam);
1734
1735     if (!(hdc = GetDCEx( hwnd, 0, DCX_USESTYLE | DCX_WINDOW )))
1736         return 0;
1737
1738     if (dwStyle & WS_BORDER) {
1739         GetWindowRect (hwnd, &rcWindow);
1740         OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
1741         DrawEdge (hdc, &rcWindow, EDGE_ETCHED, BF_RECT);
1742     }
1743
1744     ReleaseDC( hwnd, hdc );
1745
1746     return 0;
1747 }
1748
1749
1750 static LRESULT
1751 REBAR_Paint (HWND hwnd, WPARAM wParam)
1752 {
1753     HDC hdc;
1754     PAINTSTRUCT ps;
1755
1756     hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
1757     REBAR_Refresh (hwnd, hdc);
1758     if (!wParam)
1759         EndPaint (hwnd, &ps);
1760     return 0;
1761 }
1762
1763
1764 static LRESULT
1765 REBAR_SetCursor (HWND hwnd, WPARAM wParam, LPARAM lParam)
1766 {
1767     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1768     DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1769     POINT pt;
1770     UINT  flags;
1771
1772     TRACE("code=0x%X  id=0x%X\n", LOWORD(lParam), HIWORD(lParam));
1773
1774     GetCursorPos (&pt);
1775     ScreenToClient (hwnd, &pt);
1776
1777     REBAR_InternalHitTest (hwnd, &pt, &flags, NULL);
1778
1779     if (flags == RBHT_GRABBER) {
1780         if ((dwStyle & CCS_VERT) &&
1781             !(dwStyle & RBS_VERTICALGRIPPER))
1782             SetCursor (infoPtr->hcurVert);
1783         else
1784             SetCursor (infoPtr->hcurHorz);
1785     }
1786     else if (flags != RBHT_CLIENT)
1787         SetCursor (infoPtr->hcurArrow);
1788
1789     return 0;
1790 }
1791
1792
1793 static LRESULT
1794 REBAR_SetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
1795 {
1796     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1797     
1798     /* TEXTMETRIC32A tm; */
1799     HFONT hFont /*, hOldFont */;
1800     /* HDC32 hdc; */
1801
1802     infoPtr->hFont = (HFONT)wParam;
1803
1804     hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT);
1805 /*
1806     hdc = GetDC32 (0);
1807     hOldFont = SelectObject32 (hdc, hFont);
1808     GetTextMetrics32A (hdc, &tm);
1809     infoPtr->nHeight = tm.tmHeight + VERT_BORDER;
1810     SelectObject32 (hdc, hOldFont);
1811     ReleaseDC32 (0, hdc);
1812 */
1813     if (lParam) {
1814 /*
1815         REBAR_Layout (hwnd);
1816         hdc = GetDC32 (hwnd);
1817         REBAR_Refresh (hwnd, hdc);
1818         ReleaseDC32 (hwnd, hdc);
1819 */
1820     }
1821
1822     return 0;
1823 }
1824
1825 static LRESULT
1826 REBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
1827 {
1828     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1829     /* DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE); */
1830     RECT rcParent;
1831     /* INT32 x, y, cx, cy; */
1832
1833     /* auto resize deadlock check */
1834     if (infoPtr->bAutoResize) {
1835         infoPtr->bAutoResize = FALSE;
1836         return 0;
1837     }
1838
1839     TRACE("sizing rebar!\n");
1840
1841     /* get parent rectangle */
1842     GetClientRect (GetParent (hwnd), &rcParent);
1843 /*
1844     REBAR_Layout (hwnd, &rcParent);
1845
1846     if (dwStyle & CCS_VERT) {
1847         if (dwStyle & CCS_LEFT == CCS_LEFT) {
1848             x = rcParent.left;
1849             y = rcParent.top;
1850             cx = infoPtr->calcSize.cx;
1851             cy = infoPtr->calcSize.cy;
1852         }
1853         else {
1854             x = rcParent.right - infoPtr->calcSize.cx;
1855             y = rcParent.top;
1856             cx = infoPtr->calcSize.cx;
1857             cy = infoPtr->calcSize.cy;
1858         }
1859     }
1860     else {
1861         if (dwStyle & CCS_TOP) {
1862             x = rcParent.left;
1863             y = rcParent.top;
1864             cx = infoPtr->calcSize.cx;
1865             cy = infoPtr->calcSize.cy;
1866         }
1867         else {
1868             x = rcParent.left;
1869             y = rcParent.bottom - infoPtr->calcSize.cy;
1870             cx = infoPtr->calcSize.cx;
1871             cy = infoPtr->calcSize.cy;
1872         }
1873     }
1874
1875     SetWindowPos32 (hwnd, 0, x, y, cx, cy,
1876                     SWP_NOZORDER | SWP_SHOWWINDOW);
1877 */
1878     REBAR_Layout (hwnd, NULL);
1879     REBAR_ForceResize (hwnd);
1880     REBAR_MoveChildWindows (hwnd);
1881
1882     return 0;
1883 }
1884
1885
1886 static LRESULT WINAPI
1887 REBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1888 {
1889     TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n", hwnd, uMsg, wParam, lParam);
1890     if (!REBAR_GetInfoPtr (hwnd) && (uMsg != WM_CREATE))
1891             return DefWindowProcA (hwnd, uMsg, wParam, lParam);
1892     switch (uMsg)
1893     {
1894 /*      case RB_BEGINDRAG: */
1895
1896         case RB_DELETEBAND:
1897             return REBAR_DeleteBand (hwnd, wParam, lParam);
1898
1899 /*      case RB_DRAGMOVE: */
1900 /*      case RB_ENDDRAG: */
1901
1902         case RB_GETBANDBORDERS:
1903             return REBAR_GetBandBorders (hwnd, wParam, lParam);
1904
1905         case RB_GETBANDCOUNT:
1906             return REBAR_GetBandCount (hwnd);
1907
1908 /*      case RB_GETBANDINFO32:  */ /* outdated, just for compatibility */
1909
1910         case RB_GETBANDINFOA:
1911             return REBAR_GetBandInfoA (hwnd, wParam, lParam);
1912
1913         case RB_GETBANDINFOW:
1914             return REBAR_GetBandInfoW (hwnd, wParam, lParam);
1915
1916         case RB_GETBARHEIGHT:
1917             return REBAR_GetBarHeight (hwnd, wParam, lParam);
1918
1919         case RB_GETBARINFO:
1920             return REBAR_GetBarInfo (hwnd, wParam, lParam);
1921
1922         case RB_GETBKCOLOR:
1923             return REBAR_GetBkColor (hwnd);
1924
1925 /*      case RB_GETCOLORSCHEME: */
1926 /*      case RB_GETDROPTARGET: */
1927
1928         case RB_GETPALETTE:
1929             return REBAR_GetPalette (hwnd, wParam, lParam);
1930
1931         case RB_GETRECT:
1932             return REBAR_GetRect (hwnd, wParam, lParam);
1933
1934         case RB_GETROWCOUNT:
1935             return REBAR_GetRowCount (hwnd);
1936
1937         case RB_GETROWHEIGHT:
1938             return REBAR_GetRowHeight (hwnd, wParam, lParam);
1939
1940         case RB_GETTEXTCOLOR:
1941             return REBAR_GetTextColor (hwnd);
1942
1943         case RB_GETTOOLTIPS:
1944             return REBAR_GetToolTips (hwnd);
1945
1946         case RB_GETUNICODEFORMAT:
1947             return REBAR_GetUnicodeFormat (hwnd);
1948
1949         case CCM_GETVERSION:
1950             return REBAR_GetVersion (hwnd);
1951
1952         case RB_HITTEST:
1953             return REBAR_HitTest (hwnd, wParam, lParam);
1954
1955         case RB_IDTOINDEX:
1956             return REBAR_IdToIndex (hwnd, wParam, lParam);
1957
1958         case RB_INSERTBANDA:
1959             return REBAR_InsertBandA (hwnd, wParam, lParam);
1960
1961         case RB_INSERTBANDW:
1962             return REBAR_InsertBandW (hwnd, wParam, lParam);
1963
1964         case RB_MAXIMIZEBAND:
1965             return REBAR_MaximizeBand (hwnd, wParam, lParam);
1966
1967         case RB_MINIMIZEBAND:
1968             return REBAR_MinimizeBand (hwnd, wParam, lParam);
1969
1970         case RB_MOVEBAND:
1971             return REBAR_MoveBand (hwnd, wParam, lParam);
1972
1973         case RB_SETBANDINFOA:
1974             return REBAR_SetBandInfoA (hwnd, wParam, lParam);
1975
1976         case RB_SETBANDINFOW:
1977             return REBAR_SetBandInfoW (hwnd, wParam, lParam);
1978
1979         case RB_SETBARINFO:
1980             return REBAR_SetBarInfo (hwnd, wParam, lParam);
1981
1982         case RB_SETBKCOLOR:
1983             return REBAR_SetBkColor (hwnd, wParam, lParam);
1984
1985 /*      case RB_SETCOLORSCHEME: */
1986 /*      case RB_SETPALETTE: */
1987 /*          return REBAR_GetPalette (hwnd, wParam, lParam); */
1988
1989         case RB_SETPARENT:
1990             return REBAR_SetParent (hwnd, wParam, lParam);
1991
1992         case RB_SETTEXTCOLOR:
1993             return REBAR_SetTextColor (hwnd, wParam, lParam);
1994
1995 /*      case RB_SETTOOLTIPS: */
1996
1997         case RB_SETUNICODEFORMAT:
1998             return REBAR_SetUnicodeFormat (hwnd, wParam);
1999
2000         case CCM_SETVERSION:
2001             return REBAR_SetVersion (hwnd, (INT)wParam);
2002
2003         case RB_SHOWBAND:
2004             return REBAR_ShowBand (hwnd, wParam, lParam);
2005
2006         case RB_SIZETORECT:
2007             return REBAR_SizeToRect (hwnd, wParam, lParam);
2008
2009
2010         case WM_COMMAND:
2011             return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
2012
2013         case WM_CREATE:
2014             return REBAR_Create (hwnd, wParam, lParam);
2015
2016         case WM_DESTROY:
2017             return REBAR_Destroy (hwnd, wParam, lParam);
2018
2019         case WM_GETFONT:
2020             return REBAR_GetFont (hwnd, wParam, lParam);
2021
2022 /*      case WM_MOUSEMOVE: */
2023 /*          return REBAR_MouseMove (hwnd, wParam, lParam); */
2024
2025         case WM_NCCALCSIZE:
2026             return REBAR_NCCalcSize (hwnd, wParam, lParam);
2027
2028         case WM_NCPAINT:
2029             return REBAR_NCPaint (hwnd, wParam, lParam);
2030
2031         case WM_NOTIFY:
2032             return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
2033
2034         case WM_PAINT:
2035             return REBAR_Paint (hwnd, wParam);
2036
2037         case WM_SETCURSOR:
2038             return REBAR_SetCursor (hwnd, wParam, lParam);
2039
2040         case WM_SETFONT:
2041             return REBAR_SetFont (hwnd, wParam, lParam);
2042
2043         case WM_SIZE:
2044             return REBAR_Size (hwnd, wParam, lParam);
2045
2046 /*      case WM_TIMER: */
2047
2048 /*      case WM_WININICHANGE: */
2049
2050         default:
2051             if (uMsg >= WM_USER)
2052                 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
2053                      uMsg, wParam, lParam);
2054             return DefWindowProcA (hwnd, uMsg, wParam, lParam);
2055     }
2056     return 0;
2057 }
2058
2059
2060 VOID
2061 REBAR_Register (void)
2062 {
2063     WNDCLASSA wndClass;
2064
2065     ZeroMemory (&wndClass, sizeof(WNDCLASSA));
2066     wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS;
2067     wndClass.lpfnWndProc   = (WNDPROC)REBAR_WindowProc;
2068     wndClass.cbClsExtra    = 0;
2069     wndClass.cbWndExtra    = sizeof(REBAR_INFO *);
2070     wndClass.hCursor       = 0;
2071     wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
2072     wndClass.lpszClassName = REBARCLASSNAMEA;
2073  
2074     RegisterClassA (&wndClass);
2075 }
2076
2077
2078 VOID
2079 REBAR_Unregister (void)
2080 {
2081     UnregisterClassA (REBARCLASSNAMEA, (HINSTANCE)NULL);
2082 }
2083