/*
 * Rebar control    rev 5b
 *
 * Copyright 1998, 1999 Eric Kohl
 *
 * NOTES
 *   An author is needed! Any volunteers?
 *   I will only improve this control once in a while.
 *     Eric <ekohl@abo.rhein-zeitung.de>
 *
 * TODO:
 *   - vertical placement
 *   - ComboBox and ComboBoxEx placement
 *   - center image 
 *   - Layout code.
 *   - Display code.
 *   - Some messages.
 *   - All notifications.

 * Changes Guy Albertelli <galberte@neo.lrun.com>
 *  rev 2,3,4
 *   - Implement initial version of row grouping, row separators,
 *     text and background colors. Support additional messages. 
 *     Support RBBS_BREAK. Implement ERASEBKGND and improve painting.
 *  rev 5
 *  1. Support dragging by the Gripper for only left and right drags 
 *     within a row. (5a)
 *  2. Implement WM_LBUTTONDOWN, WM_LBUTTONUP, and WM_MOUSEMOVE.
 *  3. Support RBS_BANDBORDERS. 
 *  4. Total rewrite of MouseMove code to handle multiple bands in row. (5b)
 *  5. Fix drawing bugs.
 *
 *    Still to do:
 *  1. default row height should be the max height of all visible bands
 *  2. Following still not handled: RBBS_FIXEDBMP, RBBS_CHILDEDGE,
 *            RBBS_VARIABLEHEIGHT, RBBS_USECHEVRON
 *  3. GETBANDINFO seems to return correct colors in native but not here.

 */

#include <stdlib.h>
#include <string.h>

#include "winbase.h"
#include "wingdi.h"
#include "wine/unicode.h"
#include "commctrl.h"
#include "debugtools.h"

DEFAULT_DEBUG_CHANNEL(rebar);

typedef struct
{
    UINT    fStyle;
    UINT    fMask;
    COLORREF  clrFore;
    COLORREF  clrBack;
    INT     iImage;
    HWND    hwndChild;
    UINT    cxMinChild;
    UINT    cyMinChild;
    UINT    cx;
    HBITMAP hbmBack;
    UINT    wID;
    UINT    cyChild;
    UINT    cyMaxChild;
    UINT    cyIntegral;
    UINT    cxIdeal;
    LPARAM    lParam;
    UINT    cxHeader;

    UINT    lcx;            /* minimum cx for band */
    UINT    hcx;            /* maximum cx for band */
    UINT    lcy;            /* minimum cy for band */
    UINT    hcy;            /* maximum cy for band */

    SIZE    offChild;       /* x,y offset if child is not FIXEDSIZE */
    UINT    uMinHeight;
    INT     iRow;           /* row this band assigned to */
    UINT    fDraw;          /* drawing flags */
    RECT    rcBand;         /* calculated band rectangle */
    RECT    rcGripper;      /* calculated gripper rectangle */
    RECT    rcCapImage;     /* calculated caption image rectangle */
    RECT    rcCapText;      /* calculated caption text rectangle */
    RECT    rcChild;        /* calculated child rectangle */

    LPWSTR    lpText;
    HWND    hwndPrevParent;
} REBAR_BAND;

/* fDraw flags */
#define DRAW_GRIPPER    1
#define DRAW_IMAGE      2
#define DRAW_TEXT       4
#define DRAW_CHILD      8
#define DRAW_SEP        16


typedef struct
{
    COLORREF   clrBk;       /* background color */
    COLORREF   clrText;     /* text color */
    HIMAGELIST himl;        /* handle to imagelist */
    UINT     uNumBands;   /* number of bands in the rebar */
    UINT     uNumRows;    /* number of rows of bands */
    HWND     hwndToolTip; /* handle to the tool tip control */
    HWND     hwndNotify;  /* notification window (parent) */
    HFONT    hFont;       /* handle to the rebar's font */
    SIZE     imageSize;   /* image size (image list) */

    SIZE     calcSize;    /* calculated rebar size */
    BOOL     bUnicode;    /* Unicode flag */
    UINT     fStatus;     /* Status flags (see below)  */ 
    HCURSOR  hcurArrow;   /* handle to the arrow cursor */
    HCURSOR  hcurHorz;    /* handle to the EW cursor */
    HCURSOR  hcurVert;    /* handle to the NS cursor */
    HCURSOR  hcurDrag;    /* handle to the drag cursor */
    INT      iVersion;    /* version number */
    POINTS   dragStart;   /* x,y of button down */
    POINTS   dragNow;     /* x,y of this MouseMove */
    INT      ihitBand;    /* band number of band whose gripper was grabbed */
    INT      ihitoffset;  /* offset of hotspot from gripper.left */

    REBAR_BAND *bands;      /* pointer to the array of rebar bands */
} REBAR_INFO;

/* fStatus flags */
#define BEGIN_DRAG_ISSUED   1
#define AUTO_RESIZE         2


#define GRIPPER_WIDTH   8
#define GRIPPER_HEIGHT  16
#define SEP_WIDTH       3

/* This is the increment that is used over the band height */
/* Determined by experiment.                               */ 
#define REBARSPACE      4

#define REBAR_GetInfoPtr(wndPtr) ((REBAR_INFO *)GetWindowLongA (hwnd, 0))


/* "constant values" retrieved when DLL was initialized    */
/* FIXME we do this when the classes are registered.       */
static UINT mindragx = 0;
static UINT mindragy = 0;


static VOID
REBAR_DumpBandInfo( LPREBARBANDINFOA pB)
{
	TRACE("band info: ID=%u, size=%u, style=0x%08x, mask=0x%08x, child=%04x\n",
	  pB->wID, pB->cbSize, pB->fStyle, pB->fMask, pB->hwndChild); 
	TRACE("band info: cx=%u, xMin=%u, yMin=%u, yChild=%u, yMax=%u, yIntgl=%u\n",
          pB->cx, pB->cxMinChild, 
          pB->cyMinChild, pB->cyChild, pB->cyMaxChild, pB->cyIntegral);
	TRACE("band info: xIdeal=%u, xHeader=%u, lParam=0x%08lx, clrF=0x%06lx, clrB=0x%06lx\n",
	  pB->cxIdeal, pB->cxHeader, pB->lParam, pB->clrFore, pB->clrBack);
}

static VOID
REBAR_DumpBand (HWND hwnd)
{
    REBAR_INFO *iP = REBAR_GetInfoPtr (hwnd);
    REBAR_BAND *pB;
    UINT i;

    if( TRACE_ON(rebar) ) {

      TRACE("hwnd=%04x: color=%08lx/%08lx, bands=%u, rows=%u, cSize=%ld,%ld\n", 
        hwnd, iP->clrText, iP->clrBk, iP->uNumBands, iP->uNumRows,
        iP->calcSize.cx, iP->calcSize.cy);
      TRACE("hwnd=%04x: flags=%08x, dragStart=%d,%d, dragNow=%d,%d, ihitBand=%d\n",
	    hwnd, iP->fStatus, iP->dragStart.x, iP->dragStart.y,
	    iP->dragNow.x, iP->dragNow.y,
	    iP->ihitBand);
      for (i = 0; i < iP->uNumBands; i++) {
	pB = &iP->bands[i];
	TRACE("band # %u: ID=%u, mask=0x%08x, style=0x%08x, child=%04x, row=%u\n",
	  i, pB->wID, pB->fMask, pB->fStyle, pB->hwndChild, pB->iRow);
	TRACE("band # %u: xMin=%u, yMin=%u, cx=%u, yChild=%u, yMax=%u, yIntgl=%u, uMinH=%u,\n",
	  i, pB->cxMinChild, pB->cyMinChild, pB->cx,
          pB->cyChild, pB->cyMaxChild, pB->cyIntegral, pB->uMinHeight);
	TRACE("band # %u: header=%u, lcx=%u, hcx=%u, lcy=%u, hcy=%u, offChild=%ld,%ld\n",
	  i, pB->cxHeader, pB->lcx, pB->hcx, pB->lcy, pB->hcy, pB->offChild.cx, pB->offChild.cy);
	TRACE("band # %u: fDraw=%08x, Band=(%d,%d)-(%d,%d), Grip=(%d,%d)-(%d,%d)\n",
	  i, pB->fDraw,
	  pB->rcBand.left, pB->rcBand.top, pB->rcBand.right, pB->rcBand.bottom,
	  pB->rcGripper.left, pB->rcGripper.top, pB->rcGripper.right, pB->rcGripper.bottom);
	TRACE("band # %u: Img=(%d,%d)-(%d,%d), Txt=(%d,%d)-(%d,%d), Child=(%d,%d)-(%d,%d)\n",
	  i,
	  pB->rcCapImage.left, pB->rcCapImage.top, pB->rcCapImage.right, pB->rcCapImage.bottom,
	  pB->rcCapText.left, pB->rcCapText.top, pB->rcCapText.right, pB->rcCapText.bottom,
	  pB->rcChild.left, pB->rcChild.top, pB->rcChild.right, pB->rcChild.bottom);
      }

    }
}

static void
REBAR_Notify (HWND hwnd, NMHDR *nmhdr, UINT code)
{
    HWND parent, owner;

    parent = GetParent (hwnd);
    owner = GetWindow (hwnd, GW_OWNER);
    if (owner) parent = owner;
    nmhdr->idFrom = GetDlgCtrlID (hwnd);
    nmhdr->hwndFrom = hwnd;
    nmhdr->code = code;

    SendMessageA (parent, WM_NOTIFY, (WPARAM) nmhdr->idFrom,
		      (LPARAM)nmhdr);
}

static VOID
REBAR_DrawBand (HDC hdc, REBAR_INFO *infoPtr, REBAR_BAND *lpBand, DWORD dwStyle)
{

    /* draw separator */
    if (lpBand->fDraw & DRAW_SEP) {
        RECT rcSep;
	if (dwStyle & CCS_VERT)
	  SetRect (&rcSep, lpBand->rcBand.left-2, lpBand->rcBand.top-SEP_WIDTH,
		   lpBand->rcBand.right+2, lpBand->rcBand.top-1);
	else
	  SetRect (&rcSep, lpBand->rcBand.left-SEP_WIDTH, lpBand->rcBand.top-2,
		   lpBand->rcBand.left-1, lpBand->rcBand.bottom+2);
	TRACE("drawing band separator (%d,%d)-(%d,%d)\n",
	      rcSep.left, rcSep.top, rcSep.right, rcSep.bottom);
	DrawEdge (hdc, &rcSep, EDGE_ETCHED, BF_LEFT | BF_TOP | BF_MIDDLE);
    }

    /* draw gripper */
    if (lpBand->fDraw & DRAW_GRIPPER)
        DrawEdge (hdc, &lpBand->rcGripper, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE);

    /* draw caption image */
    if (lpBand->fDraw & DRAW_IMAGE) {
	POINT pt;

	/* center image */
	pt.y = (lpBand->rcCapImage.bottom + lpBand->rcCapImage.top - infoPtr->imageSize.cy)/2;
	pt.x = (lpBand->rcCapImage.right + lpBand->rcCapImage.left - infoPtr->imageSize.cx)/2;

	ImageList_Draw (infoPtr->himl, lpBand->iImage, hdc,
			pt.x, pt.y,
			ILD_TRANSPARENT);
    }

    /* draw caption text */
    if (lpBand->fDraw & DRAW_TEXT) {
	HFONT hOldFont = SelectObject (hdc, infoPtr->hFont);
	INT oldBkMode = SetBkMode (hdc, TRANSPARENT);
	COLORREF oldcolor = CLR_NONE;
	if (lpBand->clrFore != CLR_NONE)
	    oldcolor = SetTextColor (hdc, lpBand->clrFore);
	DrawTextW (hdc, lpBand->lpText, -1, &lpBand->rcCapText,
		     DT_CENTER | DT_VCENTER | DT_SINGLELINE);
	if (oldBkMode != TRANSPARENT)
	    SetBkMode (hdc, oldBkMode);
	if (lpBand->clrFore != CLR_NONE)
	    SetTextColor (hdc, oldcolor);
	SelectObject (hdc, hOldFont);
    }
}


static VOID
REBAR_Refresh (HWND hwnd, HDC hdc)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    REBAR_BAND *lpBand;
    UINT i, oldrow;
    RECT rcRowSep;
    DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);

    oldrow = infoPtr->bands[0].iRow;
    for (i = 0; i < infoPtr->uNumBands; i++) {
	lpBand = &infoPtr->bands[i];

	if ((lpBand->fStyle & RBBS_HIDDEN) || 
	    ((dwStyle & CCS_VERT) &&
	     (lpBand->fStyle & RBBS_NOVERT)))
	    continue;

	/* if a new row then draw a separator */
	if (oldrow != lpBand->iRow) {
	    if (dwStyle & RBS_BANDBORDERS) {
	        if (dwStyle & CCS_VERT) {
	            SetRect (&rcRowSep, lpBand->rcBand.left-2, 0,
			     lpBand->rcBand.left-1, infoPtr->calcSize.cy);
		}
		else {
		    SetRect (&rcRowSep, 0, lpBand->rcBand.top-2,
			     infoPtr->calcSize.cx, lpBand->rcBand.top-1);
		}
		TRACE ("drawing row sep (%d,%d)-(%d,%d)\n",
		       rcRowSep.left, rcRowSep.top,
		       rcRowSep.right, rcRowSep.bottom);
		DrawEdge (hdc, &rcRowSep, EDGE_ETCHED, BF_TOP|BF_LEFT);
		oldrow = lpBand->iRow;
	    }
	}

	/* now draw the band */
	REBAR_DrawBand (hdc, infoPtr, lpBand, dwStyle);

    }
}

static void
REBAR_AdjustBands (REBAR_INFO *infoPtr, UINT rowstart, UINT rowend,
		   INT maxx, INT usedx, INT mcy, DWORD dwStyle)
     /* Function: This routine distributes the extra space in a row */
     /*  evenly over the adjustable bands in the row. It also makes */
     /*  sure that all bands in the row are the same height.        */
{
    REBAR_BAND *lpBand;
    UINT i, j;
    INT incr, lastx=0;

    TRACE("start=%u, end=%u, max x=%d, used x=%d, max y=%d\n",
	  rowstart, rowend-1, maxx, usedx, mcy);

    j = 0;
    for (i = rowstart; i<rowend; i++) {
      lpBand = &infoPtr->bands[i];
      if ((lpBand->fMask & RBBIM_CHILD) && lpBand->hwndChild &&
	  !(lpBand->fStyle & RBBS_FIXEDSIZE)) 
         j++;
    }
    if (j)
      incr = (maxx-usedx) / j;
    else
      incr = 0;

    TRACE("adjusting %u of %u bands in row, incr=%d\n", 
	  j, rowend-rowstart, incr);

    for (i = rowstart; i<rowend; i++) {
      lpBand = &infoPtr->bands[i];
      if (dwStyle & CCS_VERT) {
        lpBand->rcBand.bottom = lastx + 
                                lpBand->rcBand.bottom - lpBand->rcBand.top;
        if ((lpBand->fMask & RBBIM_CHILD) && lpBand->hwndChild &&
	    !(lpBand->fStyle & RBBS_FIXEDSIZE)) {
           /* if a child window exists and not fixed then widen it */
           lpBand->rcBand.bottom += incr;
        }
        lpBand->rcBand.top = lastx;
        lastx = lpBand->rcBand.bottom + 1;
        lpBand->rcBand.right = lpBand->rcBand.left + mcy;
      }
      else {
        lpBand->rcBand.right = lastx + 
                               lpBand->rcBand.right - lpBand->rcBand.left;
        if ((lpBand->fMask & RBBIM_CHILD) && lpBand->hwndChild &&
	    !(lpBand->fStyle & RBBS_FIXEDSIZE)) {
           /* if a child window exists and not fixed then widen it */
           lpBand->rcBand.right += incr;
        }
        lpBand->rcBand.left = lastx;
        lastx = lpBand->rcBand.right + 1;
        lpBand->rcBand.bottom = lpBand->rcBand.top + mcy;
      }
    }

}

static void
REBAR_CalcHorzBand (HWND hwnd, REBAR_INFO *infoPtr, UINT rstart, UINT rend, BOOL notify, DWORD dwStyle)
     /* Function: this routine initializes all the rectangles in */
     /*  each band in a row to fit in the adjusted rcBand rect.  */
     /* *** Supports only Horizontal bars. ***                   */
{
    REBAR_BAND *lpBand;
    UINT i, xoff, yoff;
    NMREBARCHILDSIZE  rbcz;
    HWND parenthwnd;
    RECT oldChild;

    rbcz.hdr.hwndFrom = hwnd;
    rbcz.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
    /* MS seems to use GetDlgCtrlID() for above GetWindowLong call */
    parenthwnd = GetParent (hwnd);

    for(i=rstart; i<rend; i++){
      lpBand = &infoPtr->bands[i];
      oldChild = lpBand->rcChild;

      /* set initial gripper rectangle */
      SetRect (&lpBand->rcGripper, lpBand->rcBand.left, lpBand->rcBand.top,
	     lpBand->rcBand.left, lpBand->rcBand.bottom);

      /* calculate gripper rectangle */
      if ((!(lpBand->fStyle & RBBS_NOGRIPPER)) &&
	  (!(lpBand->fStyle & RBBS_FIXEDSIZE)) &&
	  ((lpBand->fStyle & RBBS_GRIPPERALWAYS) || 
	   (infoPtr->uNumBands > 1))) {
	lpBand->fDraw |= DRAW_GRIPPER;
	lpBand->rcGripper.left   += 1;
	lpBand->rcGripper.right  = lpBand->rcGripper.left + 3;
	lpBand->rcGripper.top    += 3;
	lpBand->rcGripper.bottom -= 3;

	SetRect (&lpBand->rcCapImage, lpBand->rcGripper.left + GRIPPER_WIDTH,
		 lpBand->rcBand.top, lpBand->rcGripper.left + GRIPPER_WIDTH,
		 lpBand->rcBand.bottom);
      }
      else {
	SetRect (&lpBand->rcCapImage, lpBand->rcBand.left, lpBand->rcBand.top,
		 lpBand->rcBand.left, lpBand->rcBand.bottom);
      }

      /* image is visible */
      if ((lpBand->fMask & RBBIM_IMAGE) && (infoPtr->himl)) {
	lpBand->fDraw |= DRAW_IMAGE;

	lpBand->rcCapImage.right  += infoPtr->imageSize.cx;
	lpBand->rcCapImage.bottom = lpBand->rcCapImage.top + infoPtr->imageSize.cy;

	/* update band height */
	if (lpBand->uMinHeight < infoPtr->imageSize.cy + 2) {
	    lpBand->uMinHeight = infoPtr->imageSize.cy + 2;
	    lpBand->rcBand.bottom = lpBand->rcBand.top + lpBand->uMinHeight;
	}
      }

      /* set initial caption text rectangle */
      SetRect (&lpBand->rcCapText, lpBand->rcCapImage.right, lpBand->rcBand.top+1,
	       lpBand->rcCapImage.right, lpBand->rcBand.bottom-1);

      /* text is visible */
      if ((lpBand->fMask & RBBIM_TEXT) && (lpBand->lpText)) {
	HDC hdc = GetDC (0);
	HFONT hOldFont = SelectObject (hdc, infoPtr->hFont);
	SIZE size;

	lpBand->fDraw |= DRAW_TEXT;
	GetTextExtentPoint32W (hdc, lpBand->lpText,
			       lstrlenW (lpBand->lpText), &size);
	lpBand->rcCapText.right += (size.cx + 2);

	SelectObject (hdc, hOldFont);
	ReleaseDC (0, hdc);
      }

      /* set initial child window rectangle if there is a child */
      if (lpBand->fMask & RBBIM_CHILD) {
	xoff = lpBand->offChild.cx;
	yoff = lpBand->offChild.cy;
        SetRect (&lpBand->rcChild,
	         lpBand->rcBand.left+lpBand->cxHeader+xoff, lpBand->rcBand.top+yoff,
	         lpBand->rcBand.right-xoff, lpBand->rcBand.bottom-yoff);
      }
      else {
        SetRect (&lpBand->rcChild,
	         lpBand->rcCapText.right, lpBand->rcBand.top,
	         lpBand->rcBand.right, lpBand->rcBand.bottom);
      }

#if 1
      /* do notify is child rectangle changed */
      if (notify && !EqualRect (&oldChild, &lpBand->rcChild)) {
	TRACE("Child rectangle changed for band %u\n", i);
	TRACE("    from (%d,%d)-(%d,%d)  to (%d,%d)-(%d,%d)\n",
		oldChild.left, oldChild.top,
	        oldChild.right, oldChild.bottom,
		lpBand->rcChild.left, lpBand->rcChild.top,
	        lpBand->rcChild.right, lpBand->rcChild.bottom);
	rbcz.hdr.code = RBN_CHILDSIZE;
	rbcz.uBand = i;
	rbcz.wID = lpBand->wID;
	rbcz.rcChild = lpBand->rcChild;
	rbcz.rcBand = lpBand->rcBand;
	SendMessageA (parenthwnd, WM_NOTIFY, (WPARAM) rbcz.hdr.idFrom, 
		      (LPARAM)&rbcz);
	if (!EqualRect (&lpBand->rcChild, &rbcz.rcChild)) {
	  TRACE("Child rect changed by NOTIFY for band %u\n", i);
	  TRACE("    from (%d,%d)-(%d,%d)  to (%d,%d)-(%d,%d)\n",
		lpBand->rcChild.left, lpBand->rcChild.top,
		lpBand->rcChild.right, lpBand->rcChild.bottom,
		rbcz.rcChild.left, rbcz.rcChild.top,
		rbcz.rcChild.right, rbcz.rcChild.bottom);
	}
      }
#endif

    }

}


static VOID
REBAR_CalcVertBand (HWND hwnd, REBAR_INFO *infoPtr, UINT rstart, UINT rend, BOOL notify, DWORD dwStyle)
     /* Function: this routine initializes all the rectangles in */
     /*  each band in a row to fit in the adjusted rcBand rect.  */
     /* *** Supports only Vertical bars. ***                     */
{
    REBAR_BAND *lpBand;
    UINT i, xoff, yoff;
    NMREBARCHILDSIZE  rbcz;
    HWND parenthwnd;
    RECT oldChild;

    rbcz.hdr.hwndFrom = hwnd;
    rbcz.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
    /* MS seems to use GetDlgCtrlID() for above GetWindowLong call */
    parenthwnd = GetParent (hwnd);

    for(i=rstart; i<rend; i++){
      lpBand = &infoPtr->bands[i];
      oldChild = lpBand->rcChild;

      /* set initial gripper rectangle */
      SetRect (&lpBand->rcGripper, lpBand->rcBand.left, lpBand->rcBand.top,
	     lpBand->rcBand.right, lpBand->rcBand.top);

      /* calculate gripper rectangle */
      if ((!(lpBand->fStyle & RBBS_NOGRIPPER)) &&
	  (!(lpBand->fStyle & RBBS_FIXEDSIZE)) &&
	  ((lpBand->fStyle & RBBS_GRIPPERALWAYS) || 
	   (infoPtr->uNumBands > 1))) {
	lpBand->fDraw |= DRAW_GRIPPER;

	if (dwStyle & RBS_VERTICALGRIPPER) {
	    /*  vertical gripper  */
	    lpBand->rcGripper.left   += 3;
	    lpBand->rcGripper.right  = lpBand->rcGripper.left + 3;
	    lpBand->rcGripper.top    += 3;
	    lpBand->rcGripper.bottom = lpBand->rcGripper.top + GRIPPER_HEIGHT;

	    /* initialize Caption image rectangle  */
	    SetRect (&lpBand->rcCapImage, lpBand->rcBand.left,
		     lpBand->rcGripper.top + GRIPPER_HEIGHT,
		     lpBand->rcBand.right,
		     lpBand->rcGripper.top + GRIPPER_HEIGHT);
	}
	else {
	    /*  horizontal gripper  */
	    lpBand->rcGripper.left   += 3;
	    lpBand->rcGripper.right  -= 3;
	    lpBand->rcGripper.top    += 3;
	    lpBand->rcGripper.bottom  = lpBand->rcGripper.top + 3;

	    /* initialize Caption image rectangle  */
	    SetRect (&lpBand->rcCapImage, lpBand->rcBand.left,
		     lpBand->rcGripper.top + GRIPPER_WIDTH,
		     lpBand->rcBand.right,
		     lpBand->rcGripper.top + GRIPPER_WIDTH);
	}
      }
      else {
	/* initialize Caption image rectangle  */
	SetRect (&lpBand->rcCapImage, lpBand->rcBand.left, lpBand->rcBand.top,
		 lpBand->rcBand.right, lpBand->rcBand.top);
      }

      /* image is visible */
      if ((lpBand->fMask & RBBIM_IMAGE) && (infoPtr->himl)) {
	lpBand->fDraw |= DRAW_IMAGE;

	lpBand->rcCapImage.right  += infoPtr->imageSize.cx;
	lpBand->rcCapImage.bottom += infoPtr->imageSize.cy;

	/* update band height */
	if (lpBand->uMinHeight < infoPtr->imageSize.cx + 2) {
	    lpBand->uMinHeight = infoPtr->imageSize.cx + 2;
	    lpBand->rcBand.right = lpBand->rcBand.left + lpBand->uMinHeight;
	}
      }

      /* set initial caption text rectangle */
      lpBand->rcCapText.left   = lpBand->rcBand.left + 1;
      lpBand->rcCapText.top    = lpBand->rcCapImage.bottom;
      lpBand->rcCapText.right  = lpBand->rcBand.right - 1;
      lpBand->rcCapText.bottom = lpBand->rcCapText.top;

      /* text is visible */
      if (lpBand->lpText) {
	HDC hdc = GetDC (0);
	HFONT hOldFont = SelectObject (hdc, infoPtr->hFont);
	SIZE size;

	lpBand->fDraw |= DRAW_TEXT;
	GetTextExtentPoint32W (hdc, lpBand->lpText,
			       lstrlenW (lpBand->lpText), &size);
	lpBand->rcCapText.bottom += (size.cy + 2);

	SelectObject (hdc, hOldFont);
	ReleaseDC (0, hdc);
      }

      /* set initial child window rectangle if there is a child */
      if (lpBand->fMask & RBBIM_CHILD) {
	yoff = lpBand->offChild.cx;
	xoff = lpBand->offChild.cy;
        SetRect (&lpBand->rcChild,
	         lpBand->rcBand.left+xoff, 
		 lpBand->rcBand.top+lpBand->cxHeader+yoff,
	         lpBand->rcBand.right-xoff, lpBand->rcBand.bottom-yoff);
      }
      else {
        SetRect (&lpBand->rcChild,
	         lpBand->rcBand.left, lpBand->rcCapText.bottom,
	         lpBand->rcBand.right, lpBand->rcBand.top);
      }

#if 1
      /* do notify is child rectangle changed */
      if (notify && !EqualRect (&oldChild, &lpBand->rcChild)) {
	TRACE("Child rectangle changed for band %u\n", i);
	TRACE("    from (%d,%d)-(%d,%d)  to (%d,%d)-(%d,%d)\n",
	      oldChild.left, oldChild.top,
	      oldChild.right, oldChild.bottom,
	      lpBand->rcChild.left, lpBand->rcChild.top,
	      lpBand->rcChild.right, lpBand->rcChild.bottom);
	rbcz.hdr.code = RBN_CHILDSIZE;
	rbcz.uBand = i;
	rbcz.wID = lpBand->wID;
	rbcz.rcChild = lpBand->rcChild;
	rbcz.rcBand = lpBand->rcBand;
	SendMessageA (parenthwnd, WM_NOTIFY, (WPARAM) rbcz.hdr.idFrom, 
		      (LPARAM)&rbcz);
	if (!EqualRect (&lpBand->rcChild, &rbcz.rcChild)) {
	  TRACE("Child rect changed by NOTIFY for band %u\n", i);
	  TRACE("    from (%d,%d)-(%d,%d)  to (%d,%d)-(%d,%d)\n",
		lpBand->rcChild.left, lpBand->rcChild.top,
		lpBand->rcChild.right, lpBand->rcChild.bottom,
		rbcz.rcChild.left, rbcz.rcChild.top,
		rbcz.rcChild.right, rbcz.rcChild.bottom);
	}
      }
#endif

    }
}


static VOID
REBAR_Layout (HWND hwnd, LPRECT lpRect, BOOL notify, BOOL resetclient)
     /* Function: This routine is resposible for laying out all */
     /*  the bands in a rebar. It assigns each band to a row and*/
     /*  determines when to start a new row.                    */
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
    REBAR_BAND *lpBand;
    RECT rcClient, rcAdj;
    INT x, y, cx, cxsep, mcy, clientcx, clientcy, adjcx, adjcy, row, rightx, bottomy;
    UINT i, rowstartband;
    BOOL dobreak;

    GetClientRect (hwnd, &rcClient);
    TRACE("Client is (%d,%d)-(%d,%d)\n",
	  rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);

    if (lpRect) {
	rcAdj = *lpRect;
	TRACE("adjustment rect is (%d,%d)-(%d,%d)\n",
	      rcAdj.left, rcAdj.top, rcAdj.right, rcAdj.bottom);
    }
    else {
      CopyRect (&rcAdj, &rcClient);
    }

    clientcx = rcClient.right - rcClient.left;
    clientcy = rcClient.bottom - rcClient.top;
    adjcx = rcAdj.right - rcAdj.left;
    adjcy = rcAdj.bottom - rcAdj.top;
    if (resetclient) {
      TRACE("window client rect will be set to adj rect\n");
      clientcx = adjcx;
      clientcy = adjcy;
    }
    x = 0;
    y = 0;
    rowstartband = 0;
    row = 1;
    cx = 0;
    mcy = 0;

    for (i = 0; i < infoPtr->uNumBands; i++) {
	lpBand = &infoPtr->bands[i];
	lpBand->fDraw = 0;
	lpBand->iRow = row;

	if ((lpBand->fStyle & RBBS_HIDDEN) || 
	    ((dwStyle & CCS_VERT) && (lpBand->fStyle & RBBS_NOVERT)))
	    continue;

	cxsep = (x==0) ? 0 : SEP_WIDTH;  /* separator from previous band */
	cx = lpBand->cxHeader +   /* Header: includes gripper, text, image */
             lpBand->hcx;         /* coumpted size of child */
	if (dwStyle & CCS_VERT)
	  dobreak = (y + cx + cxsep > adjcy);
        else
	  dobreak = (x + cx + cxsep > adjcx);
	/* This is the check for whether we need to start a new row */
	if ( ( (lpBand->fStyle & RBBS_BREAK) && (i != 0) ) ||
	     ( ((dwStyle & CCS_VERT) ? (y != 0) : (x != 0)) && dobreak)) {
	  INT borders;

	  TRACE("Spliting to new row %d on band %u\n", row+1, i);
	  borders = (dwStyle & RBS_BANDBORDERS) ? 2 : 0;
	  if (dwStyle & CCS_VERT) {
	    /* first adjust all bands in previous current row to */
	    /* redistribute extra x pixels                       */
	    REBAR_AdjustBands (infoPtr, rowstartband, i,
			       clientcy, y, mcy, dwStyle);
	    /* calculate band subrectangles and break to new row */
	    REBAR_CalcVertBand (hwnd, infoPtr, rowstartband, i,
				notify, dwStyle);
	    y = 0;
	    x += (mcy + borders);
	  }
	  else {
	    /* first adjust all bands in previous current row to */
	    /* redistribute extra x pixels                       */
	    REBAR_AdjustBands (infoPtr, rowstartband, i,
			       clientcx, x, mcy, dwStyle);
	    /* calculate band subrectangles and break to new row */
	    REBAR_CalcHorzBand (hwnd, infoPtr, rowstartband, i,
				notify, dwStyle);
	    x = 0;
	    y += (mcy + borders);
	  }

	  /* FIXME: if not RBS_VARHEIGHT then find max */
	  mcy = 0;
	  cxsep = 0;
	  row++;
	  rowstartband = i;
	  lpBand->iRow = row;
	}

	if (mcy < lpBand->lcy + REBARSPACE) mcy = lpBand->lcy + REBARSPACE;

	/* if boundary rect specified then limit mcy */
	if (lpRect) {
	  if (dwStyle & CCS_VERT) {
	    if (x+mcy > adjcx) {
	      mcy = adjcx - x;
	      TRACE("row %u limiting mcy=%d, adjcx=%d, x=%d\n",
		    i, mcy, adjcx, x);
	    }
	  }
	  else {
	    if (y+mcy > adjcy) {
	      mcy = adjcy - y;
	      TRACE("row %u limiting mcy=%d, adjcy=%d, y=%d\n",
		    i, mcy, adjcy, y);
	    }
	  }
	}

	if (dwStyle & CCS_VERT) {
	  /* bound the bottom side if we have a bounding rectangle */
	  lpBand->fDraw |= (y==0) ? 0 : DRAW_SEP;
	  rightx = clientcx;
	  bottomy = (lpRect) ? min(clientcy, y+cxsep+cx) : y+cxsep+cx;
	  lpBand->rcBand.left   = x;
	  lpBand->rcBand.right  = y + min(mcy, lpBand->lcy+REBARSPACE);
	  lpBand->rcBand.top    = min(bottomy, y + cxsep);
	  lpBand->rcBand.bottom = bottomy;
	  lpBand->uMinHeight = lpBand->lcy;
	  y = bottomy;
	}
	else {
	  /* bound the right side if we have a bounding rectangle */
	  lpBand->fDraw |= (x==0) ? 0 : DRAW_SEP;
	  rightx = (lpRect) ? min(clientcx, x+cxsep+cx) : x+cxsep+cx;
	  bottomy = clientcy;
	  lpBand->rcBand.left   = min(rightx, x + cxsep);
	  lpBand->rcBand.right  = rightx;
	  lpBand->rcBand.top    = y;
	  lpBand->rcBand.bottom = y + min(mcy, lpBand->lcy+REBARSPACE);
	  lpBand->uMinHeight = lpBand->lcy;
	  x = rightx;
	}
	TRACE("band %u, row %d, (%d,%d)-(%d,%d)\n",
	      i, row,
	      lpBand->rcBand.left, lpBand->rcBand.top,
	      lpBand->rcBand.right, lpBand->rcBand.bottom);

    }
    if (infoPtr->uNumBands) {
      infoPtr->uNumRows = row;

      if (dwStyle & CCS_VERT) {
	REBAR_AdjustBands (infoPtr, rowstartband, infoPtr->uNumBands,
			   clientcy, y, mcy, dwStyle);
	REBAR_CalcVertBand (hwnd, infoPtr, rowstartband, infoPtr->uNumBands,
			    notify, dwStyle);
	x += mcy;
      }
      else {
	REBAR_AdjustBands (infoPtr, rowstartband, infoPtr->uNumBands,
			   clientcx, x, mcy, dwStyle);
	REBAR_CalcHorzBand (hwnd, infoPtr, rowstartband, infoPtr->uNumBands, 
			    notify, dwStyle);
	y += mcy;
      }
    }

    /* FIXME: if not RBS_VARHEIGHT then find max mcy and adj rect*/

    if (dwStyle & CCS_VERT) {
	infoPtr->calcSize.cx = x;
	infoPtr->calcSize.cy = clientcy;
    }
    else {
	infoPtr->calcSize.cx = clientcx;
	infoPtr->calcSize.cy = y;
    }
    REBAR_DumpBand (hwnd);
}


static VOID
REBAR_ForceResize (HWND hwnd)
     /* Function: This changes the size of the REBAR window to that */
     /*  calculated by REBAR_Layout.                                */
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    RECT rc;

    TRACE( " to [%ld x %ld]!\n",
	   infoPtr->calcSize.cx, infoPtr->calcSize.cy);

    infoPtr->fStatus |= AUTO_RESIZE;

    rc.left = 0;
    rc.top = 0;
    rc.right  = infoPtr->calcSize.cx;
    rc.bottom = infoPtr->calcSize.cy;

    if (GetWindowLongA (hwnd, GWL_STYLE) & WS_BORDER) {
	InflateRect (&rc, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
    }

    SetWindowPos (hwnd, 0, 0, 0,
		    rc.right - rc.left, rc.bottom - rc.top,
		    SWP_NOMOVE | SWP_NOZORDER | SWP_SHOWWINDOW);
}


static VOID
REBAR_MoveChildWindows (HWND hwnd)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    REBAR_BAND *lpBand;
    CHAR szClassName[40];
    UINT i;

    for (i = 0; i < infoPtr->uNumBands; i++) {
	lpBand = &infoPtr->bands[i];

	if (lpBand->fStyle & RBBS_HIDDEN)
	    continue;
	if (lpBand->hwndChild) {
	    TRACE("hwndChild = %x\n", lpBand->hwndChild);

	    GetClassNameA (lpBand->hwndChild, szClassName, 40);
	    if (!lstrcmpA (szClassName, "ComboBox")) {
		INT nEditHeight, yPos;
		RECT rc;

		/* special placement code for combo box */


		/* get size of edit line */
		GetWindowRect (lpBand->hwndChild, &rc);
		nEditHeight = rc.bottom - rc.top;
		yPos = (lpBand->rcChild.bottom + lpBand->rcChild.top - nEditHeight)/2;

		/* center combo box inside child area */
		TRACE("moving child %04x to (%d,%d)-(%d,%d)\n",
		      lpBand->hwndChild,
		      lpBand->rcChild.left, yPos,
		      lpBand->rcChild.right - lpBand->rcChild.left,
		      nEditHeight);
		SetWindowPos (lpBand->hwndChild, HWND_TOP,
			    lpBand->rcChild.left, /*lpBand->rcChild.top*/ yPos,
			    lpBand->rcChild.right - lpBand->rcChild.left,
			    nEditHeight,
			    SWP_SHOWWINDOW);
	    }
#if 0
	    else if (!lstrcmpA (szClassName, WC_COMBOBOXEXA)) {
		INT nEditHeight, yPos;
		RECT rc;
		HWND hwndEdit;

		/* special placement code for extended combo box */

		/* get size of edit line */
		hwndEdit = SendMessageA (lpBand->hwndChild, CBEM_GETEDITCONTROL, 0, 0);
		GetWindowRect (hwndEdit, &rc);
		nEditHeight = rc.bottom - rc.top;
		yPos = (lpBand->rcChild.bottom + lpBand->rcChild.top - nEditHeight)/2;

		/* center combo box inside child area */
		TRACE("moving child %04x to (%d,%d)-(%d,%d)\n",
		      lpBand->hwndChild,
		      lpBand->rcChild.left, yPos,
		      lpBand->rcChild.right - lpBand->rcChild.left,
		      nEditHeight);
		SetWindowPos (lpBand->hwndChild, HWND_TOP,
			    lpBand->rcChild.left, /*lpBand->rcChild.top*/ yPos,
			    lpBand->rcChild.right - lpBand->rcChild.left,
			    nEditHeight,
			    SWP_SHOWWINDOW);

	    }
#endif
	    else {
		TRACE("moving child %04x to (%d,%d)-(%d,%d)\n",
		      lpBand->hwndChild,
		      lpBand->rcChild.left, lpBand->rcChild.top,
		      lpBand->rcChild.right - lpBand->rcChild.left,
		      lpBand->rcChild.bottom - lpBand->rcChild.top);
		SetWindowPos (lpBand->hwndChild, HWND_TOP,
			    lpBand->rcChild.left, lpBand->rcChild.top,
			    lpBand->rcChild.right - lpBand->rcChild.left,
			    lpBand->rcChild.bottom - lpBand->rcChild.top,
			    SWP_SHOWWINDOW);
	    }
	}
    }
}


static VOID
REBAR_ValidateBand (HWND hwnd, REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
     /* Function:  This routine evaluates the band specs supplied */
     /*  by the user and updates the following 5 fields in        */
     /*  the internal band structure: cxHeader, lcx, lcy, hcx, hcy*/
{
    UINT header=0;
    DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);

    lpBand->lcx = 0;
    lpBand->lcy = 0;
    lpBand->hcx = 0;
    lpBand->hcy = 0;

    /* Header is where the image, text and gripper exist  */
    /* in the band and preceed the child window.          */

    /* calculate gripper rectangle */
    if ((!(lpBand->fStyle & RBBS_NOGRIPPER)) &&
	(!(lpBand->fStyle & RBBS_FIXEDSIZE)) &&
	((lpBand->fStyle & RBBS_GRIPPERALWAYS) || 
	 (infoPtr->uNumBands > 1))) {
       if (dwStyle & CCS_VERT)
	  if (dwStyle & RBS_VERTICALGRIPPER)
             header += (GRIPPER_HEIGHT + 3);
          else
	     header += (GRIPPER_WIDTH + 3);
       else
          header += (GRIPPER_WIDTH + 1);
    }

    /* image is visible */
    if ((lpBand->fMask & RBBIM_IMAGE) && (infoPtr->himl)) {
        if (dwStyle & CCS_VERT) {
	   header += infoPtr->imageSize.cy;
	   lpBand->lcy = infoPtr->imageSize.cx + 2;
	}
	else {
	   header += infoPtr->imageSize.cx;
	   lpBand->lcy = infoPtr->imageSize.cy + 2;
	}
    }

    /* text is visible */
    if ((lpBand->fMask & RBBIM_TEXT) && (lpBand->lpText)) {
	HDC hdc = GetDC (0);
	HFONT hOldFont = SelectObject (hdc, infoPtr->hFont);
	SIZE size;

	GetTextExtentPoint32W (hdc, lpBand->lpText,
			       lstrlenW (lpBand->lpText), &size);
	header += ((dwStyle & CCS_VERT) ? (size.cy + 2) : (size.cx + 2));

	SelectObject (hdc, hOldFont);
	ReleaseDC (0, hdc);
    }

    /* check if user overrode the header value */
    if (!(lpBand->fMask & RBBIM_HEADERSIZE))
        lpBand->cxHeader = header;


    /* Now compute minimum size of child window */
    lpBand->offChild.cx = 0;
    lpBand->offChild.cy = 0;
    if (lpBand->fMask & RBBIM_CHILDSIZE) {
	if (!(lpBand->fStyle & RBBS_FIXEDSIZE)) {
	    lpBand->offChild.cx = 4;
	    lpBand->offChild.cy = 2;
        }
        lpBand->lcx = lpBand->cxMinChild;
        lpBand->lcy = lpBand->cyMinChild;
        lpBand->hcy = lpBand->lcy;
        if (lpBand->fStyle & RBBS_VARIABLEHEIGHT) {
	    if (lpBand->cyChild != 0xffffffff)
	        lpBand->lcy = max (lpBand->cyChild, lpBand->lcy);
	    lpBand->hcy = lpBand->cyMaxChild;
        }
        TRACE("_CHILDSIZE\n");
    }
    if (lpBand->fMask & RBBIM_SIZE) {
        lpBand->hcx = max (lpBand->cx, lpBand->lcx);
        TRACE("_SIZE\n");
    }
    else
        lpBand->hcx = lpBand->lcx;

}

static void
REBAR_CommonSetupBand (HWND hwnd, LPREBARBANDINFOA lprbbi, REBAR_BAND *lpBand)
     /* Function:  This routine copies the supplied values from   */
     /*  user input (lprbbi) to the internal band structure.      */
{
    lpBand->fMask |= lprbbi->fMask;

    if (lprbbi->fMask & RBBIM_STYLE)
	lpBand->fStyle = lprbbi->fStyle;

    if (lprbbi->fMask & RBBIM_COLORS) {
	lpBand->clrFore = lprbbi->clrFore;
	lpBand->clrBack = lprbbi->clrBack;
    }

    if (lprbbi->fMask & RBBIM_IMAGE)
	lpBand->iImage = lprbbi->iImage;

    if (lprbbi->fMask & RBBIM_CHILD) {
	if (lprbbi->hwndChild) {
	    lpBand->hwndChild = lprbbi->hwndChild;
	    lpBand->hwndPrevParent =
		SetParent (lpBand->hwndChild, hwnd);
	}
	else {
	    TRACE("child: 0x%x  prev parent: 0x%x\n",
		   lpBand->hwndChild, lpBand->hwndPrevParent);
	    lpBand->hwndChild = 0;
	    lpBand->hwndPrevParent = 0;
	}
    }

    if (lprbbi->fMask & RBBIM_CHILDSIZE) {
	lpBand->cxMinChild = lprbbi->cxMinChild;
	lpBand->cyMinChild = lprbbi->cyMinChild;
	lpBand->cyMaxChild = lprbbi->cyMaxChild;
	lpBand->cyChild    = lprbbi->cyChild;
	lpBand->cyIntegral = lprbbi->cyIntegral;
    }

    if (lprbbi->fMask & RBBIM_SIZE)
	lpBand->cx = lprbbi->cx;

    if (lprbbi->fMask & RBBIM_BACKGROUND)
	lpBand->hbmBack = lprbbi->hbmBack;

    if (lprbbi->fMask & RBBIM_ID)
	lpBand->wID = lprbbi->wID;

    /* check for additional data */
    if (lprbbi->cbSize >= sizeof (REBARBANDINFOA)) {
	if (lprbbi->fMask & RBBIM_IDEALSIZE)
	    lpBand->cxIdeal = lprbbi->cxIdeal;

	if (lprbbi->fMask & RBBIM_LPARAM)
	    lpBand->lParam = lprbbi->lParam;

	if (lprbbi->fMask & RBBIM_HEADERSIZE)
	    lpBand->cxHeader = lprbbi->cxHeader;
    }
}

static LRESULT
REBAR_InternalEraseBkGnd (HWND hwnd, WPARAM wParam, LPARAM lParam, RECT *clip)
     /* Function:  This erases the background rectangle with the  */
     /*  default brush, then with any band that has a different   */
     /*  background color.                                        */
{
    HBRUSH hbrBackground = GetClassWord(hwnd, GCW_HBRBACKGROUND);
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    RECT eraserect;
    REBAR_BAND *lpBand;
    INT i;

    if (hbrBackground)
        FillRect( (HDC) wParam, clip, hbrBackground);

    for(i=0; i<infoPtr->uNumBands; i++) {
        lpBand = &infoPtr->bands[i];
	if (lpBand->clrBack != CLR_NONE) {
	  if (IntersectRect (&eraserect, clip, &lpBand->rcBand)) {
	    /* draw background */
	    HBRUSH brh = CreateSolidBrush (lpBand->clrBack);
	    TRACE("backround color=0x%06lx, rect (%d,%d)-(%d,%d)\n",
		  lpBand->clrBack,
		  lpBand->rcBand.left,lpBand->rcBand.top,
		  lpBand->rcBand.right,lpBand->rcBand.bottom);
	    FillRect ( (HDC)wParam, &eraserect, brh);
	    DeleteObject (brh);
	  }
	}
    }
    return TRUE;
}

static void
REBAR_InternalHitTest (HWND hwnd, LPPOINT lpPt, UINT *pFlags, INT *pBand)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    REBAR_BAND *lpBand;
    RECT rect;
    INT  iCount;

    GetClientRect (hwnd, &rect);

    *pFlags = RBHT_NOWHERE;
    if (PtInRect (&rect, *lpPt))
    {
	if (infoPtr->uNumBands == 0) {
	    *pFlags = RBHT_NOWHERE;
	    if (pBand)
		*pBand = -1;
	    TRACE("NOWHERE\n");
	    return;
	}
	else {
	    /* somewhere inside */
	    infoPtr->ihitBand = -1;
	    for (iCount = 0; iCount < infoPtr->uNumBands; iCount++) {
		lpBand = &infoPtr->bands[iCount];
		if (PtInRect (&lpBand->rcBand, *lpPt)) {
		    if (pBand)
			*pBand = iCount;
		    if (PtInRect (&lpBand->rcGripper, *lpPt)) {
			*pFlags = RBHT_GRABBER;
			infoPtr->ihitBand = iCount;
			TRACE("ON GRABBER %d\n", iCount);
			return;
		    }
		    else if (PtInRect (&lpBand->rcCapImage, *lpPt)) {
			*pFlags = RBHT_CAPTION;
			TRACE("ON CAPTION %d\n", iCount);
			return;
		    }
		    else if (PtInRect (&lpBand->rcCapText, *lpPt)) {
			*pFlags = RBHT_CAPTION;
			TRACE("ON CAPTION %d\n", iCount);
			return;
		    }
		    else if (PtInRect (&lpBand->rcChild, *lpPt)) {
			*pFlags = RBHT_CLIENT;
			TRACE("ON CLIENT %d\n", iCount);
			return;
		    }
		    else {
			*pFlags = RBHT_NOWHERE;
			TRACE("NOWHERE %d\n", iCount);
			return;
		    }
		}
	    }

	    *pFlags = RBHT_NOWHERE;
	    if (pBand)
		*pBand = -1;

	    TRACE("NOWHERE\n");
	    return;
	}
    }
    else {
	*pFlags = RBHT_NOWHERE;
	if (pBand)
	    *pBand = -1;
	TRACE("NOWHERE\n");
	return;
    }

    TRACE("flags=0x%X\n", *pFlags);
    return;
}

#define READJ(b,i) {b->rcChild.right += (i);b->rcBand.right += (i);}
#define LEADJ(b,i) {b->rcBand.left += (i); \
                    b->rcGripper.left += (i); \
                    b->rcGripper.right += (i); \
                    b->rcCapImage.left += (i); \
                    b->rcCapImage.right += (i); \
                    b->rcCapText.left += (i); \
                    b->rcCapText.right += (i); \
                    b->rcChild.left += (i);}


static INT
REBAR_Shrink (REBAR_BAND *band, INT movement, INT i)
     /* Function:  This attempts to shrink the given band by the  */
     /*  the amount in "movement". A shrink to the left is indi-  */
     /*  cated by "movement" being negative. "i" is merely the    */
     /*  band index for trace messages.                           */
{
    INT Leadjust, Readjust, avail, ret;

    /* Note: a left drag is indicated by "movement" being negative.  */
    /*       Similarly, a right drag is indicated by "movement"      */
    /*       being positive. "movement" should never be 0, but if    */
    /*       it is then the band does not move.                      */

    avail = band->rcBand.right - band->rcBand.left -
            band->cxHeader - band->offChild.cx;

    /* now compute the Left End adjustment factor and Right End */
    /* adjustment factor. They may be different if shrinking.   */
    if (avail <= 0) {
        /* if this band is not shrinkable, then just move it */
        Leadjust = Readjust = movement;
	ret = movement;
    }
    else {
        if (movement < 0) {
	    /* Drag to left */
	    if (avail <= abs(movement)) {
	        Readjust = movement;
		Leadjust = movement + avail;
		ret = Leadjust;
	    }
	    else {
	        Readjust = movement;
		Leadjust = 0;
		ret = 0;
	    }
	}
	else {
	    /* Drag to right */
	    if (avail <= abs(movement)) {
	        Leadjust = movement;
		Readjust = movement - avail;
		ret = Readjust;
	    }
	    else {
	        Leadjust = movement;
		Readjust = 0;
		ret = 0;
	    }
	}
    }

    /* Reasonability Check */
    if (band->rcBand.left+Leadjust < 0) {
        ERR("adjustment will fail, band %d: left=%d, right=%d, move=%d, rtn=%d\n",
	    i, Leadjust, Readjust, movement, ret);
    }

    LEADJ(band, Leadjust);
    READJ(band, Readjust);

    TRACE("band %d:  left=%d, right=%d, move=%d, rtn=%d, rcBand=(%d,%d)-(%d,%d)\n",
	  i, Leadjust, Readjust, movement, ret,
	  band->rcBand.left, band->rcBand.top,
	  band->rcBand.right, band->rcBand.bottom);
    return ret;
}


static void
REBAR_HandleLRDrag (HWND hwnd, REBAR_INFO *infoPtr, POINTS *ptsmove)
     /* Function:  This will implement the functionality of a     */
     /*  Gripper drag within a row. It will not implement "out-   */
     /*  of-row" drags. (They are detected and handled in         */
     /*  REBAR_MouseMove.)                                        */
     /*  **** FIXME Vertical rebars not implemented.        ****  */
     /*  **** FIXME Switching order of bands in a row not   ****  */
     /*  ****       yet implemented.                        ****  */
{
    REBAR_BAND *hitBand, *band, *prevband, *mindBand, *maxdBand;
    DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
    HDWP deferpos;
    NMREBARCHILDSIZE cs;
    NMREBAR startdrag;
    RECT newrect;
    INT imindBand = -1, imaxdBand, ihitBand, i, movement, tempx;
    INT RHeaderSum = 0, LHeaderSum = 0;
    INT compress;

    /* *** FIXME drag does not work for vertical           *** */
    if (dwStyle & CCS_VERT) {
        FIXME("Drag not yet implemented for vertical rebars\n");
	return;
    }

    /* on first significant mouse movement, issue notify */

    if (!(infoPtr->fStatus & BEGIN_DRAG_ISSUED)) {
        startdrag.dwMask = 0;
	startdrag.uBand = -1;
	REBAR_Notify(hwnd, (NMHDR *) &startdrag, RBN_BEGINDRAG);
	infoPtr->fStatus |= BEGIN_DRAG_ISSUED;
    }

    ihitBand = infoPtr->ihitBand;
    hitBand = &infoPtr->bands[ihitBand];
    imaxdBand = ihitBand; /* to suppress warning message */

    /* find all the bands in the row of the one whose Gripper was seized */
    for (i=0; i<infoPtr->uNumBands; i++) {
        band = &infoPtr->bands[i];
	if (band->iRow == hitBand->iRow) {
	    imaxdBand = i;
	    if (imindBand == -1) imindBand = i;
	    /* minimum size of each band is size of header plus            */
	    /* size of minimum child plus offset of child from header plus */
	    /* a one to separate each band.                                */
	    if (i < ihitBand)
	        LHeaderSum += (band->cxHeader + band->offChild.cx +
			       band->lcx + 1);
	    else 
	        RHeaderSum += (band->cxHeader + band->offChild.cx +
			       band->lcx + 1);

	}
    }
    if (RHeaderSum) RHeaderSum--; /* no separator afterlast band */

    mindBand = &infoPtr->bands[imindBand];
    maxdBand = &infoPtr->bands[imaxdBand];

    if (imindBand == imaxdBand) return; /* nothing to drag agains */
    if (imindBand == ihitBand) return; /* first band in row, cant drag */

    /* limit movement to inside adjustable bands - Left */
    if (ptsmove->x < mindBand->rcBand.left)
        return; /* should swap bands */
    /* limit movement to inside adjustable bands - Right */
    if (ptsmove->x > maxdBand->rcBand.right)
        return; /* should swap bands */

    movement = ptsmove->x - (hitBand->rcGripper.left - infoPtr->ihitoffset);
    infoPtr->dragNow = *ptsmove;

    TRACE("before: movement=%d (%d,%d), imindBand=%d, ihitBand=%d, imaxdBand=%d, LSum=%d, RSum=%d\n",
	  movement, ptsmove->x, ptsmove->y, imindBand, ihitBand,
	  imaxdBand, LHeaderSum, RHeaderSum);
    REBAR_DumpBand (hwnd);

    if (movement < 0) {  

        /* ***  Drag left *** */
        compress = hitBand->rcBand.left-1 - mindBand->rcBand.left -
	           LHeaderSum;
	if (compress < abs(movement)) {
	    TRACE("limiting left drag, was %d changed to %d\n",
		  movement, -compress);
	    movement = -compress;
	}
        for (i=ihitBand; i>=imindBand; i--) {
	    band = &infoPtr->bands[i];
	    if (i == ihitBand) {
		prevband = &infoPtr->bands[i-1];
		if (band->rcBand.left - movement <= prevband->rcBand.right) {
		    tempx = movement - (prevband->rcBand.right-band->rcBand.left+1);
		    ERR("movement bad. BUG!! was %d, left=%d, right=%d, setting to %d\n",
			movement, band->rcBand.left, prevband->rcBand.right, tempx);
		    movement = tempx;
		}
		LEADJ(band, movement)
	    }
	    else 
	        movement = REBAR_Shrink (band, movement, i);
	}
    }
    else {

        /* ***  Drag right *** */
        compress = maxdBand->rcBand.right - hitBand->rcBand.left -
	           RHeaderSum;
	if (compress < abs(movement)) {
	    TRACE("limiting right drag, was %d changed to %d\n",
		  movement, compress);
	    movement = compress;
	}
        for (i=ihitBand-1; i<=imaxdBand; i++) {
	    band = &infoPtr->bands[i];
	    if (i == ihitBand-1) {
		READJ(band, movement)
	    }
	    else 
	        movement = REBAR_Shrink (band, movement, i);
	}
    }

    TRACE("bands after adjustment, see band # %d, %d\n",
	  imindBand, imaxdBand);
    REBAR_DumpBand (hwnd);

    SetRect (&newrect, 
	     mindBand->rcBand.left,
	     min(mindBand->rcBand.top, maxdBand->rcBand.top),
	     maxdBand->rcBand.right,
	     max(mindBand->rcBand.bottom, maxdBand->rcBand.bottom));

    if (!(deferpos = BeginDeferWindowPos (4))) {
        ERR("BeginDeferWindowPos returned NULL\n");
    }

    for (i=imindBand; i<=imaxdBand; i++) {
        band = &infoPtr->bands[i];
	if ((band->fMask & RBBIM_CHILD) && band->hwndChild) {
	    cs.uBand = i;
	    cs.wID = band->wID;
	    cs.rcChild = band->rcChild;
	    cs.rcBand = band->rcBand;
	    REBAR_Notify (hwnd, (NMHDR *) &cs, RBN_CHILDSIZE);
	    deferpos = DeferWindowPos (deferpos, band->hwndChild, HWND_TOP,
				       cs.rcChild.left, cs.rcChild.top,
				       cs.rcChild.right - cs.rcChild.left,
				       cs.rcChild.bottom - cs.rcChild.top,
				       SWP_NOZORDER);
	    if (!deferpos) {
	        ERR("DeferWindowPos returned NULL\n");
	    }
	}
    }

    if (!EndDeferWindowPos (deferpos)) {
        ERR("EndDeferWindowPos failed\n");
    }

    InvalidateRect (hwnd, &newrect, TRUE);
    UpdateWindow (hwnd);

}
#undef READJ
#undef LEADJ



/* << REBAR_BeginDrag >> */


static LRESULT
REBAR_DeleteBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    UINT uBand = (UINT)wParam;

    if (uBand >= infoPtr->uNumBands)
	return FALSE;

    TRACE("deleting band %u!\n", uBand);

    if (infoPtr->uNumBands == 1) {
	TRACE(" simple delete!\n");
	COMCTL32_Free (infoPtr->bands);
	infoPtr->bands = NULL;
	infoPtr->uNumBands = 0;
    }
    else {
	REBAR_BAND *oldBands = infoPtr->bands;
        TRACE("complex delete! [uBand=%u]\n", uBand);

	infoPtr->uNumBands--;
	infoPtr->bands = COMCTL32_Alloc (sizeof (REBAR_BAND) * infoPtr->uNumBands);
        if (uBand > 0) {
            memcpy (&infoPtr->bands[0], &oldBands[0],
                    uBand * sizeof(REBAR_BAND));
        }

        if (uBand < infoPtr->uNumBands) {
            memcpy (&infoPtr->bands[uBand], &oldBands[uBand+1],
                    (infoPtr->uNumBands - uBand) * sizeof(REBAR_BAND));
        }

	COMCTL32_Free (oldBands);
    }

    REBAR_Layout (hwnd, NULL, FALSE, FALSE);
    REBAR_ForceResize (hwnd);
    REBAR_MoveChildWindows (hwnd);

    return TRUE;
}


/* << REBAR_DragMove >> */
/* << REBAR_EndDrag >> */


static LRESULT
REBAR_GetBandBorders (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    /* LPRECT32 lpRect = (LPRECT32)lParam; */
    REBAR_BAND *lpBand;

    if (!lParam)
	return 0;
    if ((UINT)wParam >= infoPtr->uNumBands)
	return 0;

    lpBand = &infoPtr->bands[(UINT)wParam];
    if (GetWindowLongA (hwnd, GWL_STYLE) & RBS_BANDBORDERS) {
      /*lpRect.left   = ??? */
      /*lpRect.top    = ??? */
      /*lpRect.right  = ??? */
      /*lpRect.bottom = ??? */
    }
    else {
      /*lpRect.left   = ??? */
    }
    FIXME("stub\n");
    return 0;
}


inline static LRESULT
REBAR_GetBandCount (HWND hwnd)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);

    TRACE("band count %u!\n", infoPtr->uNumBands);

    return infoPtr->uNumBands;
}


static LRESULT
REBAR_GetBandInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    LPREBARBANDINFOA lprbbi = (LPREBARBANDINFOA)lParam;
    REBAR_BAND *lpBand;

    if (lprbbi == NULL)
	return FALSE;
    if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEA)
	return FALSE;
    if ((UINT)wParam >= infoPtr->uNumBands)
	return FALSE;

    TRACE("index %u\n", (UINT)wParam);

    /* copy band information */
    lpBand = &infoPtr->bands[(UINT)wParam];

    if (lprbbi->fMask & RBBIM_STYLE)
	lprbbi->fStyle = lpBand->fStyle;

    if (lprbbi->fMask & RBBIM_COLORS) {
	lprbbi->clrFore = lpBand->clrFore;
	lprbbi->clrBack = lpBand->clrBack;
	if (lprbbi->clrBack == CLR_NONE)
	    lprbbi->clrBack = GetSysColor (COLOR_BTNFACE);
    }

    if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) {
      if (lpBand->lpText && (lpBand->fMask & RBBIM_TEXT))
      {
          if (!WideCharToMultiByte( CP_ACP, 0, lpBand->lpText, -1,
                                    lprbbi->lpText, lprbbi->cch, NULL, NULL ))
              lprbbi->lpText[lprbbi->cch-1] = 0;
      }
      else 
	*lprbbi->lpText = 0;
    }

    if (lprbbi->fMask & RBBIM_IMAGE) {
      if (lpBand->fMask & RBBIM_IMAGE)
	lprbbi->iImage = lpBand->iImage;
      else
	lprbbi->iImage = -1;
    }

    if (lprbbi->fMask & RBBIM_CHILD)
	lprbbi->hwndChild = lpBand->hwndChild;

    if (lprbbi->fMask & RBBIM_CHILDSIZE) {
	lprbbi->cxMinChild = lpBand->cxMinChild;
	lprbbi->cyMinChild = lpBand->cyMinChild;
	lprbbi->cyMaxChild = lpBand->cyMaxChild;
	lprbbi->cyChild    = lpBand->cyChild;
	lprbbi->cyIntegral = lpBand->cyIntegral;
    }

    if (lprbbi->fMask & RBBIM_SIZE)
	lprbbi->cx = lpBand->cx;

    if (lprbbi->fMask & RBBIM_BACKGROUND)
	lprbbi->hbmBack = lpBand->hbmBack;

    if (lprbbi->fMask & RBBIM_ID)
	lprbbi->wID = lpBand->wID;

    /* check for additional data */
    if (lprbbi->cbSize >= sizeof (REBARBANDINFOA)) {
	if (lprbbi->fMask & RBBIM_IDEALSIZE)
	    lprbbi->cxIdeal = lpBand->cxIdeal;

	if (lprbbi->fMask & RBBIM_LPARAM)
	    lprbbi->lParam = lpBand->lParam;

	if (lprbbi->fMask & RBBIM_HEADERSIZE)
	    lprbbi->cxHeader = lpBand->cxHeader;
    }

    REBAR_DumpBandInfo (lprbbi);

    return TRUE;
}


static LRESULT
REBAR_GetBandInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    LPREBARBANDINFOW lprbbi = (LPREBARBANDINFOW)lParam;
    REBAR_BAND *lpBand;

    if (lprbbi == NULL)
	return FALSE;
    if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEW)
	return FALSE;
    if ((UINT)wParam >= infoPtr->uNumBands)
	return FALSE;

    TRACE("index %u\n", (UINT)wParam);

    /* copy band information */
    lpBand = &infoPtr->bands[(UINT)wParam];

    if (lprbbi->fMask & RBBIM_STYLE)
	lprbbi->fStyle = lpBand->fStyle;

    if (lprbbi->fMask & RBBIM_COLORS) {
	lprbbi->clrFore = lpBand->clrFore;
	lprbbi->clrBack = lpBand->clrBack;
	if (lprbbi->clrBack == CLR_NONE)
	    lprbbi->clrBack = GetSysColor (COLOR_BTNFACE);
    }

    if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) {
      if (lpBand->lpText && (lpBand->fMask & RBBIM_TEXT))
	lstrcpynW (lprbbi->lpText, lpBand->lpText, lprbbi->cch);
      else 
	*lprbbi->lpText = 0;
    }

    if (lprbbi->fMask & RBBIM_IMAGE) {
      if (lpBand->fMask & RBBIM_IMAGE)
	lprbbi->iImage = lpBand->iImage;
      else
	lprbbi->iImage = -1;
    }

    if (lprbbi->fMask & RBBIM_CHILD)
	lprbbi->hwndChild = lpBand->hwndChild;

    if (lprbbi->fMask & RBBIM_CHILDSIZE) {
	lprbbi->cxMinChild = lpBand->cxMinChild;
	lprbbi->cyMinChild = lpBand->cyMinChild;
	lprbbi->cyMaxChild = lpBand->cyMaxChild;
	lprbbi->cyChild    = lpBand->cyChild;
	lprbbi->cyIntegral = lpBand->cyIntegral;
    }

    if (lprbbi->fMask & RBBIM_SIZE)
	lprbbi->cx = lpBand->cx;

    if (lprbbi->fMask & RBBIM_BACKGROUND)
	lprbbi->hbmBack = lpBand->hbmBack;

    if (lprbbi->fMask & RBBIM_ID)
	lprbbi->wID = lpBand->wID;

    /* check for additional data */
    if (lprbbi->cbSize >= sizeof (REBARBANDINFOA)) {
	if (lprbbi->fMask & RBBIM_IDEALSIZE)
	    lprbbi->cxIdeal = lpBand->cxIdeal;

	if (lprbbi->fMask & RBBIM_LPARAM)
	    lprbbi->lParam = lpBand->lParam;

	if (lprbbi->fMask & RBBIM_HEADERSIZE)
	    lprbbi->cxHeader = lpBand->cxHeader;
    }

    REBAR_DumpBandInfo ((LPREBARBANDINFOA)lprbbi);

    return TRUE;
}


static LRESULT
REBAR_GetBarHeight (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    INT nHeight;

    nHeight = infoPtr->calcSize.cy;

    TRACE("height = %d\n", nHeight);

    return nHeight;
}


static LRESULT
REBAR_GetBarInfo (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    LPREBARINFO lpInfo = (LPREBARINFO)lParam;

    if (lpInfo == NULL)
	return FALSE;

    if (lpInfo->cbSize < sizeof (REBARINFO))
	return FALSE;

    TRACE("getting bar info!\n");

    if (infoPtr->himl) {
	lpInfo->himl = infoPtr->himl;
	lpInfo->fMask |= RBIM_IMAGELIST;
    }

    return TRUE;
}


inline static LRESULT
REBAR_GetBkColor (HWND hwnd)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    COLORREF clr = infoPtr->clrBk;

    if (clr == CLR_NONE)
      clr = GetSysColor (COLOR_BTNFACE);

    TRACE("background color 0x%06lx!\n", clr);

    return clr;
}


/* << REBAR_GetColorScheme >> */
/* << REBAR_GetDropTarget >> */


static LRESULT
REBAR_GetPalette (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    FIXME("empty stub!\n");

    return 0;
}


static LRESULT
REBAR_GetRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    INT iBand = (INT)wParam;
    LPRECT lprc = (LPRECT)lParam;
    REBAR_BAND *lpBand;

    if ((iBand < 0) && ((UINT)iBand >= infoPtr->uNumBands))
	return FALSE;
    if (!lprc)
	return FALSE;

    lpBand = &infoPtr->bands[iBand];
    CopyRect (lprc, &lpBand->rcBand);

    TRACE("band %d, (%d,%d)-(%d,%d)\n", iBand,
	  lprc->left, lprc->top, lprc->right, lprc->bottom);

    return TRUE;
}


inline static LRESULT
REBAR_GetRowCount (HWND hwnd)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);

    TRACE("%u\n", infoPtr->uNumRows);

    return infoPtr->uNumRows;
}


static LRESULT
REBAR_GetRowHeight (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    INT iRow = (INT)wParam;
    int ret = 0;
    int i, j = 0;
    REBAR_BAND *lpBand;
    DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);

    for (i=0; i<infoPtr->uNumBands; i++) {
      lpBand = &infoPtr->bands[i];
      if (lpBand->iRow != iRow) continue;
      if (dwStyle & CCS_VERT)
	j = lpBand->rcBand.right - lpBand->rcBand.left;
      else
	j = lpBand->rcBand.bottom - lpBand->rcBand.top;
      if (j > ret) ret = j;
    }

    TRACE("row %d, height %d\n", iRow, ret);

    return ret;
}


inline static LRESULT
REBAR_GetTextColor (HWND hwnd)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);

    TRACE("text color 0x%06lx!\n", infoPtr->clrText);

    return infoPtr->clrText;
}


inline static LRESULT
REBAR_GetToolTips (HWND hwnd)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    return infoPtr->hwndToolTip;
}


inline static LRESULT
REBAR_GetUnicodeFormat (HWND hwnd)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    return infoPtr->bUnicode;
}


inline static LRESULT
REBAR_GetVersion (HWND hwnd)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    TRACE("version %d\n", infoPtr->iVersion);
    return infoPtr->iVersion;
}


static LRESULT
REBAR_HitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    /* REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */
    LPRBHITTESTINFO lprbht = (LPRBHITTESTINFO)lParam; 

    if (!lprbht)
	return -1;

    REBAR_InternalHitTest (hwnd, &lprbht->pt, &lprbht->flags, &lprbht->iBand);

    return lprbht->iBand;
}


static LRESULT
REBAR_IdToIndex (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    UINT i;

    if (infoPtr == NULL)
	return -1;

    if (infoPtr->uNumBands < 1)
	return -1;

    for (i = 0; i < infoPtr->uNumBands; i++) {
	if (infoPtr->bands[i].wID == (UINT)wParam) {
	    TRACE("id %u is band %u found!\n", (UINT)wParam, i);
	    return i;
	}
    }

    TRACE("id %u is not found\n", (UINT)wParam);
    return -1;
}


static LRESULT
REBAR_InsertBandA (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    LPREBARBANDINFOA lprbbi = (LPREBARBANDINFOA)lParam;
    UINT uIndex = (UINT)wParam;
    REBAR_BAND *lpBand;

    if (infoPtr == NULL)
	return FALSE;
    if (lprbbi == NULL)
	return FALSE;
    if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEA)
	return FALSE;

    /* trace the index as signed to see the -1 */
    TRACE("insert band at %d!\n", (INT)uIndex);
    REBAR_DumpBandInfo (lprbbi);

    if (infoPtr->uNumBands == 0) {
	infoPtr->bands = (REBAR_BAND *)COMCTL32_Alloc (sizeof (REBAR_BAND));
	uIndex = 0;
    }
    else {
	REBAR_BAND *oldBands = infoPtr->bands;
	infoPtr->bands =
	    (REBAR_BAND *)COMCTL32_Alloc ((infoPtr->uNumBands+1)*sizeof(REBAR_BAND));
	if (((INT)uIndex == -1) || (uIndex > infoPtr->uNumBands))
	    uIndex = infoPtr->uNumBands;

	/* pre insert copy */
	if (uIndex > 0) {
	    memcpy (&infoPtr->bands[0], &oldBands[0],
		    uIndex * sizeof(REBAR_BAND));
	}

	/* post copy */
	if (uIndex < infoPtr->uNumBands - 1) {
	    memcpy (&infoPtr->bands[uIndex+1], &oldBands[uIndex],
		    (infoPtr->uNumBands - uIndex - 1) * sizeof(REBAR_BAND));
	}

	COMCTL32_Free (oldBands);
    }

    infoPtr->uNumBands++;

    TRACE("index %u!\n", uIndex);

    /* initialize band (infoPtr->bands[uIndex])*/
    lpBand = &infoPtr->bands[uIndex];
    lpBand->fMask = 0;
    lpBand->clrFore = infoPtr->clrText;
    lpBand->clrBack = infoPtr->clrBk;
    lpBand->hwndChild = 0;
    lpBand->hwndPrevParent = 0;

    REBAR_CommonSetupBand (hwnd, lprbbi, lpBand);
    lpBand->lpText = NULL;
    if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) {
        INT len = MultiByteToWideChar( CP_ACP, 0, lprbbi->lpText, -1, NULL, 0 );
        if (len > 1) {
            lpBand->lpText = (LPWSTR)COMCTL32_Alloc (len*sizeof(WCHAR));
            MultiByteToWideChar( CP_ACP, 0, lprbbi->lpText, -1, lpBand->lpText, len );
	}
    }

    REBAR_ValidateBand (hwnd, infoPtr, lpBand);

    REBAR_DumpBand (hwnd);

    REBAR_Layout (hwnd, NULL, FALSE, FALSE);
    REBAR_ForceResize (hwnd);
    REBAR_MoveChildWindows (hwnd);

    return TRUE;
}


static LRESULT
REBAR_InsertBandW (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    LPREBARBANDINFOW lprbbi = (LPREBARBANDINFOW)lParam;
    UINT uIndex = (UINT)wParam;
    REBAR_BAND *lpBand;

    if (infoPtr == NULL)
	return FALSE;
    if (lprbbi == NULL)
	return FALSE;
    if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEW)
	return FALSE;

    /* trace the index as signed to see the -1 */
    TRACE("insert band at %d!\n", (INT)uIndex);
    REBAR_DumpBandInfo ((LPREBARBANDINFOA)lprbbi);

    if (infoPtr->uNumBands == 0) {
	infoPtr->bands = (REBAR_BAND *)COMCTL32_Alloc (sizeof (REBAR_BAND));
	uIndex = 0;
    }
    else {
	REBAR_BAND *oldBands = infoPtr->bands;
	infoPtr->bands =
	    (REBAR_BAND *)COMCTL32_Alloc ((infoPtr->uNumBands+1)*sizeof(REBAR_BAND));
	if (((INT)uIndex == -1) || (uIndex > infoPtr->uNumBands))
	    uIndex = infoPtr->uNumBands;

	/* pre insert copy */
	if (uIndex > 0) {
	    memcpy (&infoPtr->bands[0], &oldBands[0],
		    uIndex * sizeof(REBAR_BAND));
	}

	/* post copy */
	if (uIndex < infoPtr->uNumBands - 1) {
	    memcpy (&infoPtr->bands[uIndex+1], &oldBands[uIndex],
		    (infoPtr->uNumBands - uIndex - 1) * sizeof(REBAR_BAND));
	}

	COMCTL32_Free (oldBands);
    }

    infoPtr->uNumBands++;

    TRACE("index %u!\n", uIndex);

    /* initialize band (infoPtr->bands[uIndex])*/
    lpBand = &infoPtr->bands[uIndex];
    lpBand->fMask = 0;
    lpBand->clrFore = infoPtr->clrText;
    lpBand->clrBack = infoPtr->clrBk;
    lpBand->hwndChild = 0;
    lpBand->hwndPrevParent = 0;

    REBAR_CommonSetupBand (hwnd, (LPREBARBANDINFOA)lprbbi, lpBand);
    lpBand->lpText = NULL;
    if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) {
	INT len = lstrlenW (lprbbi->lpText);
	if (len > 0) {
	    lpBand->lpText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
	    strcpyW (lpBand->lpText, lprbbi->lpText);
	}
    }

    REBAR_ValidateBand (hwnd, infoPtr, lpBand);

    REBAR_DumpBand (hwnd);

    REBAR_Layout (hwnd, NULL, FALSE, FALSE);
    REBAR_ForceResize (hwnd);
    REBAR_MoveChildWindows (hwnd);

    return TRUE;
}


static LRESULT
REBAR_MaximizeBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
/*    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */

    FIXME("(uBand = %u fIdeal = %s)\n",
	   (UINT)wParam, lParam ? "TRUE" : "FALSE");

 
    return 0;
}


static LRESULT
REBAR_MinimizeBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
/*    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */

    FIXME("(uBand = %u)\n", (UINT)wParam);

 
    return 0;
}


static LRESULT
REBAR_MoveBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
/*    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */

    FIXME("(iFrom = %u iTof = %u)\n",
	   (UINT)wParam, (UINT)lParam);

 
    return FALSE;
}


static LRESULT
REBAR_SetBandInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    LPREBARBANDINFOA lprbbi = (LPREBARBANDINFOA)lParam;
    REBAR_BAND *lpBand;

    if (lprbbi == NULL)
	return FALSE;
    if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEA)
	return FALSE;
    if ((UINT)wParam >= infoPtr->uNumBands)
	return FALSE;

    TRACE("index %u\n", (UINT)wParam);
    REBAR_DumpBandInfo (lprbbi);

    /* set band information */
    lpBand = &infoPtr->bands[(UINT)wParam];

    REBAR_CommonSetupBand (hwnd, lprbbi, lpBand);
    if (lprbbi->fMask & RBBIM_TEXT) {
	if (lpBand->lpText) {
	    COMCTL32_Free (lpBand->lpText);
	    lpBand->lpText = NULL;
	}
	if (lprbbi->lpText) {
            INT len = MultiByteToWideChar( CP_ACP, 0, lprbbi->lpText, -1, NULL, 0 );
            lpBand->lpText = (LPWSTR)COMCTL32_Alloc (len*sizeof(WCHAR));
            MultiByteToWideChar( CP_ACP, 0, lprbbi->lpText, -1, lpBand->lpText, len );
	}
    }

    REBAR_ValidateBand (hwnd, infoPtr, lpBand);

    REBAR_DumpBand (hwnd);

    if (lprbbi->fMask & (RBBIM_CHILDSIZE | RBBIM_SIZE)) {
      REBAR_Layout (hwnd, NULL, TRUE, FALSE);
      REBAR_ForceResize (hwnd);
      REBAR_MoveChildWindows (hwnd);
    }

    return TRUE;
}


static LRESULT
REBAR_SetBandInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    LPREBARBANDINFOW lprbbi = (LPREBARBANDINFOW)lParam;
    REBAR_BAND *lpBand;

    if (lprbbi == NULL)
	return FALSE;
    if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEW)
	return FALSE;
    if ((UINT)wParam >= infoPtr->uNumBands)
	return FALSE;

    TRACE("index %u\n", (UINT)wParam);
    REBAR_DumpBandInfo ((LPREBARBANDINFOA)lprbbi);

    /* set band information */
    lpBand = &infoPtr->bands[(UINT)wParam];

    REBAR_CommonSetupBand (hwnd, (LPREBARBANDINFOA)lprbbi, lpBand);
    if (lprbbi->fMask & RBBIM_TEXT) {
	if (lpBand->lpText) {
	    COMCTL32_Free (lpBand->lpText);
	    lpBand->lpText = NULL;
	}
	if (lprbbi->lpText) {
	    INT len = lstrlenW (lprbbi->lpText);
	    lpBand->lpText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
	    strcpyW (lpBand->lpText, lprbbi->lpText);
	}
    }

    REBAR_ValidateBand (hwnd, infoPtr, lpBand);

    REBAR_DumpBand (hwnd);

    if (lprbbi->fMask & (RBBIM_CHILDSIZE | RBBIM_SIZE)) {
      REBAR_Layout (hwnd, NULL, TRUE, FALSE);
      REBAR_ForceResize (hwnd);
      REBAR_MoveChildWindows (hwnd);
    }

    return TRUE;
}


static LRESULT
REBAR_SetBarInfo (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    LPREBARINFO lpInfo = (LPREBARINFO)lParam;

    if (lpInfo == NULL)
	return FALSE;

    if (lpInfo->cbSize < sizeof (REBARINFO))
	return FALSE;

    TRACE("setting bar info!\n");

    if (lpInfo->fMask & RBIM_IMAGELIST) {
	infoPtr->himl = lpInfo->himl;
	if (infoPtr->himl) {
            INT cx, cy;
	    ImageList_GetIconSize (infoPtr->himl, &cx, &cy);
	    infoPtr->imageSize.cx = cx;
	    infoPtr->imageSize.cy = cy;
	}
	else {
	    infoPtr->imageSize.cx = 0;
	    infoPtr->imageSize.cy = 0;
	}
	TRACE("new image cx=%ld, cy=%ld\n", infoPtr->imageSize.cx,
	      infoPtr->imageSize.cy);
    }

    return TRUE;
}


static LRESULT
REBAR_SetBkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    COLORREF clrTemp;

    clrTemp = infoPtr->clrBk;
    infoPtr->clrBk = (COLORREF)lParam;

    TRACE("background color 0x%06lx!\n", infoPtr->clrBk);

    return clrTemp;
}


/* << REBAR_SetColorScheme >> */
/* << REBAR_SetPalette >> */


static LRESULT
REBAR_SetParent (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    HWND hwndTemp = infoPtr->hwndNotify;

    infoPtr->hwndNotify = (HWND)wParam;

    return (LRESULT)hwndTemp;
}


static LRESULT
REBAR_SetTextColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    COLORREF clrTemp;

    clrTemp = infoPtr->clrText;
    infoPtr->clrText = (COLORREF)lParam;

    TRACE("text color 0x%06lx!\n", infoPtr->clrText);

    return clrTemp;
}


/* << REBAR_SetTooltips >> */


inline static LRESULT
REBAR_SetUnicodeFormat (HWND hwnd, WPARAM wParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    BOOL bTemp = infoPtr->bUnicode;
    infoPtr->bUnicode = (BOOL)wParam;
    return bTemp;
}


static LRESULT
REBAR_SetVersion (HWND hwnd, INT iVersion)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    INT iOldVersion = infoPtr->iVersion;

    if (iVersion > COMCTL32_VERSION)
	return -1;

    infoPtr->iVersion = iVersion;

    TRACE("new version %d\n", iVersion);

    return iOldVersion;
}


static LRESULT
REBAR_ShowBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    REBAR_BAND *lpBand;

    if (((INT)wParam < 0) || ((INT)wParam > infoPtr->uNumBands))
	return FALSE;

    lpBand = &infoPtr->bands[(INT)wParam];

    if ((BOOL)lParam) {
	TRACE("show band %d\n", (INT)wParam);
	lpBand->fStyle = lpBand->fStyle & ~RBBS_HIDDEN;
	if (IsWindow (lpBand->hwndChild))
	    ShowWindow (lpBand->hwndChild, SW_SHOW);
    }
    else {
	TRACE("hide band %d\n", (INT)wParam);
	lpBand->fStyle = lpBand->fStyle | RBBS_HIDDEN;
	if (IsWindow (lpBand->hwndChild))
	    ShowWindow (lpBand->hwndChild, SW_SHOW);
    }

    REBAR_Layout (hwnd, NULL, TRUE, FALSE);
    REBAR_ForceResize (hwnd);
    REBAR_MoveChildWindows (hwnd);

    return TRUE;
}


static LRESULT
REBAR_SizeToRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    LPRECT lpRect = (LPRECT)lParam;
    RECT t1;

    if (lpRect == NULL)
       return FALSE;

    TRACE("[%d %d %d %d]\n",
	  lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);

    /*  what is going on???? */
    GetWindowRect(hwnd, &t1);
    TRACE("window rect [%d %d %d %d]\n",
	  t1.left, t1.top, t1.right, t1.bottom);
    GetClientRect(hwnd, &t1);
    TRACE("client rect [%d %d %d %d]\n",
	  t1.left, t1.top, t1.right, t1.bottom);

    REBAR_Layout (hwnd, lpRect, TRUE, FALSE);
    REBAR_ForceResize (hwnd);
    REBAR_MoveChildWindows (hwnd);
    return TRUE;
}



static LRESULT
REBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr;

    /* allocate memory for info structure */
    infoPtr = (REBAR_INFO *)COMCTL32_Alloc (sizeof(REBAR_INFO));
    SetWindowLongA (hwnd, 0, (DWORD)infoPtr);

    /* initialize info structure */
    infoPtr->iVersion = 0;
    infoPtr->clrBk = CLR_NONE;
    infoPtr->clrText = GetSysColor (COLOR_BTNTEXT);
    infoPtr->ihitBand = -1;
    infoPtr->fStatus = 0;

    infoPtr->hcurArrow = LoadCursorA (0, IDC_ARROWA);
    infoPtr->hcurHorz  = LoadCursorA (0, IDC_SIZEWEA);
    infoPtr->hcurVert  = LoadCursorA (0, IDC_SIZENSA);
    infoPtr->hcurDrag  = LoadCursorA (0, IDC_SIZEA);

    infoPtr->bUnicode = IsWindowUnicode (hwnd);

    if (GetWindowLongA (hwnd, GWL_STYLE) & RBS_AUTOSIZE)
	FIXME("style RBS_AUTOSIZE set!\n");

#if 0
    SendMessageA (hwnd, WM_NOTIFYFORMAT, (WPARAM)hwnd, NF_QUERY);
#endif

    TRACE("created!\n");
    return 0;
}


static LRESULT
REBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    REBAR_BAND *lpBand;
    INT i;


    /* free rebar bands */
    if ((infoPtr->uNumBands > 0) && infoPtr->bands) {
	/* clean up each band */
	for (i = 0; i < infoPtr->uNumBands; i++) {
	    lpBand = &infoPtr->bands[i];

	    /* delete text strings */
	    if (lpBand->lpText) {
		COMCTL32_Free (lpBand->lpText);
		lpBand->lpText = NULL;
	    }
	    /* destroy child window */
	    DestroyWindow (lpBand->hwndChild);
	}

	/* free band array */
	COMCTL32_Free (infoPtr->bands);
	infoPtr->bands = NULL;
    }

    DeleteObject (infoPtr->hcurArrow);
    DeleteObject (infoPtr->hcurHorz);
    DeleteObject (infoPtr->hcurVert);
    DeleteObject (infoPtr->hcurDrag);

    /* free rebar info data */
    COMCTL32_Free (infoPtr);
    SetWindowLongA (hwnd, 0, 0);
    TRACE("destroyed!\n");
    return 0;
}


static LRESULT
REBAR_EraseBkGnd (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    RECT cliprect;

    if (GetClipBox ( (HDC)wParam, &cliprect))
        return REBAR_InternalEraseBkGnd (hwnd, wParam, lParam, &cliprect);
    return 0;
}


static LRESULT
REBAR_GetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);

    return (LRESULT)infoPtr->hFont;
}


static LRESULT
REBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    REBAR_BAND *lpBand;

    /* If InternalHitTest did not find a hit on the Gripper, */
    /* then ignore the button click.                         */
    if (infoPtr->ihitBand == -1) return 0;

    SetCapture (hwnd);

    /* save off the LOWORD and HIWORD of lParam as initial x,y */
    lpBand = &infoPtr->bands[infoPtr->ihitBand];
    infoPtr->dragStart = MAKEPOINTS(lParam);
    infoPtr->dragNow = infoPtr->dragStart;
    infoPtr->ihitoffset = infoPtr->dragStart.x - lpBand->rcGripper.left;

    return 0;
}


static LRESULT
REBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    NMHDR layout;
    NMREBAR enddrag;
    RECT rect;

    /* If InternalHitTest did not find a hit on the Gripper, */
    /* then ignore the button click.                         */
    if (infoPtr->ihitBand == -1) return 0;

    infoPtr->dragStart.x = 0;
    infoPtr->dragStart.y = 0;
    infoPtr->dragNow = infoPtr->dragStart;
    infoPtr->ihitBand = -1;

    ReleaseCapture ();

    if (infoPtr->fStatus & BEGIN_DRAG_ISSUED) {
        REBAR_Notify(hwnd, (NMHDR *) &layout, RBN_LAYOUTCHANGED);

	enddrag.dwMask = 0;
	enddrag.uBand = -1;
	REBAR_Notify(hwnd, (NMHDR *) &enddrag, RBN_ENDDRAG);
	infoPtr->fStatus &= ~BEGIN_DRAG_ISSUED;
    }

    GetClientRect(hwnd, &rect);
    InvalidateRect(hwnd, NULL, TRUE);

    return 0;
}


static LRESULT
REBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    REBAR_BAND *band1, *band2;
    POINTS ptsmove;

    /* Validate entry as hit on Gripper has occured */
    if (GetCapture() != hwnd) return 0;
    if (infoPtr->ihitBand == -1) return 0;

    ptsmove = MAKEPOINTS(lParam);

    /* if mouse did not move much, exit */
    if ((abs(ptsmove.x - infoPtr->dragNow.x) <= mindragx) &&
	(abs(ptsmove.y - infoPtr->dragNow.y) <= mindragy)) return 0;

    band1 = &infoPtr->bands[infoPtr->ihitBand-1];
    band2 = &infoPtr->bands[infoPtr->ihitBand];

    /* Test for valid drag case - must not be first band in row */
    if ((ptsmove.y < band2->rcBand.top) ||
	(ptsmove.y > band2->rcBand.bottom) ||
        ((infoPtr->ihitBand > 0) && (band1->iRow != band2->iRow))) {
        FIXME("Cannot drag to other rows yet!!\n");
    }
    else {
        REBAR_HandleLRDrag (hwnd, infoPtr, &ptsmove);
    }
    return 0;
}


inline static LRESULT
REBAR_NCCalcSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    if (GetWindowLongA (hwnd, GWL_STYLE) & WS_BORDER) {
	((LPRECT)lParam)->left   += GetSystemMetrics(SM_CXEDGE);
	((LPRECT)lParam)->top    += GetSystemMetrics(SM_CYEDGE);
	((LPRECT)lParam)->right  -= GetSystemMetrics(SM_CXEDGE);
	((LPRECT)lParam)->bottom -= GetSystemMetrics(SM_CYEDGE);
    }

    return 0;
}


static LRESULT
REBAR_NCPaint (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
    RECT rcWindow;
    HDC hdc;

    if (dwStyle & WS_MINIMIZE)
	return 0; /* Nothing to do */

    DefWindowProcA (hwnd, WM_NCPAINT, wParam, lParam);

    if (!(hdc = GetDCEx( hwnd, 0, DCX_USESTYLE | DCX_WINDOW )))
	return 0;

    if (dwStyle & WS_BORDER) {
	GetWindowRect (hwnd, &rcWindow);
	OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
	DrawEdge (hdc, &rcWindow, EDGE_ETCHED, BF_RECT);
    }

    ReleaseDC( hwnd, hdc );

    return 0;
}


static LRESULT
REBAR_Paint (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;

    hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;

    if (ps.fErase) {
	/* Erase area of paint if requested */
        REBAR_InternalEraseBkGnd (hwnd, wParam, lParam, &ps.rcPaint);
    }

    REBAR_Refresh (hwnd, hdc);
    if (!wParam)
	EndPaint (hwnd, &ps);
    return 0;
}


static LRESULT
REBAR_SetCursor (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
    POINT pt;
    UINT  flags;

    TRACE("code=0x%X  id=0x%X\n", LOWORD(lParam), HIWORD(lParam));

    GetCursorPos (&pt);
    ScreenToClient (hwnd, &pt);

    REBAR_InternalHitTest (hwnd, &pt, &flags, NULL);

    if (flags == RBHT_GRABBER) {
	if ((dwStyle & CCS_VERT) &&
	    !(dwStyle & RBS_VERTICALGRIPPER))
	    SetCursor (infoPtr->hcurVert);
	else
	    SetCursor (infoPtr->hcurHorz);
    }
    else if (flags != RBHT_CLIENT)
	SetCursor (infoPtr->hcurArrow);

    return 0;
}


static LRESULT
REBAR_SetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    
    /* TEXTMETRIC32A tm; */
    HFONT hFont /*, hOldFont */;
    /* HDC32 hdc; */

    infoPtr->hFont = (HFONT)wParam;

    hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT);
/*
    hdc = GetDC32 (0);
    hOldFont = SelectObject32 (hdc, hFont);
    GetTextMetrics32A (hdc, &tm);
    infoPtr->nHeight = tm.tmHeight + VERT_BORDER;
    SelectObject32 (hdc, hOldFont);
    ReleaseDC32 (0, hdc);
*/
    if (lParam) {
/*
        REBAR_Layout (hwnd);
        hdc = GetDC32 (hwnd);
        REBAR_Refresh (hwnd, hdc);
        ReleaseDC32 (hwnd, hdc);
*/
    }

    return 0;
}

static LRESULT
REBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
    RECT rcClient;

    /* auto resize deadlock check */
    if (infoPtr->fStatus & AUTO_RESIZE) {
	infoPtr->fStatus &= ~AUTO_RESIZE;
	return 0;
    }

    GetClientRect (hwnd, &rcClient);
    if ((lParam == 0) && (rcClient.right == 0) && (rcClient.bottom == 0)) {
      /* native control seems to do this */
      GetClientRect (GetParent(hwnd), &rcClient);
      TRACE("sizing rebar, message and client zero, parent client (%d,%d)\n", 
	    rcClient.right, rcClient.bottom);
    }
    else {
      TRACE("sizing rebar to (%d,%d), client (%d,%d)\n", 
	    LOWORD(lParam), HIWORD(lParam), rcClient.right, rcClient.bottom);
    }

    REBAR_Layout (hwnd, &rcClient, FALSE, TRUE);
    REBAR_ForceResize (hwnd);
    REBAR_MoveChildWindows (hwnd);

    return 0;
}


static LRESULT WINAPI
REBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n", hwnd, uMsg, wParam, lParam);
    if (!REBAR_GetInfoPtr (hwnd) && (uMsg != WM_CREATE))
	    return DefWindowProcA (hwnd, uMsg, wParam, lParam);
    switch (uMsg)
    {
/*	case RB_BEGINDRAG: */

	case RB_DELETEBAND:
	    return REBAR_DeleteBand (hwnd, wParam, lParam);

/*	case RB_DRAGMOVE: */
/*	case RB_ENDDRAG: */

	case RB_GETBANDBORDERS:
	    return REBAR_GetBandBorders (hwnd, wParam, lParam);

	case RB_GETBANDCOUNT:
	    return REBAR_GetBandCount (hwnd);

	case RB_GETBANDINFO:	/* obsoleted after IE3, but we have to
				   support it anyway. */
	case RB_GETBANDINFOA:
	    return REBAR_GetBandInfoA (hwnd, wParam, lParam);

	case RB_GETBANDINFOW:
	    return REBAR_GetBandInfoW (hwnd, wParam, lParam);

	case RB_GETBARHEIGHT:
	    return REBAR_GetBarHeight (hwnd, wParam, lParam);

	case RB_GETBARINFO:
	    return REBAR_GetBarInfo (hwnd, wParam, lParam);

	case RB_GETBKCOLOR:
	    return REBAR_GetBkColor (hwnd);

/*	case RB_GETCOLORSCHEME: */
/*	case RB_GETDROPTARGET: */

	case RB_GETPALETTE:
	    return REBAR_GetPalette (hwnd, wParam, lParam);

	case RB_GETRECT:
	    return REBAR_GetRect (hwnd, wParam, lParam);

	case RB_GETROWCOUNT:
	    return REBAR_GetRowCount (hwnd);

	case RB_GETROWHEIGHT:
	    return REBAR_GetRowHeight (hwnd, wParam, lParam);

	case RB_GETTEXTCOLOR:
	    return REBAR_GetTextColor (hwnd);

	case RB_GETTOOLTIPS:
	    return REBAR_GetToolTips (hwnd);

	case RB_GETUNICODEFORMAT:
	    return REBAR_GetUnicodeFormat (hwnd);

	case CCM_GETVERSION:
	    return REBAR_GetVersion (hwnd);

	case RB_HITTEST:
	    return REBAR_HitTest (hwnd, wParam, lParam);

	case RB_IDTOINDEX:
	    return REBAR_IdToIndex (hwnd, wParam, lParam);

	case RB_INSERTBANDA:
	    return REBAR_InsertBandA (hwnd, wParam, lParam);

	case RB_INSERTBANDW:
	    return REBAR_InsertBandW (hwnd, wParam, lParam);

	case RB_MAXIMIZEBAND:
	    return REBAR_MaximizeBand (hwnd, wParam, lParam);

	case RB_MINIMIZEBAND:
	    return REBAR_MinimizeBand (hwnd, wParam, lParam);

	case RB_MOVEBAND:
	    return REBAR_MoveBand (hwnd, wParam, lParam);

	case RB_SETBANDINFOA:
	    return REBAR_SetBandInfoA (hwnd, wParam, lParam);

	case RB_SETBANDINFOW:
	    return REBAR_SetBandInfoW (hwnd, wParam, lParam);

	case RB_SETBARINFO:
	    return REBAR_SetBarInfo (hwnd, wParam, lParam);

	case RB_SETBKCOLOR:
	    return REBAR_SetBkColor (hwnd, wParam, lParam);

/*	case RB_SETCOLORSCHEME: */
/*	case RB_SETPALETTE: */
/*	    return REBAR_GetPalette (hwnd, wParam, lParam); */

	case RB_SETPARENT:
	    return REBAR_SetParent (hwnd, wParam, lParam);

	case RB_SETTEXTCOLOR:
	    return REBAR_SetTextColor (hwnd, wParam, lParam);

/*	case RB_SETTOOLTIPS: */

	case RB_SETUNICODEFORMAT:
	    return REBAR_SetUnicodeFormat (hwnd, wParam);

	case CCM_SETVERSION:
	    return REBAR_SetVersion (hwnd, (INT)wParam);

	case RB_SHOWBAND:
	    return REBAR_ShowBand (hwnd, wParam, lParam);

	case RB_SIZETORECT:
	    return REBAR_SizeToRect (hwnd, wParam, lParam);


	case WM_COMMAND:
	    return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);

	case WM_CREATE:
	    return REBAR_Create (hwnd, wParam, lParam);

	case WM_DESTROY:
	    return REBAR_Destroy (hwnd, wParam, lParam);

	case WM_GETFONT:
	    return REBAR_GetFont (hwnd, wParam, lParam);

	case WM_LBUTTONDOWN:
	    return REBAR_LButtonDown (hwnd, wParam, lParam);

	case WM_LBUTTONUP:
	    return REBAR_LButtonUp (hwnd, wParam, lParam);

	case WM_MOUSEMOVE:
	    return REBAR_MouseMove (hwnd, wParam, lParam);

	case WM_NCCALCSIZE:
	    return REBAR_NCCalcSize (hwnd, wParam, lParam);

	case WM_NCPAINT:
	    return REBAR_NCPaint (hwnd, wParam, lParam);

	case WM_NOTIFY:
	    return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);

	case WM_PAINT:
	    return REBAR_Paint (hwnd, wParam, lParam);

	case WM_SETCURSOR:
	    return REBAR_SetCursor (hwnd, wParam, lParam);

	case WM_SETFONT:
	    return REBAR_SetFont (hwnd, wParam, lParam);

	case WM_SIZE:
	    return REBAR_Size (hwnd, wParam, lParam);
	case WM_DRAWITEM:
	    return SendMessageA(GetParent(hwnd),uMsg,wParam,lParam);

/*	case WM_TIMER: */

/*	case WM_WININICHANGE: */

        case WM_ERASEBKGND:
	  return REBAR_EraseBkGnd (hwnd, wParam, lParam);

	default:
	    if (uMsg >= WM_USER)
		ERR("unknown msg %04x wp=%08x lp=%08lx\n",
		     uMsg, wParam, lParam);
	    return DefWindowProcA (hwnd, uMsg, wParam, lParam);
    }
    return 0;
}


VOID
REBAR_Register (void)
{
    WNDCLASSA wndClass;

    ZeroMemory (&wndClass, sizeof(WNDCLASSA));
    wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS;
    wndClass.lpfnWndProc   = (WNDPROC)REBAR_WindowProc;
    wndClass.cbClsExtra    = 0;
    wndClass.cbWndExtra    = sizeof(REBAR_INFO *);
    wndClass.hCursor       = 0;
    wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
    wndClass.lpszClassName = REBARCLASSNAMEA;
 
    RegisterClassA (&wndClass);

    mindragx = GetSystemMetrics (SM_CXDRAG);
    mindragy = GetSystemMetrics (SM_CYDRAG);

}


VOID
REBAR_Unregister (void)
{
    UnregisterClassA (REBARCLASSNAMEA, (HINSTANCE)NULL);
}

