Pass up WM_DRAWITEM messages to parent.
[wine] / dlls / comctl32 / rebar.c
1 /*
2  * Rebar control    rev 4a
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  * Changes Guy Albertelli <galberte@neo.lrun.com>
21  *  1. Correct use of fStyle for fMask
22  *  2. Rewrite to support putting bands in rows, also supports GETROWCOUNT
23  *     and GETROWHEIGHT.
24  *  3. Make fMask in internal band info indicate what is valid rather than -1.
25  *  4. Correct output of GETBANDINFO to match MS for iImage, lpText
26  *  5. Handle RBN_CHILDSIZE notification (not really working)
27  *  6. Draw separators between bands and fix size of grippers.
28  *  7. Draw separators between rows.
29  *  8. Support RBBS_BREAK if specified by user.
30  *  9. Support background color for band and draw the background.
31  * 10. Eliminated duplicate code in SetBandInfo[AW] and InsertBand[AW]. 
32  * 11. Support text color and propagate colors from Bar to Band
33  *    Still to do:
34  *  1. default row height should be the max height of all visible bands
35  *  2. Following still not handled: RBBS_FIXEDBMP, RBBS_CHILDEDGE,
36  *            RBBS_VARIABLEHEIGHT, RBBS_USECHEVRON
37  *  3. GETBANDINFO seems to return correct colors in native but not here.
38
39  */
40
41 #include <string.h>
42
43 #include "winbase.h"
44 #include "wingdi.h"
45 #include "wine/unicode.h"
46 #include "wine/winestring.h"
47 #include "commctrl.h"
48 #include "debugtools.h"
49
50 DEFAULT_DEBUG_CHANNEL(rebar);
51
52 typedef struct
53 {
54     UINT    fStyle;
55     UINT    fMask;
56     COLORREF  clrFore;
57     COLORREF  clrBack;
58     INT     iImage;
59     HWND    hwndChild;
60     UINT    cxMinChild;
61     UINT    cyMinChild;
62     UINT    cx;
63     HBITMAP hbmBack;
64     UINT    wID;
65     UINT    cyChild;
66     UINT    cyMaxChild;
67     UINT    cyIntegral;
68     UINT    cxIdeal;
69     LPARAM    lParam;
70     UINT    cxHeader;
71
72     UINT    lcx;            /* minimum cx for band */
73     UINT    hcx;            /* maximum cx for band */
74     UINT    lcy;            /* minimum cy for band */
75     UINT    hcy;            /* maximum cy for band */
76
77     UINT    uMinHeight;
78     INT     iRow;           /* row this band assigned to */
79     UINT    fDraw;          /* drawing flags */
80     RECT    rcBand;         /* calculated band rectangle */
81     RECT    rcGripper;      /* calculated gripper rectangle */
82     RECT    rcCapImage;     /* calculated caption image rectangle */
83     RECT    rcCapText;      /* calculated caption text rectangle */
84     RECT    rcChild;        /* calculated child rectangle */
85
86     LPWSTR    lpText;
87     HWND    hwndPrevParent;
88 } REBAR_BAND;
89
90 typedef struct
91 {
92     COLORREF   clrBk;       /* background color */
93     COLORREF   clrText;     /* text color */
94     HIMAGELIST himl;        /* handle to imagelist */
95     UINT     uNumBands;   /* number of bands in the rebar */
96     UINT     uNumRows;    /* number of rows of bands */
97     HWND     hwndToolTip; /* handle to the tool tip control */
98     HWND     hwndNotify;  /* notification window (parent) */
99     HFONT    hFont;       /* handle to the rebar's font */
100     SIZE     imageSize;   /* image size (image list) */
101
102     SIZE     calcSize;    /* calculated rebar size */
103     BOOL     bAutoResize; /* auto resize deadlock flag */
104     BOOL     bUnicode;    /* Unicode flag */
105     HCURSOR  hcurArrow;   /* handle to the arrow cursor */
106     HCURSOR  hcurHorz;    /* handle to the EW cursor */
107     HCURSOR  hcurVert;    /* handle to the NS cursor */
108     HCURSOR  hcurDrag;    /* handle to the drag cursor */
109     INT      iVersion;    /* version number */
110
111     REBAR_BAND *bands;      /* pointer to the array of rebar bands */
112 } REBAR_INFO;
113
114
115 /* fDraw flags */
116 #define DRAW_GRIPPER    1
117 #define DRAW_IMAGE      2
118 #define DRAW_TEXT       4
119 #define DRAW_CHILD      8
120 #define DRAW_SEP        16
121
122 #define GRIPPER_WIDTH   8
123 #define GRIPPER_HEIGHT  16
124 #define SEP_WIDTH       3
125
126 /* This is the increment that is used over the band height */
127 /* Determined by experiment.                               */ 
128 #define REBARSPACE      4
129
130 #define REBAR_GetInfoPtr(wndPtr) ((REBAR_INFO *)GetWindowLongA (hwnd, 0))
131
132 static VOID
133 REBAR_DumpBandInfo( LPREBARBANDINFOA pB)
134 {
135         TRACE("band info: ID=%u, size=%u, style=0x%08x, mask=0x%08x, child=%04x\n",
136           pB->wID, pB->cbSize, pB->fStyle, pB->fMask, pB->hwndChild); 
137         TRACE("band info: cx=%u, xMin=%u, yMin=%u, yChild=%u, yMax=%u, yIntgl=%u\n",
138           pB->cx, pB->cxMinChild, 
139           pB->cyMinChild, pB->cyChild, pB->cyMaxChild, pB->cyIntegral);
140         TRACE("band info: xIdeal=%u, xHeader=%u, lParam=0x%08lx, clrF=0x%06lx, clrB=0x%06lx\n",
141           pB->cxIdeal, pB->cxHeader, pB->lParam, pB->clrFore, pB->clrBack);
142 }
143
144 static VOID
145 REBAR_DumpBand (HWND hwnd)
146 {
147     REBAR_INFO *iP = REBAR_GetInfoPtr (hwnd);
148     REBAR_BAND *pB;
149     UINT i;
150
151     if( TRACE_ON(rebar) ) {
152
153       TRACE("hwnd=%04x: color=%08lx/%08lx, bands=%u, rows=%u, cSize=%ld,%ld\n", 
154         hwnd, iP->clrText, iP->clrBk, iP->uNumBands, iP->uNumRows,
155         iP->calcSize.cx, iP->calcSize.cy);
156       for (i = 0; i < iP->uNumBands; i++) {
157         pB = &iP->bands[i];
158         TRACE("band # %u: ID=%u, mask=0x%08x, style=0x%08x, child=%04x, row=%u\n",
159           i, pB->wID, pB->fMask, pB->fStyle, pB->hwndChild, pB->iRow);
160         TRACE("band # %u: xMin=%u, yMin=%u, cx=%u, yChild=%u, yMax=%u, yIntgl=%u, uMinH=%u,\n",
161           i, pB->cxMinChild, pB->cyMinChild, pB->cx,
162           pB->cyChild, pB->cyMaxChild, pB->cyIntegral, pB->uMinHeight);
163         TRACE("band # %u: header=%u, lcx=%u, hcx=%u, lcy=%u, hcy=%u\n",
164           i, pB->cxHeader, pB->lcx, pB->hcx, pB->lcy, pB->hcy);
165         TRACE("band # %u: fDraw=%08x, Band=(%d,%d)-(%d,%d), Grip=(%d,%d)-(%d,%d)\n",
166           i, pB->fDraw,
167           pB->rcBand.left, pB->rcBand.top, pB->rcBand.right, pB->rcBand.bottom,
168           pB->rcGripper.left, pB->rcGripper.top, pB->rcGripper.right, pB->rcGripper.bottom);
169         TRACE("band # %u: Img=(%d,%d)-(%d,%d), Txt=(%d,%d)-(%d,%d), Child=(%d,%d)-(%d,%d)\n",
170           i,
171           pB->rcCapImage.left, pB->rcCapImage.top, pB->rcCapImage.right, pB->rcCapImage.bottom,
172           pB->rcCapText.left, pB->rcCapText.top, pB->rcCapText.right, pB->rcCapText.bottom,
173           pB->rcChild.left, pB->rcChild.top, pB->rcChild.right, pB->rcChild.bottom);
174       }
175
176     }
177 }
178
179 static VOID
180 REBAR_DrawBand (HDC hdc, REBAR_INFO *infoPtr, REBAR_BAND *lpBand, DWORD dwStyle)
181 {
182
183     /* draw separator */
184     if (lpBand->fDraw & DRAW_SEP) {
185         RECT rcSep;
186         if (dwStyle & CCS_VERT)
187           SetRect (&rcSep, lpBand->rcBand.left-2, lpBand->rcBand.top-SEP_WIDTH,
188                    lpBand->rcBand.right+2, lpBand->rcBand.top-1);
189         else
190           SetRect (&rcSep, lpBand->rcBand.left-SEP_WIDTH, lpBand->rcBand.top-2,
191                    lpBand->rcBand.left-1, lpBand->rcBand.bottom+2);
192         TRACE("drawing band separator (%d,%d)-(%d,%d)\n",
193               rcSep.left, rcSep.top, rcSep.right, rcSep.bottom);
194         DrawEdge (hdc, &rcSep, EDGE_ETCHED, BF_LEFT | BF_TOP | BF_MIDDLE);
195     }
196
197     /* draw background */
198     if (lpBand->clrBack != CLR_NONE) {
199         HBRUSH brh = CreateSolidBrush (lpBand->clrBack);
200         TRACE("backround color=0x%06lx, rect (%d,%d)-(%d,%d)\n",
201               lpBand->clrBack,
202               lpBand->rcBand.left,lpBand->rcBand.top,
203               lpBand->rcBand.right,lpBand->rcBand.bottom);
204         FillRect (hdc, &lpBand->rcBand, brh);
205         DeleteObject (brh);
206     }
207
208     /* draw gripper */
209     if (lpBand->fDraw & DRAW_GRIPPER)
210         DrawEdge (hdc, &lpBand->rcGripper, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE);
211
212     /* draw caption image */
213     if (lpBand->fDraw & DRAW_IMAGE) {
214         POINT pt;
215
216         /* center image */
217         pt.y = (lpBand->rcCapImage.bottom + lpBand->rcCapImage.top - infoPtr->imageSize.cy)/2;
218         pt.x = (lpBand->rcCapImage.right + lpBand->rcCapImage.left - infoPtr->imageSize.cx)/2;
219
220         ImageList_Draw (infoPtr->himl, lpBand->iImage, hdc,
221                         pt.x, pt.y,
222                         ILD_TRANSPARENT);
223     }
224
225     /* draw caption text */
226     if (lpBand->fDraw & DRAW_TEXT) {
227         HFONT hOldFont = SelectObject (hdc, infoPtr->hFont);
228         INT oldBkMode = SetBkMode (hdc, TRANSPARENT);
229         COLORREF oldcolor = CLR_NONE;
230         if (lpBand->clrFore != CLR_NONE)
231             oldcolor = SetTextColor (hdc, lpBand->clrFore);
232         DrawTextW (hdc, lpBand->lpText, -1, &lpBand->rcCapText,
233                      DT_CENTER | DT_VCENTER | DT_SINGLELINE);
234         if (oldBkMode != TRANSPARENT)
235             SetBkMode (hdc, oldBkMode);
236         if (lpBand->clrFore != CLR_NONE)
237             SetTextColor (hdc, oldcolor);
238         SelectObject (hdc, hOldFont);
239     }
240 }
241
242
243 static VOID
244 REBAR_Refresh (HWND hwnd, HDC hdc)
245 {
246     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
247     REBAR_BAND *lpBand;
248     UINT i, oldrow;
249     RECT rcRowSep;
250     DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
251
252     oldrow = infoPtr->bands[0].iRow;
253     for (i = 0; i < infoPtr->uNumBands; i++) {
254         lpBand = &infoPtr->bands[i];
255
256         if ((lpBand->fStyle & RBBS_HIDDEN) || 
257             ((dwStyle & CCS_VERT) &&
258              (lpBand->fStyle & RBBS_NOVERT)))
259             continue;
260
261         /* if a new row then draw a separator */
262         if (oldrow != lpBand->iRow) {
263           if (dwStyle & CCS_VERT) {
264             SetRect (&rcRowSep, lpBand->rcBand.left-2, 0,
265                      lpBand->rcBand.left-1, infoPtr->calcSize.cy);
266           }
267           else {
268             SetRect (&rcRowSep, 0, lpBand->rcBand.top-2,
269                      infoPtr->calcSize.cx, lpBand->rcBand.top-1);
270           } 
271           TRACE ("drawing row sep (%d,%d)-(%d,%d)\n",
272                  rcRowSep.left, rcRowSep.top, rcRowSep.right, rcRowSep.bottom);
273           DrawEdge (hdc, &rcRowSep, EDGE_ETCHED, BF_TOP|BF_LEFT);
274           oldrow = lpBand->iRow;
275         }
276
277         /* now draw the band */
278         REBAR_DrawBand (hdc, infoPtr, lpBand, dwStyle);
279
280     }
281 }
282
283 static void
284 REBAR_AdjustBands (REBAR_INFO *infoPtr, UINT rowstart, UINT rowend,
285                    INT maxx, INT usedx, INT mcy, DWORD dwStyle)
286      /* Function: This routine distributes the extra space in a row */
287      /*  evenly over the adjustable bands in the row. It also makes */
288      /*  sure that all bands in the row are the same height.        */
289 {
290     REBAR_BAND *lpBand;
291     UINT i, j;
292     INT incr, lastx=0;
293
294     TRACE("start=%u, end=%u, max x=%d, used x=%d, max y=%d\n",
295           rowstart, rowend-1, maxx, usedx, mcy);
296
297     j = 0;
298     for (i = rowstart; i<rowend; i++) {
299       lpBand = &infoPtr->bands[i];
300       if ((lpBand->fMask & RBBIM_CHILD) && lpBand->hwndChild &&
301           !(lpBand->fStyle & RBBS_FIXEDSIZE)) 
302          j++;
303     }
304     if (j)
305       incr = (maxx-usedx) / j;
306     else
307       incr = 0;
308
309     TRACE("adjusting %u of %u bands in row, incr=%d\n", 
310           j, rowend-rowstart, incr);
311
312     for (i = rowstart; i<rowend; i++) {
313       lpBand = &infoPtr->bands[i];
314       if (dwStyle & CCS_VERT) {
315         lpBand->rcBand.bottom = lastx + 
316                                 lpBand->rcBand.bottom - lpBand->rcBand.top;
317         if ((lpBand->fMask & RBBIM_CHILD) && lpBand->hwndChild &&
318             !(lpBand->fStyle & RBBS_FIXEDSIZE)) {
319            /* if a child window exists and not fixed then widen it */
320            lpBand->rcBand.bottom += incr;
321         }
322         lpBand->rcBand.top = lastx;
323         lastx = lpBand->rcBand.bottom + 1;
324         lpBand->rcBand.right = lpBand->rcBand.left + mcy;
325       }
326       else {
327         lpBand->rcBand.right = lastx + 
328                                lpBand->rcBand.right - lpBand->rcBand.left;
329         if ((lpBand->fMask & RBBIM_CHILD) && lpBand->hwndChild &&
330             !(lpBand->fStyle & RBBS_FIXEDSIZE)) {
331            /* if a child window exists and not fixed then widen it */
332            lpBand->rcBand.right += incr;
333         }
334         lpBand->rcBand.left = lastx;
335         lastx = lpBand->rcBand.right + 1;
336         lpBand->rcBand.bottom = lpBand->rcBand.top + mcy;
337       }
338     }
339
340 }
341
342 static void
343 REBAR_CalcHorzBand (HWND hwnd, REBAR_INFO *infoPtr, UINT rstart, UINT rend, BOOL notify, DWORD dwStyle)
344      /* Function: this routine initializes all the rectangles in */
345      /*  each band in a row to fit in the adjusted rcBand rect.  */
346      /* *** Supports only Horizontal bars. ***                   */
347 {
348     REBAR_BAND *lpBand;
349     UINT i, xoff, yoff;
350     NMREBARCHILDSIZE  rbcz;
351     HWND parenthwnd;
352     RECT oldChild;
353
354     rbcz.hdr.hwndFrom = hwnd;
355     rbcz.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
356     /* MS seems to use GetDlgCtrlID() for above GetWindowLong call */
357     parenthwnd = GetParent (hwnd);
358
359     for(i=rstart; i<rend; i++){
360       lpBand = &infoPtr->bands[i];
361       oldChild = lpBand->rcChild;
362
363       /* set initial gripper rectangle */
364       SetRect (&lpBand->rcGripper, lpBand->rcBand.left, lpBand->rcBand.top,
365              lpBand->rcBand.left, lpBand->rcBand.bottom);
366
367       /* calculate gripper rectangle */
368       if ((!(lpBand->fStyle & RBBS_NOGRIPPER)) &&
369           (!(lpBand->fStyle & RBBS_FIXEDSIZE)) &&
370           ((lpBand->fStyle & RBBS_GRIPPERALWAYS) || 
371            (infoPtr->uNumBands > 1))) {
372         lpBand->fDraw |= DRAW_GRIPPER;
373         lpBand->rcGripper.left   += 1;
374         lpBand->rcGripper.right  = lpBand->rcGripper.left + 3;
375         lpBand->rcGripper.top    += 3;
376         lpBand->rcGripper.bottom -= 3;
377
378         SetRect (&lpBand->rcCapImage, lpBand->rcGripper.left + GRIPPER_WIDTH,
379                  lpBand->rcBand.top, lpBand->rcGripper.left + GRIPPER_WIDTH,
380                  lpBand->rcBand.bottom);
381       }
382       else {
383         SetRect (&lpBand->rcCapImage, lpBand->rcBand.left, lpBand->rcBand.top,
384                  lpBand->rcBand.left, lpBand->rcBand.bottom);
385       }
386
387       /* image is visible */
388       if ((lpBand->fMask & RBBIM_IMAGE) && (infoPtr->himl)) {
389         lpBand->fDraw |= DRAW_IMAGE;
390
391         lpBand->rcCapImage.right  += infoPtr->imageSize.cx;
392         lpBand->rcCapImage.bottom = lpBand->rcCapImage.top + infoPtr->imageSize.cy;
393
394         /* update band height */
395         if (lpBand->uMinHeight < infoPtr->imageSize.cy + 2) {
396             lpBand->uMinHeight = infoPtr->imageSize.cy + 2;
397             lpBand->rcBand.bottom = lpBand->rcBand.top + lpBand->uMinHeight;
398         }
399       }
400
401       /* set initial caption text rectangle */
402       SetRect (&lpBand->rcCapText, lpBand->rcCapImage.right, lpBand->rcBand.top+1,
403                lpBand->rcCapImage.right, lpBand->rcBand.bottom-1);
404
405       /* text is visible */
406       if ((lpBand->fMask & RBBIM_TEXT) && (lpBand->lpText)) {
407         HDC hdc = GetDC (0);
408         HFONT hOldFont = SelectObject (hdc, infoPtr->hFont);
409         SIZE size;
410
411         lpBand->fDraw |= DRAW_TEXT;
412         GetTextExtentPoint32W (hdc, lpBand->lpText,
413                                lstrlenW (lpBand->lpText), &size);
414         lpBand->rcCapText.right += (size.cx + 2);
415
416         SelectObject (hdc, hOldFont);
417         ReleaseDC (0, hdc);
418       }
419
420       /* set initial child window rectangle if there is a child */
421       if (lpBand->fMask & RBBIM_CHILD) {
422         if (lpBand->fStyle & RBBS_FIXEDSIZE) {
423           xoff = 0;
424           yoff = 0;
425         }
426         else {
427           xoff = 4;
428           yoff = 2;
429         }
430         SetRect (&lpBand->rcChild,
431                  lpBand->rcBand.left+lpBand->cxHeader+xoff, lpBand->rcBand.top+yoff,
432                  lpBand->rcBand.right-xoff, lpBand->rcBand.bottom-yoff);
433       }
434       else {
435         SetRect (&lpBand->rcChild,
436                  lpBand->rcBand.right, lpBand->rcBand.top,
437                  lpBand->rcBand.right, lpBand->rcBand.bottom);
438       }
439
440 #if 1
441       /* do notify is child rectangle changed */
442       if (notify && !EqualRect (&oldChild, &lpBand->rcChild)) {
443         TRACE("Child rectangle changed for band %u\n", i);
444         TRACE("    from (%d,%d)-(%d,%d)  to (%d,%d)-(%d,%d)\n",
445                 oldChild.left, oldChild.top,
446                 oldChild.right, oldChild.bottom,
447                 lpBand->rcChild.left, lpBand->rcChild.top,
448                 lpBand->rcChild.right, lpBand->rcChild.bottom);
449         rbcz.hdr.code = RBN_CHILDSIZE;
450         rbcz.uBand = i;
451         rbcz.wID = lpBand->wID;
452         rbcz.rcChild = lpBand->rcChild;
453         rbcz.rcBand = lpBand->rcBand;
454         SendMessageA (parenthwnd, WM_NOTIFY, (WPARAM) rbcz.hdr.idFrom, 
455                       (LPARAM)&rbcz);
456         if (!EqualRect (&lpBand->rcChild, &rbcz.rcChild)) {
457           TRACE("Child rect changed by NOTIFY for band %u\n", i);
458           TRACE("    from (%d,%d)-(%d,%d)  to (%d,%d)-(%d,%d)\n",
459                 lpBand->rcChild.left, lpBand->rcChild.top,
460                 lpBand->rcChild.right, lpBand->rcChild.bottom,
461                 rbcz.rcChild.left, rbcz.rcChild.top,
462                 rbcz.rcChild.right, rbcz.rcChild.bottom);
463         }
464       }
465 #endif
466
467     }
468
469 }
470
471
472 static VOID
473 REBAR_CalcVertBand (HWND hwnd, REBAR_INFO *infoPtr, UINT rstart, UINT rend, BOOL notify, DWORD dwStyle)
474      /* Function: this routine initializes all the rectangles in */
475      /*  each band in a row to fit in the adjusted rcBand rect.  */
476      /* *** Supports only Vertical bars. ***                     */
477 {
478     REBAR_BAND *lpBand;
479     UINT i, xoff, yoff;
480     NMREBARCHILDSIZE  rbcz;
481     HWND parenthwnd;
482     RECT oldChild;
483
484     rbcz.hdr.hwndFrom = hwnd;
485     rbcz.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
486     /* MS seems to use GetDlgCtrlID() for above GetWindowLong call */
487     parenthwnd = GetParent (hwnd);
488
489     for(i=rstart; i<rend; i++){
490       lpBand = &infoPtr->bands[i];
491       oldChild = lpBand->rcChild;
492
493       /* set initial gripper rectangle */
494       SetRect (&lpBand->rcGripper, lpBand->rcBand.left, lpBand->rcBand.top,
495              lpBand->rcBand.right, lpBand->rcBand.top);
496
497       /* calculate gripper rectangle */
498       if ((!(lpBand->fStyle & RBBS_NOGRIPPER)) &&
499           (!(lpBand->fStyle & RBBS_FIXEDSIZE)) &&
500           ((lpBand->fStyle & RBBS_GRIPPERALWAYS) || 
501            (infoPtr->uNumBands > 1))) {
502         lpBand->fDraw |= DRAW_GRIPPER;
503
504         if (dwStyle & RBS_VERTICALGRIPPER) {
505             /*  vertical gripper  */
506             lpBand->rcGripper.left   += 3;
507             lpBand->rcGripper.right  = lpBand->rcGripper.left + 3;
508             lpBand->rcGripper.top    += 3;
509             lpBand->rcGripper.bottom = lpBand->rcGripper.top + GRIPPER_HEIGHT;
510
511             /* initialize Caption image rectangle  */
512             SetRect (&lpBand->rcCapImage, lpBand->rcBand.left,
513                      lpBand->rcGripper.top + GRIPPER_HEIGHT,
514                      lpBand->rcBand.right,
515                      lpBand->rcGripper.top + GRIPPER_HEIGHT);
516         }
517         else {
518             /*  horizontal gripper  */
519             lpBand->rcGripper.left   += 3;
520             lpBand->rcGripper.right  -= 3;
521             lpBand->rcGripper.top    += 3;
522             lpBand->rcGripper.bottom  = lpBand->rcGripper.top + 3;
523
524             /* initialize Caption image rectangle  */
525             SetRect (&lpBand->rcCapImage, lpBand->rcBand.left,
526                      lpBand->rcGripper.top + GRIPPER_WIDTH,
527                      lpBand->rcBand.right,
528                      lpBand->rcGripper.top + GRIPPER_WIDTH);
529         }
530       }
531       else {
532         /* initialize Caption image rectangle  */
533         SetRect (&lpBand->rcCapImage, lpBand->rcBand.left, lpBand->rcBand.top,
534                  lpBand->rcBand.right, lpBand->rcBand.top);
535       }
536
537       /* image is visible */
538       if ((lpBand->fMask & RBBIM_IMAGE) && (infoPtr->himl)) {
539         lpBand->fDraw |= DRAW_IMAGE;
540
541         lpBand->rcCapImage.right  += infoPtr->imageSize.cx;
542         lpBand->rcCapImage.bottom += infoPtr->imageSize.cy;
543
544         /* update band height */
545         if (lpBand->uMinHeight < infoPtr->imageSize.cx + 2) {
546             lpBand->uMinHeight = infoPtr->imageSize.cx + 2;
547             lpBand->rcBand.right = lpBand->rcBand.left + lpBand->uMinHeight;
548         }
549       }
550
551       /* set initial caption text rectangle */
552       lpBand->rcCapText.left   = lpBand->rcBand.left + 1;
553       lpBand->rcCapText.top    = lpBand->rcCapImage.bottom;
554       lpBand->rcCapText.right  = lpBand->rcBand.right - 1;
555       lpBand->rcCapText.bottom = lpBand->rcCapText.top;
556
557       /* text is visible */
558       if (lpBand->lpText) {
559         HDC hdc = GetDC (0);
560         HFONT hOldFont = SelectObject (hdc, infoPtr->hFont);
561         SIZE size;
562
563         lpBand->fDraw |= DRAW_TEXT;
564         GetTextExtentPoint32W (hdc, lpBand->lpText,
565                                lstrlenW (lpBand->lpText), &size);
566         lpBand->rcCapText.bottom += (size.cy + 2);
567
568         SelectObject (hdc, hOldFont);
569         ReleaseDC (0, hdc);
570       }
571
572       /* set initial child window rectangle if there is a child */
573       if (lpBand->fMask & RBBIM_CHILD) {
574         if (lpBand->fStyle & RBBS_FIXEDSIZE) {
575           xoff = 0;
576           yoff = 0;
577         }
578         else {
579           xoff = 2;
580           yoff = 4;
581         }
582         SetRect (&lpBand->rcChild,
583                  lpBand->rcBand.left+xoff, 
584                  lpBand->rcBand.top+lpBand->cxHeader+yoff,
585                  lpBand->rcBand.right-xoff, lpBand->rcBand.bottom-yoff);
586       }
587       else {
588         SetRect (&lpBand->rcChild,
589                  lpBand->rcBand.right, lpBand->rcBand.top,
590                  lpBand->rcBand.right, lpBand->rcBand.top);
591       }
592
593 #if 1
594       /* do notify is child rectangle changed */
595       if (notify && !EqualRect (&oldChild, &lpBand->rcChild)) {
596         TRACE("Child rectangle changed for band %u\n", i);
597         TRACE("    from (%d,%d)-(%d,%d)  to (%d,%d)-(%d,%d)\n",
598               oldChild.left, oldChild.top,
599               oldChild.right, oldChild.bottom,
600               lpBand->rcChild.left, lpBand->rcChild.top,
601               lpBand->rcChild.right, lpBand->rcChild.bottom);
602         rbcz.hdr.code = RBN_CHILDSIZE;
603         rbcz.uBand = i;
604         rbcz.wID = lpBand->wID;
605         rbcz.rcChild = lpBand->rcChild;
606         rbcz.rcBand = lpBand->rcBand;
607         SendMessageA (parenthwnd, WM_NOTIFY, (WPARAM) rbcz.hdr.idFrom, 
608                       (LPARAM)&rbcz);
609         if (!EqualRect (&lpBand->rcChild, &rbcz.rcChild)) {
610           TRACE("Child rect changed by NOTIFY for band %u\n", i);
611           TRACE("    from (%d,%d)-(%d,%d)  to (%d,%d)-(%d,%d)\n",
612                 lpBand->rcChild.left, lpBand->rcChild.top,
613                 lpBand->rcChild.right, lpBand->rcChild.bottom,
614                 rbcz.rcChild.left, rbcz.rcChild.top,
615                 rbcz.rcChild.right, rbcz.rcChild.bottom);
616         }
617       }
618 #endif
619
620     }
621 }
622
623
624 static VOID
625 REBAR_Layout (HWND hwnd, LPRECT lpRect, BOOL notify, BOOL resetclient)
626      /* Function: This routine is resposible for laying out all */
627      /*  the bands in a rebar. It assigns each band to a row and*/
628      /*  determines when to start a new row.                    */
629 {
630     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
631     DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
632     REBAR_BAND *lpBand;
633     RECT rcClient, rcAdj;
634     INT x, y, cx, cxsep, mcy, clientcx, clientcy, adjcx, adjcy, row, rightx, bottomy;
635     UINT i, rowstartband;
636     BOOL dobreak;
637
638     GetClientRect (hwnd, &rcClient);
639     TRACE("Client is (%d,%d)-(%d,%d)\n",
640           rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
641
642     if (lpRect) {
643         rcAdj = *lpRect;
644         TRACE("adjustment rect is (%d,%d)-(%d,%d)\n",
645               rcAdj.left, rcAdj.top, rcAdj.right, rcAdj.bottom);
646     }
647     else {
648       CopyRect (&rcAdj, &rcClient);
649     }
650
651     clientcx = rcClient.right - rcClient.left;
652     clientcy = rcClient.bottom - rcClient.top;
653     adjcx = rcAdj.right - rcAdj.left;
654     adjcy = rcAdj.bottom - rcAdj.top;
655     if (resetclient) {
656       TRACE("window client rect will be set to adj rect\n");
657       clientcx = adjcx;
658       clientcy = adjcy;
659     }
660     x = 0;
661     y = 0;
662     rowstartband = 0;
663     row = 1;
664     cx = 0;
665     mcy = 0;
666
667     for (i = 0; i < infoPtr->uNumBands; i++) {
668         lpBand = &infoPtr->bands[i];
669         lpBand->fDraw = 0;
670         lpBand->iRow = row;
671
672         if ((lpBand->fStyle & RBBS_HIDDEN) || 
673             ((dwStyle & CCS_VERT) && (lpBand->fStyle & RBBS_NOVERT)))
674             continue;
675
676         cxsep = (x==0) ? 0 : SEP_WIDTH;  /* separator from previous band */
677         cx = lpBand->cxHeader +   /* Header: includes gripper, text, image */
678              lpBand->hcx;         /* coumpted size of child */
679
680         if (dwStyle & CCS_VERT)
681           dobreak = (y + cx + cxsep > adjcy);
682         else
683           dobreak = (x + cx + cxsep > adjcx);
684         /* This is the check for whether we need to start a new row */
685         if ( ( (lpBand->fStyle & RBBS_BREAK) && (i != 0) ) ||
686              ( ((dwStyle & CCS_VERT) ? (y != 0) : (x != 0)) && dobreak)) {
687           TRACE("Spliting to new row %d on band %u\n", row+1, i);
688
689           if (dwStyle & CCS_VERT) {
690             /* first adjust all bands in previous current row to */
691             /* redistribute extra x pixels                       */
692             REBAR_AdjustBands (infoPtr, rowstartband, i,
693                                clientcy, y, mcy, dwStyle);
694             /* calculate band subrectangles and break to new row */
695             REBAR_CalcVertBand (hwnd, infoPtr, rowstartband, i,
696                                 notify, dwStyle);
697             y = 0;
698             x += (mcy + 2);
699           }
700           else {
701             /* first adjust all bands in previous current row to */
702             /* redistribute extra x pixels                       */
703             REBAR_AdjustBands (infoPtr, rowstartband, i,
704                                clientcx, x, mcy, dwStyle);
705             /* calculate band subrectangles and break to new row */
706             REBAR_CalcHorzBand (hwnd, infoPtr, rowstartband, i,
707                                 notify, dwStyle);
708             x = 0;
709             y += (mcy + 2);
710           }
711
712           /* FIXME: if not RBS_VARHEIGHT then find max */
713           mcy = 0;
714           cxsep = 0;
715           row++;
716           rowstartband = i;
717           lpBand->iRow = row;
718         }
719
720         if (mcy < lpBand->lcy + REBARSPACE) mcy = lpBand->lcy + REBARSPACE;
721
722         /* if boundary rect specified then limit mcy */
723         if (lpRect) {
724           if (dwStyle & CCS_VERT) {
725             if (x+mcy > adjcx) {
726               mcy = adjcx - x;
727               TRACE("row %u limiting mcy=%d, adjcx=%d, x=%d\n",
728                     i, mcy, adjcx, x);
729             }
730           }
731           else {
732             if (y+mcy > adjcy) {
733               mcy = adjcy - y;
734               TRACE("row %u limiting mcy=%d, adjcy=%d, y=%d\n",
735                     i, mcy, adjcy, y);
736             }
737           }
738         }
739
740         if (dwStyle & CCS_VERT) {
741           /* bound the bottom side if we have a bounding rectangle */
742           lpBand->fDraw |= (y==0) ? 0 : DRAW_SEP;
743           rightx = clientcx;
744           bottomy = (lpRect) ? min(clientcy, y+cxsep+cx) : y+cxsep+cx;
745           lpBand->rcBand.left   = x;
746           lpBand->rcBand.right  = y + min(mcy, lpBand->lcy+REBARSPACE);
747           lpBand->rcBand.top    = min(bottomy, y + cxsep);
748           lpBand->rcBand.bottom = bottomy;
749           lpBand->uMinHeight = lpBand->lcy;
750           y = bottomy;
751         }
752         else {
753           /* bound the right side if we have a bounding rectangle */
754           lpBand->fDraw |= (x==0) ? 0 : DRAW_SEP;
755           rightx = (lpRect) ? min(clientcx, x+cxsep+cx) : x+cxsep+cx;
756           bottomy = clientcy;
757           lpBand->rcBand.left   = min(rightx, x + cxsep);
758           lpBand->rcBand.right  = rightx;
759           lpBand->rcBand.top    = y;
760           lpBand->rcBand.bottom = y + min(mcy, lpBand->lcy+REBARSPACE);
761           lpBand->uMinHeight = lpBand->lcy;
762           x = rightx;
763         }
764         TRACE("band %u, row %d, (%d,%d)-(%d,%d)\n",
765               i, row,
766               lpBand->rcBand.left, lpBand->rcBand.top,
767               lpBand->rcBand.right, lpBand->rcBand.bottom);
768
769     }
770     if (infoPtr->uNumBands) {
771       infoPtr->uNumRows = row;
772
773       if (dwStyle & CCS_VERT) {
774         REBAR_AdjustBands (infoPtr, rowstartband, infoPtr->uNumBands,
775                            clientcy, y, mcy, dwStyle);
776         REBAR_CalcVertBand (hwnd, infoPtr, rowstartband, infoPtr->uNumBands,
777                             notify, dwStyle);
778         x += mcy;
779       }
780       else {
781         REBAR_AdjustBands (infoPtr, rowstartband, infoPtr->uNumBands,
782                            clientcx, x, mcy, dwStyle);
783         REBAR_CalcHorzBand (hwnd, infoPtr, rowstartband, infoPtr->uNumBands, 
784                             notify, dwStyle);
785         y += mcy;
786       }
787     }
788
789     /* FIXME: if not RBS_VARHEIGHT then find max mcy and adj rect*/
790
791     if (dwStyle & CCS_VERT) {
792         infoPtr->calcSize.cx = x;
793         infoPtr->calcSize.cy = clientcy;
794     }
795     else {
796         infoPtr->calcSize.cx = clientcx;
797         infoPtr->calcSize.cy = y;
798     }
799     REBAR_DumpBand (hwnd);
800 }
801
802
803 static VOID
804 REBAR_ForceResize (HWND hwnd)
805 {
806     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
807     RECT rc;
808
809     TRACE( " to [%ld x %ld]!\n",
810            infoPtr->calcSize.cx, infoPtr->calcSize.cy);
811
812     infoPtr->bAutoResize = TRUE;
813
814     rc.left = 0;
815     rc.top = 0;
816     rc.right  = infoPtr->calcSize.cx;
817     rc.bottom = infoPtr->calcSize.cy;
818
819     if (GetWindowLongA (hwnd, GWL_STYLE) & WS_BORDER) {
820         InflateRect (&rc, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
821     }
822
823     SetWindowPos (hwnd, 0, 0, 0,
824                     rc.right - rc.left, rc.bottom - rc.top,
825                     SWP_NOMOVE | SWP_NOZORDER | SWP_SHOWWINDOW);
826 }
827
828
829 static VOID
830 REBAR_MoveChildWindows (HWND hwnd)
831 {
832     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
833     REBAR_BAND *lpBand;
834     CHAR szClassName[40];
835     UINT i;
836
837     for (i = 0; i < infoPtr->uNumBands; i++) {
838         lpBand = &infoPtr->bands[i];
839
840         if (lpBand->fStyle & RBBS_HIDDEN)
841             continue;
842         if (lpBand->hwndChild) {
843             TRACE("hwndChild = %x\n", lpBand->hwndChild);
844
845             GetClassNameA (lpBand->hwndChild, szClassName, 40);
846             if (!lstrcmpA (szClassName, "ComboBox")) {
847                 INT nEditHeight, yPos;
848                 RECT rc;
849
850                 /* special placement code for combo box */
851
852
853                 /* get size of edit line */
854                 GetWindowRect (lpBand->hwndChild, &rc);
855                 nEditHeight = rc.bottom - rc.top;
856                 yPos = (lpBand->rcChild.bottom + lpBand->rcChild.top - nEditHeight)/2;
857
858                 /* center combo box inside child area */
859                 TRACE("moving child %04x to (%d,%d)-(%d,%d)\n",
860                       lpBand->hwndChild,
861                       lpBand->rcChild.left, yPos,
862                       lpBand->rcChild.right - lpBand->rcChild.left,
863                       nEditHeight);
864                 SetWindowPos (lpBand->hwndChild, HWND_TOP,
865                             lpBand->rcChild.left, /*lpBand->rcChild.top*/ yPos,
866                             lpBand->rcChild.right - lpBand->rcChild.left,
867                             nEditHeight,
868                             SWP_SHOWWINDOW);
869             }
870 #if 0
871             else if (!lstrcmpA (szClassName, WC_COMBOBOXEXA)) {
872                 INT nEditHeight, yPos;
873                 RECT rc;
874                 HWND hwndEdit;
875
876                 /* special placement code for extended combo box */
877
878                 /* get size of edit line */
879                 hwndEdit = SendMessageA (lpBand->hwndChild, CBEM_GETEDITCONTROL, 0, 0);
880                 GetWindowRect (hwndEdit, &rc);
881                 nEditHeight = rc.bottom - rc.top;
882                 yPos = (lpBand->rcChild.bottom + lpBand->rcChild.top - nEditHeight)/2;
883
884                 /* center combo box inside child area */
885                 TRACE("moving child %04x to (%d,%d)-(%d,%d)\n",
886                       lpBand->hwndChild,
887                       lpBand->rcChild.left, yPos,
888                       lpBand->rcChild.right - lpBand->rcChild.left,
889                       nEditHeight);
890                 SetWindowPos (lpBand->hwndChild, HWND_TOP,
891                             lpBand->rcChild.left, /*lpBand->rcChild.top*/ yPos,
892                             lpBand->rcChild.right - lpBand->rcChild.left,
893                             nEditHeight,
894                             SWP_SHOWWINDOW);
895
896             }
897 #endif
898             else {
899                 TRACE("moving child %04x to (%d,%d)-(%d,%d)\n",
900                       lpBand->hwndChild,
901                       lpBand->rcChild.left, lpBand->rcChild.top,
902                       lpBand->rcChild.right - lpBand->rcChild.left,
903                       lpBand->rcChild.bottom - lpBand->rcChild.top);
904                 SetWindowPos (lpBand->hwndChild, HWND_TOP,
905                             lpBand->rcChild.left, lpBand->rcChild.top,
906                             lpBand->rcChild.right - lpBand->rcChild.left,
907                             lpBand->rcChild.bottom - lpBand->rcChild.top,
908                             SWP_SHOWWINDOW);
909             }
910         }
911     }
912 }
913
914
915 static VOID
916 REBAR_ValidateBand (HWND hwnd, REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
917      /* Function:  This routine evaluates the band specs supplied */
918      /*  by the user and updates the following 5 fields in        */
919      /*  the internal band structure: cxHeader, lcx, lcy, hcx, hcy*/
920 {
921     UINT header=0;
922     DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
923
924     lpBand->lcx = 0;
925     lpBand->lcy = 0;
926     lpBand->hcx = 0;
927     lpBand->hcy = 0;
928
929     /* Header is where the image, text and gripper exist  */
930     /* in the band and preceed the child window.          */
931
932     /* calculate gripper rectangle */
933     if ((!(lpBand->fStyle & RBBS_NOGRIPPER)) &&
934         (!(lpBand->fStyle & RBBS_FIXEDSIZE)) &&
935         ((lpBand->fStyle & RBBS_GRIPPERALWAYS) || 
936          (infoPtr->uNumBands > 1))) {
937        if (dwStyle & CCS_VERT)
938           if (dwStyle & RBS_VERTICALGRIPPER)
939              header += (GRIPPER_HEIGHT + 3);
940           else
941              header += (GRIPPER_WIDTH + 3);
942        else
943           header += (GRIPPER_WIDTH + 1);
944     }
945
946     /* image is visible */
947     if ((lpBand->fMask & RBBIM_IMAGE) && (infoPtr->himl)) {
948         if (dwStyle & CCS_VERT) {
949            header += infoPtr->imageSize.cy;
950            lpBand->lcy = infoPtr->imageSize.cx + 2;
951         }
952         else {
953            header += infoPtr->imageSize.cx;
954            lpBand->lcy = infoPtr->imageSize.cy + 2;
955         }
956     }
957
958     /* text is visible */
959     if ((lpBand->fMask & RBBIM_TEXT) && (lpBand->lpText)) {
960         HDC hdc = GetDC (0);
961         HFONT hOldFont = SelectObject (hdc, infoPtr->hFont);
962         SIZE size;
963
964         GetTextExtentPoint32W (hdc, lpBand->lpText,
965                                lstrlenW (lpBand->lpText), &size);
966         header += ((dwStyle & CCS_VERT) ? (size.cy + 2) : (size.cx + 2));
967
968         SelectObject (hdc, hOldFont);
969         ReleaseDC (0, hdc);
970     }
971
972     /* check if user overrode the header value */
973     if (!(lpBand->fMask & RBBIM_HEADERSIZE))
974         lpBand->cxHeader = header;
975
976
977     /* Now compute minimum size of child window */
978     if (lpBand->fMask & RBBIM_CHILDSIZE) {
979         lpBand->lcx = lpBand->cxMinChild;
980         lpBand->lcy = lpBand->cyMinChild;
981         lpBand->hcy = lpBand->lcy;
982         if (lpBand->fStyle & RBBS_VARIABLEHEIGHT) {
983             if (lpBand->cyChild != 0xffffffff)
984                 lpBand->lcy = max (lpBand->cyChild, lpBand->lcy);
985             lpBand->hcy = lpBand->cyMaxChild;
986         }
987         TRACE("_CHILDSIZE\n");
988     }
989     if (lpBand->fMask & RBBIM_SIZE) {
990         lpBand->hcx = max (lpBand->cx, lpBand->lcx);
991         TRACE("_SIZE\n");
992     }
993     else
994         lpBand->hcx = lpBand->lcx;
995
996 }
997
998 static void
999 REBAR_CommonSetupBand (HWND hwnd, LPREBARBANDINFOA lprbbi, REBAR_BAND *lpBand)
1000      /* Function:  This routine copies the supplied values from   */
1001      /*  user input (lprbbi) to the internal band structure.      */
1002 {
1003     lpBand->fMask |= lprbbi->fMask;
1004
1005     if (lprbbi->fMask & RBBIM_STYLE)
1006         lpBand->fStyle = lprbbi->fStyle;
1007
1008     if (lprbbi->fMask & RBBIM_COLORS) {
1009         lpBand->clrFore = lprbbi->clrFore;
1010         lpBand->clrBack = lprbbi->clrBack;
1011     }
1012
1013     if (lprbbi->fMask & RBBIM_IMAGE)
1014         lpBand->iImage = lprbbi->iImage;
1015
1016     if (lprbbi->fMask & RBBIM_CHILD) {
1017         if (lprbbi->hwndChild) {
1018             lpBand->hwndChild = lprbbi->hwndChild;
1019             lpBand->hwndPrevParent =
1020                 SetParent (lpBand->hwndChild, hwnd);
1021         }
1022         else {
1023             TRACE("child: 0x%x  prev parent: 0x%x\n",
1024                    lpBand->hwndChild, lpBand->hwndPrevParent);
1025             lpBand->hwndChild = 0;
1026             lpBand->hwndPrevParent = 0;
1027         }
1028     }
1029
1030     if (lprbbi->fMask & RBBIM_CHILDSIZE) {
1031         lpBand->cxMinChild = lprbbi->cxMinChild;
1032         lpBand->cyMinChild = lprbbi->cyMinChild;
1033         lpBand->cyMaxChild = lprbbi->cyMaxChild;
1034         lpBand->cyChild    = lprbbi->cyChild;
1035         lpBand->cyIntegral = lprbbi->cyIntegral;
1036     }
1037
1038     if (lprbbi->fMask & RBBIM_SIZE)
1039         lpBand->cx = lprbbi->cx;
1040
1041     if (lprbbi->fMask & RBBIM_BACKGROUND)
1042         lpBand->hbmBack = lprbbi->hbmBack;
1043
1044     if (lprbbi->fMask & RBBIM_ID)
1045         lpBand->wID = lprbbi->wID;
1046
1047     /* check for additional data */
1048     if (lprbbi->cbSize >= sizeof (REBARBANDINFOA)) {
1049         if (lprbbi->fMask & RBBIM_IDEALSIZE)
1050             lpBand->cxIdeal = lprbbi->cxIdeal;
1051
1052         if (lprbbi->fMask & RBBIM_LPARAM)
1053             lpBand->lParam = lprbbi->lParam;
1054
1055         if (lprbbi->fMask & RBBIM_HEADERSIZE)
1056             lpBand->cxHeader = lprbbi->cxHeader;
1057     }
1058 }
1059
1060 static void
1061 REBAR_InternalHitTest (HWND hwnd, LPPOINT lpPt, UINT *pFlags, INT *pBand)
1062 {
1063     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1064     REBAR_BAND *lpBand;
1065     RECT rect;
1066     INT  iCount;
1067
1068     GetClientRect (hwnd, &rect);
1069
1070     *pFlags = RBHT_NOWHERE;
1071     if (PtInRect (&rect, *lpPt))
1072     {
1073         if (infoPtr->uNumBands == 0) {
1074             *pFlags = RBHT_NOWHERE;
1075             if (pBand)
1076                 *pBand = -1;
1077             TRACE("NOWHERE\n");
1078             return;
1079         }
1080         else {
1081             /* somewhere inside */
1082             for (iCount = 0; iCount < infoPtr->uNumBands; iCount++) {
1083                 lpBand = &infoPtr->bands[iCount];
1084                 if (PtInRect (&lpBand->rcBand, *lpPt)) {
1085                     if (pBand)
1086                         *pBand = iCount;
1087                     if (PtInRect (&lpBand->rcGripper, *lpPt)) {
1088                         *pFlags = RBHT_GRABBER;
1089                         TRACE("ON GRABBER %d\n", iCount);
1090                         return;
1091                     }
1092                     else if (PtInRect (&lpBand->rcCapImage, *lpPt)) {
1093                         *pFlags = RBHT_CAPTION;
1094                         TRACE("ON CAPTION %d\n", iCount);
1095                         return;
1096                     }
1097                     else if (PtInRect (&lpBand->rcCapText, *lpPt)) {
1098                         *pFlags = RBHT_CAPTION;
1099                         TRACE("ON CAPTION %d\n", iCount);
1100                         return;
1101                     }
1102                     else if (PtInRect (&lpBand->rcChild, *lpPt)) {
1103                         *pFlags = RBHT_CLIENT;
1104                         TRACE("ON CLIENT %d\n", iCount);
1105                         return;
1106                     }
1107                     else {
1108                         *pFlags = RBHT_NOWHERE;
1109                         TRACE("NOWHERE %d\n", iCount);
1110                         return;
1111                     }
1112                 }
1113             }
1114
1115             *pFlags = RBHT_NOWHERE;
1116             if (pBand)
1117                 *pBand = -1;
1118
1119             TRACE("NOWHERE\n");
1120             return;
1121         }
1122     }
1123     else {
1124         *pFlags = RBHT_NOWHERE;
1125         if (pBand)
1126             *pBand = -1;
1127         TRACE("NOWHERE\n");
1128         return;
1129     }
1130
1131     TRACE("flags=0x%X\n", *pFlags);
1132     return;
1133 }
1134
1135
1136
1137 /* << REBAR_BeginDrag >> */
1138
1139
1140 static LRESULT
1141 REBAR_DeleteBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
1142 {
1143     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1144     UINT uBand = (UINT)wParam;
1145
1146     if (uBand >= infoPtr->uNumBands)
1147         return FALSE;
1148
1149     TRACE("deleting band %u!\n", uBand);
1150
1151     if (infoPtr->uNumBands == 1) {
1152         TRACE(" simple delete!\n");
1153         COMCTL32_Free (infoPtr->bands);
1154         infoPtr->bands = NULL;
1155         infoPtr->uNumBands = 0;
1156     }
1157     else {
1158         REBAR_BAND *oldBands = infoPtr->bands;
1159         TRACE("complex delete! [uBand=%u]\n", uBand);
1160
1161         infoPtr->uNumBands--;
1162         infoPtr->bands = COMCTL32_Alloc (sizeof (REBAR_BAND) * infoPtr->uNumBands);
1163         if (uBand > 0) {
1164             memcpy (&infoPtr->bands[0], &oldBands[0],
1165                     uBand * sizeof(REBAR_BAND));
1166         }
1167
1168         if (uBand < infoPtr->uNumBands) {
1169             memcpy (&infoPtr->bands[uBand], &oldBands[uBand+1],
1170                     (infoPtr->uNumBands - uBand) * sizeof(REBAR_BAND));
1171         }
1172
1173         COMCTL32_Free (oldBands);
1174     }
1175
1176     REBAR_Layout (hwnd, NULL, FALSE, FALSE);
1177     REBAR_ForceResize (hwnd);
1178     REBAR_MoveChildWindows (hwnd);
1179
1180     return TRUE;
1181 }
1182
1183
1184 /* << REBAR_DragMove >> */
1185 /* << REBAR_EndDrag >> */
1186
1187
1188 static LRESULT
1189 REBAR_GetBandBorders (HWND hwnd, WPARAM wParam, LPARAM lParam)
1190 {
1191     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1192     /* LPRECT32 lpRect = (LPRECT32)lParam; */
1193     REBAR_BAND *lpBand;
1194
1195     if (!lParam)
1196         return 0;
1197     if ((UINT)wParam >= infoPtr->uNumBands)
1198         return 0;
1199
1200     lpBand = &infoPtr->bands[(UINT)wParam];
1201     if (GetWindowLongA (hwnd, GWL_STYLE) & RBS_BANDBORDERS) {
1202       /*lpRect.left   = ??? */
1203       /*lpRect.top    = ??? */
1204       /*lpRect.right  = ??? */
1205       /*lpRect.bottom = ??? */
1206     }
1207     else {
1208       /*lpRect.left   = ??? */
1209     }
1210     FIXME("stub\n");
1211     return 0;
1212 }
1213
1214
1215 inline static LRESULT
1216 REBAR_GetBandCount (HWND hwnd)
1217 {
1218     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1219
1220     TRACE("band count %u!\n", infoPtr->uNumBands);
1221
1222     return infoPtr->uNumBands;
1223 }
1224
1225
1226 static LRESULT
1227 REBAR_GetBandInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1228 {
1229     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1230     LPREBARBANDINFOA lprbbi = (LPREBARBANDINFOA)lParam;
1231     REBAR_BAND *lpBand;
1232
1233     if (lprbbi == NULL)
1234         return FALSE;
1235     if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEA)
1236         return FALSE;
1237     if ((UINT)wParam >= infoPtr->uNumBands)
1238         return FALSE;
1239
1240     TRACE("index %u\n", (UINT)wParam);
1241
1242     /* copy band information */
1243     lpBand = &infoPtr->bands[(UINT)wParam];
1244
1245     if (lprbbi->fMask & RBBIM_STYLE)
1246         lprbbi->fStyle = lpBand->fStyle;
1247
1248     if (lprbbi->fMask & RBBIM_COLORS) {
1249         lprbbi->clrFore = lpBand->clrFore;
1250         lprbbi->clrBack = lpBand->clrBack;
1251         if (lprbbi->clrBack == CLR_NONE)
1252             lprbbi->clrBack = GetSysColor (COLOR_BTNFACE);
1253     }
1254
1255     if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) {
1256       if (lpBand->lpText && (lpBand->fMask & RBBIM_TEXT))
1257         lstrcpynWtoA (lprbbi->lpText, lpBand->lpText, lprbbi->cch);
1258       else 
1259         *lprbbi->lpText = 0;
1260     }
1261
1262     if (lprbbi->fMask & RBBIM_IMAGE) {
1263       if (lpBand->fMask & RBBIM_IMAGE)
1264         lprbbi->iImage = lpBand->iImage;
1265       else
1266         lprbbi->iImage = -1;
1267     }
1268
1269     if (lprbbi->fMask & RBBIM_CHILD)
1270         lprbbi->hwndChild = lpBand->hwndChild;
1271
1272     if (lprbbi->fMask & RBBIM_CHILDSIZE) {
1273         lprbbi->cxMinChild = lpBand->cxMinChild;
1274         lprbbi->cyMinChild = lpBand->cyMinChild;
1275         lprbbi->cyMaxChild = lpBand->cyMaxChild;
1276         lprbbi->cyChild    = lpBand->cyChild;
1277         lprbbi->cyIntegral = lpBand->cyIntegral;
1278     }
1279
1280     if (lprbbi->fMask & RBBIM_SIZE)
1281         lprbbi->cx = lpBand->cx;
1282
1283     if (lprbbi->fMask & RBBIM_BACKGROUND)
1284         lprbbi->hbmBack = lpBand->hbmBack;
1285
1286     if (lprbbi->fMask & RBBIM_ID)
1287         lprbbi->wID = lpBand->wID;
1288
1289     /* check for additional data */
1290     if (lprbbi->cbSize >= sizeof (REBARBANDINFOA)) {
1291         if (lprbbi->fMask & RBBIM_IDEALSIZE)
1292             lprbbi->cxIdeal = lpBand->cxIdeal;
1293
1294         if (lprbbi->fMask & RBBIM_LPARAM)
1295             lprbbi->lParam = lpBand->lParam;
1296
1297         if (lprbbi->fMask & RBBIM_HEADERSIZE)
1298             lprbbi->cxHeader = lpBand->cxHeader;
1299     }
1300
1301     REBAR_DumpBandInfo (lprbbi);
1302
1303     return TRUE;
1304 }
1305
1306
1307 static LRESULT
1308 REBAR_GetBandInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1309 {
1310     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1311     LPREBARBANDINFOW lprbbi = (LPREBARBANDINFOW)lParam;
1312     REBAR_BAND *lpBand;
1313
1314     if (lprbbi == NULL)
1315         return FALSE;
1316     if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEW)
1317         return FALSE;
1318     if ((UINT)wParam >= infoPtr->uNumBands)
1319         return FALSE;
1320
1321     TRACE("index %u\n", (UINT)wParam);
1322
1323     /* copy band information */
1324     lpBand = &infoPtr->bands[(UINT)wParam];
1325
1326     if (lprbbi->fMask & RBBIM_STYLE)
1327         lprbbi->fStyle = lpBand->fStyle;
1328
1329     if (lprbbi->fMask & RBBIM_COLORS) {
1330         lprbbi->clrFore = lpBand->clrFore;
1331         lprbbi->clrBack = lpBand->clrBack;
1332         if (lprbbi->clrBack == CLR_NONE)
1333             lprbbi->clrBack = GetSysColor (COLOR_BTNFACE);
1334     }
1335
1336     if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) {
1337       if (lpBand->lpText && (lpBand->fMask & RBBIM_TEXT))
1338         lstrcpynW (lprbbi->lpText, lpBand->lpText, lprbbi->cch);
1339       else 
1340         *lprbbi->lpText = 0;
1341     }
1342
1343     if (lprbbi->fMask & RBBIM_IMAGE) {
1344       if (lpBand->fMask & RBBIM_IMAGE)
1345         lprbbi->iImage = lpBand->iImage;
1346       else
1347         lprbbi->iImage = -1;
1348     }
1349
1350     if (lprbbi->fMask & RBBIM_CHILD)
1351         lprbbi->hwndChild = lpBand->hwndChild;
1352
1353     if (lprbbi->fMask & RBBIM_CHILDSIZE) {
1354         lprbbi->cxMinChild = lpBand->cxMinChild;
1355         lprbbi->cyMinChild = lpBand->cyMinChild;
1356         lprbbi->cyMaxChild = lpBand->cyMaxChild;
1357         lprbbi->cyChild    = lpBand->cyChild;
1358         lprbbi->cyIntegral = lpBand->cyIntegral;
1359     }
1360
1361     if (lprbbi->fMask & RBBIM_SIZE)
1362         lprbbi->cx = lpBand->cx;
1363
1364     if (lprbbi->fMask & RBBIM_BACKGROUND)
1365         lprbbi->hbmBack = lpBand->hbmBack;
1366
1367     if (lprbbi->fMask & RBBIM_ID)
1368         lprbbi->wID = lpBand->wID;
1369
1370     /* check for additional data */
1371     if (lprbbi->cbSize >= sizeof (REBARBANDINFOA)) {
1372         if (lprbbi->fMask & RBBIM_IDEALSIZE)
1373             lprbbi->cxIdeal = lpBand->cxIdeal;
1374
1375         if (lprbbi->fMask & RBBIM_LPARAM)
1376             lprbbi->lParam = lpBand->lParam;
1377
1378         if (lprbbi->fMask & RBBIM_HEADERSIZE)
1379             lprbbi->cxHeader = lpBand->cxHeader;
1380     }
1381
1382     REBAR_DumpBandInfo ((LPREBARBANDINFOA)lprbbi);
1383
1384     return TRUE;
1385 }
1386
1387
1388 static LRESULT
1389 REBAR_GetBarHeight (HWND hwnd, WPARAM wParam, LPARAM lParam)
1390 {
1391     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1392     INT nHeight;
1393
1394     nHeight = infoPtr->calcSize.cy;
1395
1396     TRACE("height = %d\n", nHeight);
1397
1398     return nHeight;
1399 }
1400
1401
1402 static LRESULT
1403 REBAR_GetBarInfo (HWND hwnd, WPARAM wParam, LPARAM lParam)
1404 {
1405     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1406     LPREBARINFO lpInfo = (LPREBARINFO)lParam;
1407
1408     if (lpInfo == NULL)
1409         return FALSE;
1410
1411     if (lpInfo->cbSize < sizeof (REBARINFO))
1412         return FALSE;
1413
1414     TRACE("getting bar info!\n");
1415
1416     if (infoPtr->himl) {
1417         lpInfo->himl = infoPtr->himl;
1418         lpInfo->fMask |= RBIM_IMAGELIST;
1419     }
1420
1421     return TRUE;
1422 }
1423
1424
1425 inline static LRESULT
1426 REBAR_GetBkColor (HWND hwnd)
1427 {
1428     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1429     COLORREF clr = infoPtr->clrBk;
1430
1431     if (clr == CLR_NONE)
1432       clr = GetSysColor (COLOR_BTNFACE);
1433
1434     TRACE("background color 0x%06lx!\n", clr);
1435
1436     return clr;
1437 }
1438
1439
1440 /* << REBAR_GetColorScheme >> */
1441 /* << REBAR_GetDropTarget >> */
1442
1443
1444 static LRESULT
1445 REBAR_GetPalette (HWND hwnd, WPARAM wParam, LPARAM lParam)
1446 {
1447     FIXME("empty stub!\n");
1448
1449     return 0;
1450 }
1451
1452
1453 static LRESULT
1454 REBAR_GetRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
1455 {
1456     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1457     INT iBand = (INT)wParam;
1458     LPRECT lprc = (LPRECT)lParam;
1459     REBAR_BAND *lpBand;
1460
1461     if ((iBand < 0) && ((UINT)iBand >= infoPtr->uNumBands))
1462         return FALSE;
1463     if (!lprc)
1464         return FALSE;
1465
1466     lpBand = &infoPtr->bands[iBand];
1467     CopyRect (lprc, &lpBand->rcBand);
1468
1469     TRACE("band %d, (%d,%d)-(%d,%d)\n", iBand,
1470           lprc->left, lprc->top, lprc->right, lprc->bottom);
1471
1472     return TRUE;
1473 }
1474
1475
1476 inline static LRESULT
1477 REBAR_GetRowCount (HWND hwnd)
1478 {
1479     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1480
1481     TRACE("%u\n", infoPtr->uNumRows);
1482
1483     return infoPtr->uNumRows;
1484 }
1485
1486
1487 static LRESULT
1488 REBAR_GetRowHeight (HWND hwnd, WPARAM wParam, LPARAM lParam)
1489 {
1490     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1491     INT iRow = (INT)wParam;
1492     int ret = 0;
1493     int i, j = 0;
1494     REBAR_BAND *lpBand;
1495     DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1496
1497     for (i=0; i<infoPtr->uNumBands; i++) {
1498       lpBand = &infoPtr->bands[i];
1499       if (lpBand->iRow != iRow) continue;
1500       if (dwStyle & CCS_VERT)
1501         j = lpBand->rcBand.right - lpBand->rcBand.left;
1502       else
1503         j = lpBand->rcBand.bottom - lpBand->rcBand.top;
1504       if (j > ret) ret = j;
1505     }
1506
1507     TRACE("row %d, height %d\n", iRow, ret);
1508
1509     return ret;
1510 }
1511
1512
1513 inline static LRESULT
1514 REBAR_GetTextColor (HWND hwnd)
1515 {
1516     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1517
1518     TRACE("text color 0x%06lx!\n", infoPtr->clrText);
1519
1520     return infoPtr->clrText;
1521 }
1522
1523
1524 inline static LRESULT
1525 REBAR_GetToolTips (HWND hwnd)
1526 {
1527     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1528     return infoPtr->hwndToolTip;
1529 }
1530
1531
1532 inline static LRESULT
1533 REBAR_GetUnicodeFormat (HWND hwnd)
1534 {
1535     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1536     return infoPtr->bUnicode;
1537 }
1538
1539
1540 inline static LRESULT
1541 REBAR_GetVersion (HWND hwnd)
1542 {
1543     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1544     TRACE("version %d\n", infoPtr->iVersion);
1545     return infoPtr->iVersion;
1546 }
1547
1548
1549 static LRESULT
1550 REBAR_HitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
1551 {
1552     /* REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */
1553     LPRBHITTESTINFO lprbht = (LPRBHITTESTINFO)lParam; 
1554
1555     if (!lprbht)
1556         return -1;
1557
1558     REBAR_InternalHitTest (hwnd, &lprbht->pt, &lprbht->flags, &lprbht->iBand);
1559
1560     return lprbht->iBand;
1561 }
1562
1563
1564 static LRESULT
1565 REBAR_IdToIndex (HWND hwnd, WPARAM wParam, LPARAM lParam)
1566 {
1567     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1568     UINT i;
1569
1570     if (infoPtr == NULL)
1571         return -1;
1572
1573     if (infoPtr->uNumBands < 1)
1574         return -1;
1575
1576     for (i = 0; i < infoPtr->uNumBands; i++) {
1577         if (infoPtr->bands[i].wID == (UINT)wParam) {
1578             TRACE("id %u is band %u found!\n", (UINT)wParam, i);
1579             return i;
1580         }
1581     }
1582
1583     TRACE("id %u is not found\n", (UINT)wParam);
1584     return -1;
1585 }
1586
1587
1588 static LRESULT
1589 REBAR_InsertBandA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1590 {
1591     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1592     LPREBARBANDINFOA lprbbi = (LPREBARBANDINFOA)lParam;
1593     UINT uIndex = (UINT)wParam;
1594     REBAR_BAND *lpBand;
1595
1596     if (infoPtr == NULL)
1597         return FALSE;
1598     if (lprbbi == NULL)
1599         return FALSE;
1600     if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEA)
1601         return FALSE;
1602
1603     /* trace the index as signed to see the -1 */
1604     TRACE("insert band at %d!\n", (INT)uIndex);
1605     REBAR_DumpBandInfo (lprbbi);
1606
1607     if (infoPtr->uNumBands == 0) {
1608         infoPtr->bands = (REBAR_BAND *)COMCTL32_Alloc (sizeof (REBAR_BAND));
1609         uIndex = 0;
1610     }
1611     else {
1612         REBAR_BAND *oldBands = infoPtr->bands;
1613         infoPtr->bands =
1614             (REBAR_BAND *)COMCTL32_Alloc ((infoPtr->uNumBands+1)*sizeof(REBAR_BAND));
1615         if (((INT)uIndex == -1) || (uIndex > infoPtr->uNumBands))
1616             uIndex = infoPtr->uNumBands;
1617
1618         /* pre insert copy */
1619         if (uIndex > 0) {
1620             memcpy (&infoPtr->bands[0], &oldBands[0],
1621                     uIndex * sizeof(REBAR_BAND));
1622         }
1623
1624         /* post copy */
1625         if (uIndex < infoPtr->uNumBands - 1) {
1626             memcpy (&infoPtr->bands[uIndex+1], &oldBands[uIndex],
1627                     (infoPtr->uNumBands - uIndex - 1) * sizeof(REBAR_BAND));
1628         }
1629
1630         COMCTL32_Free (oldBands);
1631     }
1632
1633     infoPtr->uNumBands++;
1634
1635     TRACE("index %u!\n", uIndex);
1636
1637     /* initialize band (infoPtr->bands[uIndex])*/
1638     lpBand = &infoPtr->bands[uIndex];
1639     lpBand->fMask = 0;
1640     lpBand->clrFore = infoPtr->clrText;
1641     lpBand->clrBack = infoPtr->clrBk;
1642     lpBand->hwndChild = 0;
1643     lpBand->hwndPrevParent = 0;
1644
1645     REBAR_CommonSetupBand (hwnd, lprbbi, lpBand);
1646     lpBand->lpText = NULL;
1647     if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) {
1648         INT len = lstrlenA (lprbbi->lpText);
1649         if (len > 0) {
1650             lpBand->lpText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
1651             lstrcpyAtoW (lpBand->lpText, lprbbi->lpText);
1652         }
1653     }
1654
1655     REBAR_ValidateBand (hwnd, infoPtr, lpBand);
1656
1657     REBAR_DumpBand (hwnd);
1658
1659     REBAR_Layout (hwnd, NULL, FALSE, FALSE);
1660     REBAR_ForceResize (hwnd);
1661     REBAR_MoveChildWindows (hwnd);
1662
1663     return TRUE;
1664 }
1665
1666
1667 static LRESULT
1668 REBAR_InsertBandW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1669 {
1670     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1671     LPREBARBANDINFOW lprbbi = (LPREBARBANDINFOW)lParam;
1672     UINT uIndex = (UINT)wParam;
1673     REBAR_BAND *lpBand;
1674
1675     if (infoPtr == NULL)
1676         return FALSE;
1677     if (lprbbi == NULL)
1678         return FALSE;
1679     if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEW)
1680         return FALSE;
1681
1682     /* trace the index as signed to see the -1 */
1683     TRACE("insert band at %d!\n", (INT)uIndex);
1684     REBAR_DumpBandInfo ((LPREBARBANDINFOA)lprbbi);
1685
1686     if (infoPtr->uNumBands == 0) {
1687         infoPtr->bands = (REBAR_BAND *)COMCTL32_Alloc (sizeof (REBAR_BAND));
1688         uIndex = 0;
1689     }
1690     else {
1691         REBAR_BAND *oldBands = infoPtr->bands;
1692         infoPtr->bands =
1693             (REBAR_BAND *)COMCTL32_Alloc ((infoPtr->uNumBands+1)*sizeof(REBAR_BAND));
1694         if (((INT)uIndex == -1) || (uIndex > infoPtr->uNumBands))
1695             uIndex = infoPtr->uNumBands;
1696
1697         /* pre insert copy */
1698         if (uIndex > 0) {
1699             memcpy (&infoPtr->bands[0], &oldBands[0],
1700                     uIndex * sizeof(REBAR_BAND));
1701         }
1702
1703         /* post copy */
1704         if (uIndex < infoPtr->uNumBands - 1) {
1705             memcpy (&infoPtr->bands[uIndex+1], &oldBands[uIndex],
1706                     (infoPtr->uNumBands - uIndex - 1) * sizeof(REBAR_BAND));
1707         }
1708
1709         COMCTL32_Free (oldBands);
1710     }
1711
1712     infoPtr->uNumBands++;
1713
1714     TRACE("index %u!\n", uIndex);
1715
1716     /* initialize band (infoPtr->bands[uIndex])*/
1717     lpBand = &infoPtr->bands[uIndex];
1718     lpBand->fMask = 0;
1719     lpBand->clrFore = infoPtr->clrText;
1720     lpBand->clrBack = infoPtr->clrBk;
1721     lpBand->hwndChild = 0;
1722     lpBand->hwndPrevParent = 0;
1723
1724     REBAR_CommonSetupBand (hwnd, (LPREBARBANDINFOA)lprbbi, lpBand);
1725     lpBand->lpText = NULL;
1726     if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) {
1727         INT len = lstrlenW (lprbbi->lpText);
1728         if (len > 0) {
1729             lpBand->lpText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
1730             strcpyW (lpBand->lpText, lprbbi->lpText);
1731         }
1732     }
1733
1734     REBAR_ValidateBand (hwnd, infoPtr, lpBand);
1735
1736     REBAR_DumpBand (hwnd);
1737
1738     REBAR_Layout (hwnd, NULL, FALSE, FALSE);
1739     REBAR_ForceResize (hwnd);
1740     REBAR_MoveChildWindows (hwnd);
1741
1742     return TRUE;
1743 }
1744
1745
1746 static LRESULT
1747 REBAR_MaximizeBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
1748 {
1749 /*    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */
1750
1751     FIXME("(uBand = %u fIdeal = %s)\n",
1752            (UINT)wParam, lParam ? "TRUE" : "FALSE");
1753
1754  
1755     return 0;
1756 }
1757
1758
1759 static LRESULT
1760 REBAR_MinimizeBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
1761 {
1762 /*    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */
1763
1764     FIXME("(uBand = %u)\n", (UINT)wParam);
1765
1766  
1767     return 0;
1768 }
1769
1770
1771 static LRESULT
1772 REBAR_MoveBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
1773 {
1774 /*    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */
1775
1776     FIXME("(iFrom = %u iTof = %u)\n",
1777            (UINT)wParam, (UINT)lParam);
1778
1779  
1780     return FALSE;
1781 }
1782
1783
1784 static LRESULT
1785 REBAR_SetBandInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1786 {
1787     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1788     LPREBARBANDINFOA lprbbi = (LPREBARBANDINFOA)lParam;
1789     REBAR_BAND *lpBand;
1790
1791     if (lprbbi == NULL)
1792         return FALSE;
1793     if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEA)
1794         return FALSE;
1795     if ((UINT)wParam >= infoPtr->uNumBands)
1796         return FALSE;
1797
1798     TRACE("index %u\n", (UINT)wParam);
1799     REBAR_DumpBandInfo (lprbbi);
1800
1801     /* set band information */
1802     lpBand = &infoPtr->bands[(UINT)wParam];
1803
1804     REBAR_CommonSetupBand (hwnd, lprbbi, lpBand);
1805     if (lprbbi->fMask & RBBIM_TEXT) {
1806         if (lpBand->lpText) {
1807             COMCTL32_Free (lpBand->lpText);
1808             lpBand->lpText = NULL;
1809         }
1810         if (lprbbi->lpText) {
1811             INT len = lstrlenA (lprbbi->lpText);
1812             lpBand->lpText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
1813             lstrcpyAtoW (lpBand->lpText, lprbbi->lpText);
1814         }
1815     }
1816
1817     REBAR_ValidateBand (hwnd, infoPtr, lpBand);
1818
1819     REBAR_DumpBand (hwnd);
1820
1821     if (lprbbi->fMask & (RBBIM_CHILDSIZE | RBBIM_SIZE)) {
1822       REBAR_Layout (hwnd, NULL, TRUE, FALSE);
1823       REBAR_ForceResize (hwnd);
1824       REBAR_MoveChildWindows (hwnd);
1825     }
1826
1827     return TRUE;
1828 }
1829
1830
1831 static LRESULT
1832 REBAR_SetBandInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
1833 {
1834     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1835     LPREBARBANDINFOW lprbbi = (LPREBARBANDINFOW)lParam;
1836     REBAR_BAND *lpBand;
1837
1838     if (lprbbi == NULL)
1839         return FALSE;
1840     if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEW)
1841         return FALSE;
1842     if ((UINT)wParam >= infoPtr->uNumBands)
1843         return FALSE;
1844
1845     TRACE("index %u\n", (UINT)wParam);
1846     REBAR_DumpBandInfo ((LPREBARBANDINFOA)lprbbi);
1847
1848     /* set band information */
1849     lpBand = &infoPtr->bands[(UINT)wParam];
1850
1851     REBAR_CommonSetupBand (hwnd, (LPREBARBANDINFOA)lprbbi, lpBand);
1852     if (lprbbi->fMask & RBBIM_TEXT) {
1853         if (lpBand->lpText) {
1854             COMCTL32_Free (lpBand->lpText);
1855             lpBand->lpText = NULL;
1856         }
1857         if (lprbbi->lpText) {
1858             INT len = lstrlenW (lprbbi->lpText);
1859             lpBand->lpText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
1860             strcpyW (lpBand->lpText, lprbbi->lpText);
1861         }
1862     }
1863
1864     REBAR_ValidateBand (hwnd, infoPtr, lpBand);
1865
1866     REBAR_DumpBand (hwnd);
1867
1868     if (lprbbi->fMask & (RBBIM_CHILDSIZE | RBBIM_SIZE)) {
1869       REBAR_Layout (hwnd, NULL, TRUE, FALSE);
1870       REBAR_ForceResize (hwnd);
1871       REBAR_MoveChildWindows (hwnd);
1872     }
1873
1874     return TRUE;
1875 }
1876
1877
1878 static LRESULT
1879 REBAR_SetBarInfo (HWND hwnd, WPARAM wParam, LPARAM lParam)
1880 {
1881     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1882     LPREBARINFO lpInfo = (LPREBARINFO)lParam;
1883
1884     if (lpInfo == NULL)
1885         return FALSE;
1886
1887     if (lpInfo->cbSize < sizeof (REBARINFO))
1888         return FALSE;
1889
1890     TRACE("setting bar info!\n");
1891
1892     if (lpInfo->fMask & RBIM_IMAGELIST) {
1893         infoPtr->himl = lpInfo->himl;
1894         if (infoPtr->himl) {
1895             INT cx, cy;
1896             ImageList_GetIconSize (infoPtr->himl, &cx, &cy);
1897             infoPtr->imageSize.cx = cx;
1898             infoPtr->imageSize.cy = cy;
1899         }
1900         else {
1901             infoPtr->imageSize.cx = 0;
1902             infoPtr->imageSize.cy = 0;
1903         }
1904         TRACE("new image cx=%ld, cy=%ld\n", infoPtr->imageSize.cx,
1905               infoPtr->imageSize.cy);
1906     }
1907
1908     return TRUE;
1909 }
1910
1911
1912 static LRESULT
1913 REBAR_SetBkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
1914 {
1915     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1916     COLORREF clrTemp;
1917
1918     clrTemp = infoPtr->clrBk;
1919     infoPtr->clrBk = (COLORREF)lParam;
1920
1921     TRACE("background color 0x%06lx!\n", infoPtr->clrBk);
1922
1923     return clrTemp;
1924 }
1925
1926
1927 /* << REBAR_SetColorScheme >> */
1928 /* << REBAR_SetPalette >> */
1929
1930
1931 static LRESULT
1932 REBAR_SetParent (HWND hwnd, WPARAM wParam, LPARAM lParam)
1933 {
1934     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1935     HWND hwndTemp = infoPtr->hwndNotify;
1936
1937     infoPtr->hwndNotify = (HWND)wParam;
1938
1939     return (LRESULT)hwndTemp;
1940 }
1941
1942
1943 static LRESULT
1944 REBAR_SetTextColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
1945 {
1946     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1947     COLORREF clrTemp;
1948
1949     clrTemp = infoPtr->clrText;
1950     infoPtr->clrText = (COLORREF)lParam;
1951
1952     TRACE("text color 0x%06lx!\n", infoPtr->clrText);
1953
1954     return clrTemp;
1955 }
1956
1957
1958 /* << REBAR_SetTooltips >> */
1959
1960
1961 inline static LRESULT
1962 REBAR_SetUnicodeFormat (HWND hwnd, WPARAM wParam)
1963 {
1964     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1965     BOOL bTemp = infoPtr->bUnicode;
1966     infoPtr->bUnicode = (BOOL)wParam;
1967     return bTemp;
1968 }
1969
1970
1971 static LRESULT
1972 REBAR_SetVersion (HWND hwnd, INT iVersion)
1973 {
1974     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1975     INT iOldVersion = infoPtr->iVersion;
1976
1977     if (iVersion > COMCTL32_VERSION)
1978         return -1;
1979
1980     infoPtr->iVersion = iVersion;
1981
1982     TRACE("new version %d\n", iVersion);
1983
1984     return iOldVersion;
1985 }
1986
1987
1988 static LRESULT
1989 REBAR_ShowBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
1990 {
1991     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1992     REBAR_BAND *lpBand;
1993
1994     if (((INT)wParam < 0) || ((INT)wParam > infoPtr->uNumBands))
1995         return FALSE;
1996
1997     lpBand = &infoPtr->bands[(INT)wParam];
1998
1999     if ((BOOL)lParam) {
2000         TRACE("show band %d\n", (INT)wParam);
2001         lpBand->fStyle = lpBand->fStyle & ~RBBS_HIDDEN;
2002         if (IsWindow (lpBand->hwndChild))
2003             ShowWindow (lpBand->hwndChild, SW_SHOW);
2004     }
2005     else {
2006         TRACE("hide band %d\n", (INT)wParam);
2007         lpBand->fStyle = lpBand->fStyle | RBBS_HIDDEN;
2008         if (IsWindow (lpBand->hwndChild))
2009             ShowWindow (lpBand->hwndChild, SW_SHOW);
2010     }
2011
2012     REBAR_Layout (hwnd, NULL, TRUE, FALSE);
2013     REBAR_ForceResize (hwnd);
2014     REBAR_MoveChildWindows (hwnd);
2015
2016     return TRUE;
2017 }
2018
2019
2020 static LRESULT
2021 REBAR_SizeToRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
2022 {
2023     LPRECT lpRect = (LPRECT)lParam;
2024     RECT t1;
2025
2026     if (lpRect == NULL)
2027        return FALSE;
2028
2029     TRACE("[%d %d %d %d]\n",
2030           lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
2031
2032     /*  what is going on???? */
2033     GetWindowRect(hwnd, &t1);
2034     TRACE("window rect [%d %d %d %d]\n",
2035           t1.left, t1.top, t1.right, t1.bottom);
2036     GetClientRect(hwnd, &t1);
2037     TRACE("client rect [%d %d %d %d]\n",
2038           t1.left, t1.top, t1.right, t1.bottom);
2039
2040     REBAR_Layout (hwnd, lpRect, TRUE, FALSE);
2041     REBAR_ForceResize (hwnd);
2042     REBAR_MoveChildWindows (hwnd);
2043     return TRUE;
2044 }
2045
2046
2047
2048 static LRESULT
2049 REBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
2050 {
2051     REBAR_INFO *infoPtr;
2052
2053     /* allocate memory for info structure */
2054     infoPtr = (REBAR_INFO *)COMCTL32_Alloc (sizeof(REBAR_INFO));
2055     SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
2056
2057     /* initialize info structure */
2058     infoPtr->iVersion = 0;
2059     infoPtr->clrBk = CLR_NONE;
2060     infoPtr->clrText = GetSysColor (COLOR_BTNTEXT);
2061
2062     infoPtr->bAutoResize = FALSE;
2063     infoPtr->hcurArrow = LoadCursorA (0, IDC_ARROWA);
2064     infoPtr->hcurHorz  = LoadCursorA (0, IDC_SIZEWEA);
2065     infoPtr->hcurVert  = LoadCursorA (0, IDC_SIZENSA);
2066     infoPtr->hcurDrag  = LoadCursorA (0, IDC_SIZEA);
2067
2068     infoPtr->bUnicode = IsWindowUnicode (hwnd);
2069
2070     if (GetWindowLongA (hwnd, GWL_STYLE) & RBS_AUTOSIZE)
2071         FIXME("style RBS_AUTOSIZE set!\n");
2072
2073 #if 0
2074     SendMessageA (hwnd, WM_NOTIFYFORMAT, (WPARAM)hwnd, NF_QUERY);
2075 #endif
2076
2077     TRACE("created!\n");
2078     return 0;
2079 }
2080
2081
2082 static LRESULT
2083 REBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
2084 {
2085     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2086     REBAR_BAND *lpBand;
2087     INT i;
2088
2089
2090     /* free rebar bands */
2091     if ((infoPtr->uNumBands > 0) && infoPtr->bands) {
2092         /* clean up each band */
2093         for (i = 0; i < infoPtr->uNumBands; i++) {
2094             lpBand = &infoPtr->bands[i];
2095
2096             /* delete text strings */
2097             if (lpBand->lpText) {
2098                 COMCTL32_Free (lpBand->lpText);
2099                 lpBand->lpText = NULL;
2100             }
2101             /* destroy child window */
2102             DestroyWindow (lpBand->hwndChild);
2103         }
2104
2105         /* free band array */
2106         COMCTL32_Free (infoPtr->bands);
2107         infoPtr->bands = NULL;
2108     }
2109
2110
2111
2112
2113     DeleteObject (infoPtr->hcurArrow);
2114     DeleteObject (infoPtr->hcurHorz);
2115     DeleteObject (infoPtr->hcurVert);
2116     DeleteObject (infoPtr->hcurDrag);
2117
2118
2119
2120
2121     /* free rebar info data */
2122     COMCTL32_Free (infoPtr);
2123     SetWindowLongA (hwnd, 0, 0);
2124     TRACE("destroyed!\n");
2125     return 0;
2126 }
2127
2128
2129 static LRESULT
2130 REBAR_GetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
2131 {
2132     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2133
2134     return (LRESULT)infoPtr->hFont;
2135 }
2136
2137
2138 #if 0
2139 static LRESULT
2140 REBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
2141 {
2142     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2143
2144     return 0;
2145 }
2146 #endif
2147
2148
2149 inline static LRESULT
2150 REBAR_NCCalcSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
2151 {
2152     if (GetWindowLongA (hwnd, GWL_STYLE) & WS_BORDER) {
2153         ((LPRECT)lParam)->left   += GetSystemMetrics(SM_CXEDGE);
2154         ((LPRECT)lParam)->top    += GetSystemMetrics(SM_CYEDGE);
2155         ((LPRECT)lParam)->right  -= GetSystemMetrics(SM_CXEDGE);
2156         ((LPRECT)lParam)->bottom -= GetSystemMetrics(SM_CYEDGE);
2157     }
2158
2159     return 0;
2160 }
2161
2162
2163 static LRESULT
2164 REBAR_NCPaint (HWND hwnd, WPARAM wParam, LPARAM lParam)
2165 {
2166     DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
2167     RECT rcWindow;
2168     HDC hdc;
2169
2170     if (dwStyle & WS_MINIMIZE)
2171         return 0; /* Nothing to do */
2172
2173     DefWindowProcA (hwnd, WM_NCPAINT, wParam, lParam);
2174
2175     if (!(hdc = GetDCEx( hwnd, 0, DCX_USESTYLE | DCX_WINDOW )))
2176         return 0;
2177
2178     if (dwStyle & WS_BORDER) {
2179         GetWindowRect (hwnd, &rcWindow);
2180         OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
2181         DrawEdge (hdc, &rcWindow, EDGE_ETCHED, BF_RECT);
2182     }
2183
2184     ReleaseDC( hwnd, hdc );
2185
2186     return 0;
2187 }
2188
2189
2190 static LRESULT
2191 REBAR_Paint (HWND hwnd, WPARAM wParam)
2192 {
2193     HDC hdc;
2194     PAINTSTRUCT ps;
2195
2196     hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
2197     REBAR_Refresh (hwnd, hdc);
2198     if (!wParam)
2199         EndPaint (hwnd, &ps);
2200     return 0;
2201 }
2202
2203
2204 static LRESULT
2205 REBAR_SetCursor (HWND hwnd, WPARAM wParam, LPARAM lParam)
2206 {
2207     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2208     DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
2209     POINT pt;
2210     UINT  flags;
2211
2212     TRACE("code=0x%X  id=0x%X\n", LOWORD(lParam), HIWORD(lParam));
2213
2214     GetCursorPos (&pt);
2215     ScreenToClient (hwnd, &pt);
2216
2217     REBAR_InternalHitTest (hwnd, &pt, &flags, NULL);
2218
2219     if (flags == RBHT_GRABBER) {
2220         if ((dwStyle & CCS_VERT) &&
2221             !(dwStyle & RBS_VERTICALGRIPPER))
2222             SetCursor (infoPtr->hcurVert);
2223         else
2224             SetCursor (infoPtr->hcurHorz);
2225     }
2226     else if (flags != RBHT_CLIENT)
2227         SetCursor (infoPtr->hcurArrow);
2228
2229     return 0;
2230 }
2231
2232
2233 static LRESULT
2234 REBAR_SetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
2235 {
2236     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2237     
2238     /* TEXTMETRIC32A tm; */
2239     HFONT hFont /*, hOldFont */;
2240     /* HDC32 hdc; */
2241
2242     infoPtr->hFont = (HFONT)wParam;
2243
2244     hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT);
2245 /*
2246     hdc = GetDC32 (0);
2247     hOldFont = SelectObject32 (hdc, hFont);
2248     GetTextMetrics32A (hdc, &tm);
2249     infoPtr->nHeight = tm.tmHeight + VERT_BORDER;
2250     SelectObject32 (hdc, hOldFont);
2251     ReleaseDC32 (0, hdc);
2252 */
2253     if (lParam) {
2254 /*
2255         REBAR_Layout (hwnd);
2256         hdc = GetDC32 (hwnd);
2257         REBAR_Refresh (hwnd, hdc);
2258         ReleaseDC32 (hwnd, hdc);
2259 */
2260     }
2261
2262     return 0;
2263 }
2264
2265 static LRESULT
2266 REBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
2267 {
2268     REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2269     RECT rcClient;
2270
2271     /* auto resize deadlock check */
2272     if (infoPtr->bAutoResize) {
2273         infoPtr->bAutoResize = FALSE;
2274         return 0;
2275     }
2276
2277     GetClientRect (hwnd, &rcClient);
2278     if ((lParam == 0) && (rcClient.right == 0) && (rcClient.bottom == 0)) {
2279       /* native control seems to do this */
2280       GetClientRect (GetParent(hwnd), &rcClient);
2281       TRACE("sizing rebar, message and client zero, parent client (%d,%d)\n", 
2282             rcClient.right, rcClient.bottom);
2283     }
2284     else {
2285       TRACE("sizing rebar to (%d,%d), client (%d,%d)\n", 
2286             LOWORD(lParam), HIWORD(lParam), rcClient.right, rcClient.bottom);
2287     }
2288
2289     REBAR_Layout (hwnd, &rcClient, FALSE, TRUE);
2290     REBAR_ForceResize (hwnd);
2291     REBAR_MoveChildWindows (hwnd);
2292
2293     return 0;
2294 }
2295
2296
2297 static LRESULT WINAPI
2298 REBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
2299 {
2300     TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n", hwnd, uMsg, wParam, lParam);
2301     if (!REBAR_GetInfoPtr (hwnd) && (uMsg != WM_CREATE))
2302             return DefWindowProcA (hwnd, uMsg, wParam, lParam);
2303     switch (uMsg)
2304     {
2305 /*      case RB_BEGINDRAG: */
2306
2307         case RB_DELETEBAND:
2308             return REBAR_DeleteBand (hwnd, wParam, lParam);
2309
2310 /*      case RB_DRAGMOVE: */
2311 /*      case RB_ENDDRAG: */
2312
2313         case RB_GETBANDBORDERS:
2314             return REBAR_GetBandBorders (hwnd, wParam, lParam);
2315
2316         case RB_GETBANDCOUNT:
2317             return REBAR_GetBandCount (hwnd);
2318
2319         case RB_GETBANDINFO:    /* obsoleted after IE3, but we have to
2320                                    support it anyway. */
2321         case RB_GETBANDINFOA:
2322             return REBAR_GetBandInfoA (hwnd, wParam, lParam);
2323
2324         case RB_GETBANDINFOW:
2325             return REBAR_GetBandInfoW (hwnd, wParam, lParam);
2326
2327         case RB_GETBARHEIGHT:
2328             return REBAR_GetBarHeight (hwnd, wParam, lParam);
2329
2330         case RB_GETBARINFO:
2331             return REBAR_GetBarInfo (hwnd, wParam, lParam);
2332
2333         case RB_GETBKCOLOR:
2334             return REBAR_GetBkColor (hwnd);
2335
2336 /*      case RB_GETCOLORSCHEME: */
2337 /*      case RB_GETDROPTARGET: */
2338
2339         case RB_GETPALETTE:
2340             return REBAR_GetPalette (hwnd, wParam, lParam);
2341
2342         case RB_GETRECT:
2343             return REBAR_GetRect (hwnd, wParam, lParam);
2344
2345         case RB_GETROWCOUNT:
2346             return REBAR_GetRowCount (hwnd);
2347
2348         case RB_GETROWHEIGHT:
2349             return REBAR_GetRowHeight (hwnd, wParam, lParam);
2350
2351         case RB_GETTEXTCOLOR:
2352             return REBAR_GetTextColor (hwnd);
2353
2354         case RB_GETTOOLTIPS:
2355             return REBAR_GetToolTips (hwnd);
2356
2357         case RB_GETUNICODEFORMAT:
2358             return REBAR_GetUnicodeFormat (hwnd);
2359
2360         case CCM_GETVERSION:
2361             return REBAR_GetVersion (hwnd);
2362
2363         case RB_HITTEST:
2364             return REBAR_HitTest (hwnd, wParam, lParam);
2365
2366         case RB_IDTOINDEX:
2367             return REBAR_IdToIndex (hwnd, wParam, lParam);
2368
2369         case RB_INSERTBANDA:
2370             return REBAR_InsertBandA (hwnd, wParam, lParam);
2371
2372         case RB_INSERTBANDW:
2373             return REBAR_InsertBandW (hwnd, wParam, lParam);
2374
2375         case RB_MAXIMIZEBAND:
2376             return REBAR_MaximizeBand (hwnd, wParam, lParam);
2377
2378         case RB_MINIMIZEBAND:
2379             return REBAR_MinimizeBand (hwnd, wParam, lParam);
2380
2381         case RB_MOVEBAND:
2382             return REBAR_MoveBand (hwnd, wParam, lParam);
2383
2384         case RB_SETBANDINFOA:
2385             return REBAR_SetBandInfoA (hwnd, wParam, lParam);
2386
2387         case RB_SETBANDINFOW:
2388             return REBAR_SetBandInfoW (hwnd, wParam, lParam);
2389
2390         case RB_SETBARINFO:
2391             return REBAR_SetBarInfo (hwnd, wParam, lParam);
2392
2393         case RB_SETBKCOLOR:
2394             return REBAR_SetBkColor (hwnd, wParam, lParam);
2395
2396 /*      case RB_SETCOLORSCHEME: */
2397 /*      case RB_SETPALETTE: */
2398 /*          return REBAR_GetPalette (hwnd, wParam, lParam); */
2399
2400         case RB_SETPARENT:
2401             return REBAR_SetParent (hwnd, wParam, lParam);
2402
2403         case RB_SETTEXTCOLOR:
2404             return REBAR_SetTextColor (hwnd, wParam, lParam);
2405
2406 /*      case RB_SETTOOLTIPS: */
2407
2408         case RB_SETUNICODEFORMAT:
2409             return REBAR_SetUnicodeFormat (hwnd, wParam);
2410
2411         case CCM_SETVERSION:
2412             return REBAR_SetVersion (hwnd, (INT)wParam);
2413
2414         case RB_SHOWBAND:
2415             return REBAR_ShowBand (hwnd, wParam, lParam);
2416
2417         case RB_SIZETORECT:
2418             return REBAR_SizeToRect (hwnd, wParam, lParam);
2419
2420
2421         case WM_COMMAND:
2422             return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
2423
2424         case WM_CREATE:
2425             return REBAR_Create (hwnd, wParam, lParam);
2426
2427         case WM_DESTROY:
2428             return REBAR_Destroy (hwnd, wParam, lParam);
2429
2430         case WM_GETFONT:
2431             return REBAR_GetFont (hwnd, wParam, lParam);
2432
2433 /*      case WM_MOUSEMOVE: */
2434 /*          return REBAR_MouseMove (hwnd, wParam, lParam); */
2435
2436         case WM_NCCALCSIZE:
2437             return REBAR_NCCalcSize (hwnd, wParam, lParam);
2438
2439         case WM_NCPAINT:
2440             return REBAR_NCPaint (hwnd, wParam, lParam);
2441
2442         case WM_NOTIFY:
2443             return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
2444
2445         case WM_PAINT:
2446             return REBAR_Paint (hwnd, wParam);
2447
2448         case WM_SETCURSOR:
2449             return REBAR_SetCursor (hwnd, wParam, lParam);
2450
2451         case WM_SETFONT:
2452             return REBAR_SetFont (hwnd, wParam, lParam);
2453
2454         case WM_SIZE:
2455             return REBAR_Size (hwnd, wParam, lParam);
2456         case WM_DRAWITEM:
2457             return SendMessageA(GetParent(hwnd),uMsg,wParam,lParam);
2458
2459 /*      case WM_TIMER: */
2460
2461 /*      case WM_WININICHANGE: */
2462
2463         default:
2464             if (uMsg >= WM_USER)
2465                 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
2466                      uMsg, wParam, lParam);
2467             return DefWindowProcA (hwnd, uMsg, wParam, lParam);
2468     }
2469     return 0;
2470 }
2471
2472
2473 VOID
2474 REBAR_Register (void)
2475 {
2476     WNDCLASSA wndClass;
2477
2478     ZeroMemory (&wndClass, sizeof(WNDCLASSA));
2479     wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS;
2480     wndClass.lpfnWndProc   = (WNDPROC)REBAR_WindowProc;
2481     wndClass.cbClsExtra    = 0;
2482     wndClass.cbWndExtra    = sizeof(REBAR_INFO *);
2483     wndClass.hCursor       = 0;
2484     wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
2485     wndClass.lpszClassName = REBARCLASSNAMEA;
2486  
2487     RegisterClassA (&wndClass);
2488 }
2489
2490
2491 VOID
2492 REBAR_Unregister (void)
2493 {
2494     UnregisterClassA (REBARCLASSNAMEA, (HINSTANCE)NULL);
2495 }
2496