4 * Copyright 1998, 1999 Eric Kohl
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>
12 * - vertical placement
13 * - ComboBox and ComboBoxEx placement
18 * - All notifications.
20 * Changes Guy Albertelli <galberte@neo.lrun.com>
22 * - Implement initial version of row grouping, row separators,
23 * text and background colors. Support additional messages.
24 * Support RBBS_BREAK. Implement ERASEBKGND and improve painting.
26 * - implement support for dragging Gripper left or right in a row. Supports
27 * WM_LBUTTONDOWN, WM_LBUTTONUP, and WM_MOUSEMOVE. Also support
30 * 1. Make drawing of rebar attempt to match pixel by pixel with MS. (6a)
31 * 2. Fix interlock between REBAR_ForceResize and REBAR_Size (AUTO_RESIZE flag) (6a)
32 * 3. Fix up some of the notifications (RBN_HEIGHTCHANGE). (6a)
33 * 4. Fix up DeleteBand by hiding child window. (6a)
34 * 5. Change how band borders are drawn and rects are invalidated. (6b)
35 * 6. Fix height of bar with only caption text. (6b)
36 * 7. RBBS_NOGRIPPER trumps RBBS_GRIPPERALWAYS (gripper hidden), but
37 * RBBS_GRIPPERALWAYS trumps RBBS_FIXEDSIZE (gripper displays). (6b)
38 * 8. New algorithim for AdjustBand:
39 * For all bands in a row: bands left to right are sized to their "cx"
40 * size (if space available). Also use max of (cxHeader+cxMinChild) and
42 * 9. New alogrithim for Layout:
43 * Insert band in row if cxHeader space is available. If adjustment
44 * rect exists, then back out bands in row from last to second into
45 * separate rows till "y" adjustment rect equalled or exceeded. (6c)
46 * 10. Implement vertical drag. (6c)
47 * 11. Use DeferWindowPos to set child window position. (6c)
52 * 1. default row height should be the max height of all visible bands
53 * 2. Following still not handled: RBBS_FIXEDBMP, RBBS_CHILDEDGE,
55 * 3. RBS_VARHEIGHT is assumed to always be on.
56 * 4. RBBS_HIDDEN (and the CCS_VERT + RBBS_NOVERT case) is not really
57 * supported by the following functions:
58 * _Layout (phase 2), _InternalEraseBkgnd, _InternalHitTest,
68 #include "wine/unicode.h"
70 #include "debugtools.h"
72 DEFAULT_DEBUG_CHANNEL(rebar);
94 UINT lcx; /* minimum cx for band */
95 UINT hcx; /* maximum cx for band */
96 UINT lcy; /* minimum cy for band */
97 UINT hcy; /* maximum cy for band */
99 SIZE offChild; /* x,y offset if child is not FIXEDSIZE */
101 INT iRow; /* row this band assigned to */
102 UINT fStatus; /* status flags, reset only by _Validate */
103 UINT fDraw; /* drawing flags, reset only by _Layout */
104 RECT rcBand; /* calculated band rectangle */
105 RECT rcGripper; /* calculated gripper rectangle */
106 RECT rcCapImage; /* calculated caption image rectangle */
107 RECT rcCapText; /* calculated caption text rectangle */
108 RECT rcChild; /* calculated child rectangle */
115 #define HAS_GRIPPER 0x00000001
116 #define HAS_IMAGE 0x00000002
117 #define HAS_TEXT 0x00000004
120 #define DRAW_GRIPPER 0x00000001
121 #define DRAW_IMAGE 0x00000002
122 #define DRAW_TEXT 0x00000004
123 #define DRAW_RIGHTSEP 0x00000010
124 #define DRAW_BOTTOMSEP 0x00000020
125 #define DRAW_SEPBOTH (DRAW_RIGHTSEP | DRAW_BOTTOMSEP)
126 #define NTF_INVALIDATE 0x01000000
127 #define NTF_CHILDSIZE 0x02000000
132 COLORREF clrBk; /* background color */
133 COLORREF clrText; /* text color */
134 HIMAGELIST himl; /* handle to imagelist */
135 UINT uNumBands; /* number of bands in the rebar */
136 UINT uNumRows; /* number of rows of bands */
137 HWND hwndToolTip; /* handle to the tool tip control */
138 HWND hwndNotify; /* notification window (parent) */
139 HFONT hFont; /* handle to the rebar's font */
140 SIZE imageSize; /* image size (image list) */
142 SIZE calcSize; /* calculated rebar size */
143 SIZE oldSize; /* previous calculated rebar size */
144 BOOL bUnicode; /* Unicode flag */
145 UINT fStatus; /* Status flags (see below) */
146 HCURSOR hcurArrow; /* handle to the arrow cursor */
147 HCURSOR hcurHorz; /* handle to the EW cursor */
148 HCURSOR hcurVert; /* handle to the NS cursor */
149 HCURSOR hcurDrag; /* handle to the drag cursor */
150 INT iVersion; /* version number */
151 POINTS dragStart; /* x,y of button down */
152 POINTS dragNow; /* x,y of this MouseMove */
153 INT ihitBand; /* band number of band whose gripper was grabbed */
154 INT ihitoffset; /* offset of hotspot from gripper.left */
156 REBAR_BAND *bands; /* pointer to the array of rebar bands */
160 #define BEGIN_DRAG_ISSUED 1
161 #define AUTO_RESIZE 2
162 #define RESIZE_ANYHOW 4
163 #define NTF_HGHTCHG 8
165 /* ---- REBAR layout constants. Mostly determined by ---- */
166 /* ---- experiment on WIN 98. ---- */
168 /* Width (or height) of separators between bands (either horz. or */
169 /* vert.). True only if RBS_BANDBORDERS is set */
170 #define SEP_WIDTH_SIZE 2
171 #define SEP_WIDTH ((dwStyle & RBS_BANDBORDERS) ? SEP_WIDTH_SIZE : 0)
173 /* Blank (background color) space between Gripper (if present) */
174 /* and next item (image, text, or window). Always present */
175 #define REBAR_ALWAYS_SPACE 4
177 /* Blank (background color) space after Image (if present). */
178 #define REBAR_POST_IMAGE 2
180 /* Blank (background color) space after Text (if present). */
181 #define REBAR_POST_TEXT 4
183 /* Height of vertical gripper in a CCS_VERT rebar. */
184 #define GRIPPER_HEIGHT 16
186 /* Blank (background color) space before Gripper (if present). */
187 #define REBAR_PRE_GRIPPER 2
189 /* Width (of normal vertical gripper) or height (of horz. gripper) */
191 #define GRIPPER_WIDTH 3
193 /* This is the increment that is used over the band height */
194 /* Determined by experiment. */
197 /* ---- End of REBAR layout constants. ---- */
200 /* The following 4 defines return the proper rcBand element */
201 /* depending on whether CCS_VERT was set. */
202 #define rcBlt(b) ((dwStyle & CCS_VERT) ? b->rcBand.top : b->rcBand.left)
203 #define rcBrb(b) ((dwStyle & CCS_VERT) ? b->rcBand.bottom : b->rcBand.right)
204 #define ircBlt(b) ((dwStyle & CCS_VERT) ? b->rcBand.left : b->rcBand.top)
205 #define ircBrb(b) ((dwStyle & CCS_VERT) ? b->rcBand.right : b->rcBand.bottom)
207 /* The following define determines if a given band is hidden */
208 #define HIDDENBAND(a) (((a)->fStyle & RBBS_HIDDEN) || \
209 ((dwStyle & CCS_VERT) && \
210 ((a)->fStyle & RBBS_NOVERT)))
213 #define REBAR_GetInfoPtr(wndPtr) ((REBAR_INFO *)GetWindowLongA (hwnd, 0))
216 /* "constant values" retrieved when DLL was initialized */
217 /* FIXME we do this when the classes are registered. */
218 static UINT mindragx = 0;
219 static UINT mindragy = 0;
223 REBAR_DumpBandInfo( LPREBARBANDINFOA pB)
225 TRACE("band info: ID=%u, size=%u, style=0x%08x, mask=0x%08x, child=%04x\n",
226 pB->wID, pB->cbSize, pB->fStyle, pB->fMask, pB->hwndChild);
227 TRACE("band info: cx=%u, xMin=%u, yMin=%u, yChild=%u, yMax=%u, yIntgl=%u\n",
228 pB->cx, pB->cxMinChild,
229 pB->cyMinChild, pB->cyChild, pB->cyMaxChild, pB->cyIntegral);
230 TRACE("band info: xIdeal=%u, xHeader=%u, lParam=0x%08lx, clrF=0x%06lx, clrB=0x%06lx\n",
231 pB->cxIdeal, pB->cxHeader, pB->lParam, pB->clrFore, pB->clrBack);
235 REBAR_DumpBand (HWND hwnd)
237 REBAR_INFO *iP = REBAR_GetInfoPtr (hwnd);
241 if( TRACE_ON(rebar) ) {
243 TRACE("hwnd=%04x: color=%08lx/%08lx, bands=%u, rows=%u, cSize=%ld,%ld\n",
244 hwnd, iP->clrText, iP->clrBk, iP->uNumBands, iP->uNumRows,
245 iP->calcSize.cx, iP->calcSize.cy);
246 TRACE("hwnd=%04x: flags=%08x, dragStart=%d,%d, dragNow=%d,%d, ihitBand=%d\n",
247 hwnd, iP->fStatus, iP->dragStart.x, iP->dragStart.y,
248 iP->dragNow.x, iP->dragNow.y,
250 for (i = 0; i < iP->uNumBands; i++) {
252 TRACE("band # %u: ID=%u, mask=0x%08x, style=0x%08x, child=%04x, row=%u\n",
253 i, pB->wID, pB->fMask, pB->fStyle, pB->hwndChild, pB->iRow);
254 TRACE("band # %u: xMin=%u, yMin=%u, cx=%u, yChild=%u, yMax=%u, yIntgl=%u, uMinH=%u,\n",
255 i, pB->cxMinChild, pB->cyMinChild, pB->cx,
256 pB->cyChild, pB->cyMaxChild, pB->cyIntegral, pB->uMinHeight);
257 TRACE("band # %u: header=%u, lcx=%u, hcx=%u, lcy=%u, hcy=%u, offChild=%ld,%ld\n",
258 i, pB->cxHeader, pB->lcx, pB->hcx, pB->lcy, pB->hcy, pB->offChild.cx, pB->offChild.cy);
259 TRACE("band # %u: fStatus=%08x, fDraw=%08x, Band=(%d,%d)-(%d,%d), Grip=(%d,%d)-(%d,%d)\n",
260 i, pB->fStatus, pB->fDraw,
261 pB->rcBand.left, pB->rcBand.top, pB->rcBand.right, pB->rcBand.bottom,
262 pB->rcGripper.left, pB->rcGripper.top, pB->rcGripper.right, pB->rcGripper.bottom);
263 TRACE("band # %u: Img=(%d,%d)-(%d,%d), Txt=(%d,%d)-(%d,%d), Child=(%d,%d)-(%d,%d)\n",
265 pB->rcCapImage.left, pB->rcCapImage.top, pB->rcCapImage.right, pB->rcCapImage.bottom,
266 pB->rcCapText.left, pB->rcCapText.top, pB->rcCapText.right, pB->rcCapText.bottom,
267 pB->rcChild.left, pB->rcChild.top, pB->rcChild.right, pB->rcChild.bottom);
274 REBAR_Notify (HWND hwnd, NMHDR *nmhdr, REBAR_INFO *infoPtr, UINT code)
278 parent = infoPtr->hwndNotify;
280 parent = GetParent (hwnd);
281 owner = GetWindow (hwnd, GW_OWNER);
282 if (owner) parent = owner;
284 nmhdr->idFrom = GetDlgCtrlID (hwnd);
285 nmhdr->hwndFrom = hwnd;
288 return SendMessageA (parent, WM_NOTIFY, (WPARAM) nmhdr->idFrom,
293 REBAR_Notify_NMREBAR (HWND hwnd, REBAR_INFO *infoPtr, UINT uBand, UINT code)
295 NMREBAR notify_rebar;
298 notify_rebar.dwMask = 0;
300 lpBand = &infoPtr->bands[uBand];
301 if (lpBand->fMask & RBBIM_ID) {
302 notify_rebar.dwMask |= RBNM_ID;
303 notify_rebar.wID = lpBand->wID;
305 if (lpBand->fMask & RBBIM_LPARAM) {
306 notify_rebar.dwMask |= RBNM_LPARAM;
307 notify_rebar.lParam = lpBand->lParam;
309 if (lpBand->fMask & RBBIM_STYLE) {
310 notify_rebar.dwMask |= RBNM_STYLE;
311 notify_rebar.fStyle = lpBand->fStyle;
314 notify_rebar.uBand = uBand;
315 return REBAR_Notify (hwnd, (NMHDR *)¬ify_rebar, infoPtr, code);
319 REBAR_DrawBand (HDC hdc, REBAR_INFO *infoPtr, REBAR_BAND *lpBand, DWORD dwStyle)
322 /* draw separators on both the bottom and right */
323 if ((lpBand->fDraw & DRAW_SEPBOTH) == DRAW_SEPBOTH) {
328 lpBand->rcBand.right + SEP_WIDTH_SIZE,
329 lpBand->rcBand.bottom + SEP_WIDTH_SIZE);
330 DrawEdge (hdc, &rcSep, EDGE_ETCHED, BF_BOTTOMRIGHT);
331 TRACE("drawing band separator both (%d,%d)-(%d,%d)\n",
332 rcSep.left, rcSep.top, rcSep.right, rcSep.bottom);
335 /* draw band separator between bands in a row */
336 if ((lpBand->fDraw & DRAW_SEPBOTH) == DRAW_RIGHTSEP) {
338 if (dwStyle & CCS_VERT) {
341 lpBand->rcBand.bottom,
342 lpBand->rcBand.right,
343 lpBand->rcBand.bottom + SEP_WIDTH_SIZE);
344 DrawEdge (hdc, &rcSep, EDGE_ETCHED, BF_BOTTOM);
348 lpBand->rcBand.right,
350 lpBand->rcBand.right + SEP_WIDTH_SIZE,
351 lpBand->rcBand.bottom);
352 DrawEdge (hdc, &rcSep, EDGE_ETCHED, BF_RIGHT);
354 TRACE("drawing band separator right (%d,%d)-(%d,%d)\n",
355 rcSep.left, rcSep.top, rcSep.right, rcSep.bottom);
358 /* draw band separator between rows */
359 if ((lpBand->fDraw & DRAW_SEPBOTH) == DRAW_BOTTOMSEP) {
361 if (dwStyle & CCS_VERT) {
363 lpBand->rcBand.right,
365 lpBand->rcBand.right + SEP_WIDTH_SIZE,
366 lpBand->rcBand.bottom);
367 DrawEdge (hdc, &rcRowSep, EDGE_ETCHED, BF_RIGHT);
372 lpBand->rcBand.bottom,
373 lpBand->rcBand.right,
374 lpBand->rcBand.bottom + SEP_WIDTH_SIZE);
375 DrawEdge (hdc, &rcRowSep, EDGE_ETCHED, BF_BOTTOM);
377 TRACE ("drawing band separator bottom (%d,%d)-(%d,%d)\n",
378 rcRowSep.left, rcRowSep.top,
379 rcRowSep.right, rcRowSep.bottom);
383 if (lpBand->fDraw & DRAW_GRIPPER)
384 DrawEdge (hdc, &lpBand->rcGripper, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE);
386 /* draw caption image */
387 if (lpBand->fDraw & DRAW_IMAGE) {
391 pt.y = (lpBand->rcCapImage.bottom + lpBand->rcCapImage.top - infoPtr->imageSize.cy)/2;
392 pt.x = (lpBand->rcCapImage.right + lpBand->rcCapImage.left - infoPtr->imageSize.cx)/2;
394 ImageList_Draw (infoPtr->himl, lpBand->iImage, hdc,
399 /* draw caption text */
400 if (lpBand->fDraw & DRAW_TEXT) {
401 HFONT hOldFont = SelectObject (hdc, infoPtr->hFont);
402 INT oldBkMode = SetBkMode (hdc, TRANSPARENT);
403 COLORREF oldcolor = CLR_NONE;
404 if (lpBand->clrFore != CLR_NONE)
405 oldcolor = SetTextColor (hdc, lpBand->clrFore);
406 DrawTextW (hdc, lpBand->lpText, -1, &lpBand->rcCapText,
407 DT_CENTER | DT_VCENTER | DT_SINGLELINE);
408 if (oldBkMode != TRANSPARENT)
409 SetBkMode (hdc, oldBkMode);
410 if (lpBand->clrFore != CLR_NONE)
411 SetTextColor (hdc, oldcolor);
412 SelectObject (hdc, hOldFont);
418 REBAR_Refresh (HWND hwnd, HDC hdc)
420 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
423 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
425 oldrow = infoPtr->bands[0].iRow;
426 for (i = 0; i < infoPtr->uNumBands; i++) {
427 lpBand = &infoPtr->bands[i];
429 if ((lpBand->fStyle & RBBS_HIDDEN) ||
430 ((dwStyle & CCS_VERT) &&
431 (lpBand->fStyle & RBBS_NOVERT)))
434 /* now draw the band */
435 REBAR_DrawBand (hdc, infoPtr, lpBand, dwStyle);
441 REBAR_AdjustBands (REBAR_INFO *infoPtr, UINT rowstart, UINT rowend,
442 INT maxx, INT usedx, INT mcy, DWORD dwStyle)
443 /* Function: This routine distributes the extra space in a row */
444 /* by increasing bands from left to right to their "cx" width.*/
445 /* Uses "cxHeader"+"cxMinChild" if it is bigger than "cx". */
450 INT incr, current_width, lastx=0;
453 TRACE("start=%u, end=%u, max x=%d, used x=%d, max y=%d\n",
454 rowstart, rowend-1, maxx, usedx, mcy);
458 for (i = rowstart; i<rowend; i++) {
459 lpBand = &infoPtr->bands[i];
460 if (HIDDENBAND(lpBand)) continue;
463 oldband = lpBand->rcBand;
465 /* get the current width of the band */
466 if (dwStyle & CCS_VERT)
467 current_width = lpBand->rcBand.bottom - lpBand->rcBand.top;
469 current_width = lpBand->rcBand.right - lpBand->rcBand.left;
471 /* compute (in "j") the adjustment for this band */
472 /* FIXME ??? should this not use "cx" and "cxHeader" and "cxMinChild" */
473 if (!(lpBand->fStyle & RBBS_FIXEDSIZE)) {
474 if ((lpBand->fMask & RBBIM_SIZE) && (lpBand->cx > 0))
475 j = min(lpBand->cx - current_width, incr);
476 if ((lpBand->fMask & RBBIM_CHILDSIZE) &&
477 (lpBand->cxMinChild > 0) &&
478 (lpBand->fMask & RBBIM_CHILD) &&
479 (lpBand->hwndChild)) {
480 k = lpBand->cxHeader + lpBand->cxMinChild - current_width;
490 /* validate values */
492 ERR("failed, incr=%d, current_width=%d, j=%d, k=%d\n",
493 incr, current_width, j, k);
497 if (lastx + j + current_width > maxx) {
498 ERR("exceeded maximum, lastx=%d, j=%d, current_width=%d\n",
499 lastx, j, current_width);
500 j = maxx - lastx - current_width;
504 /* adjust the band rectangle for adding width */
505 /* and setting height of all bands in row. */
506 if (dwStyle & CCS_VERT) {
507 lpBand->rcBand.top = lastx;
508 lpBand->rcBand.bottom = lastx + j + current_width;
509 if ((lpBand->rcBand.top != oldband.top) ||
510 (lpBand->rcBand.bottom != oldband.bottom))
511 lpBand->fDraw |= NTF_INVALIDATE;
512 if (lpBand->rcBand.right != lpBand->rcBand.left + mcy) {
513 lpBand->rcBand.right = lpBand->rcBand.left + mcy;
514 lpBand->fDraw |= NTF_INVALIDATE;
518 lpBand->rcBand.left = lastx;
519 lpBand->rcBand.right = lastx + j + current_width;
520 if ((lpBand->rcBand.left != oldband.left) ||
521 (lpBand->rcBand.right != oldband.right))
522 lpBand->fDraw |= NTF_INVALIDATE;
523 if (lpBand->rcBand.bottom != lpBand->rcBand.top + mcy) {
524 lpBand->rcBand.bottom = lpBand->rcBand.top + mcy;
525 lpBand->fDraw |= NTF_INVALIDATE;
529 /* update to the next band start */
530 lastx += (j + current_width + SEP_WIDTH);
532 TRACE("band %d row=%d: changed to (%d,%d)-(%d,%d)\n",
534 lpBand->rcBand.left, lpBand->rcBand.top,
535 lpBand->rcBand.right, lpBand->rcBand.bottom);
538 TRACE("band %d row=%d: unchanged (%d,%d)-(%d,%d)\n",
540 lpBand->rcBand.left, lpBand->rcBand.top,
541 lpBand->rcBand.right, lpBand->rcBand.bottom);
545 /* if any remaining space then add to the rowstart band */
547 lpBand = &infoPtr->bands[rowstart];
548 lpBand->rcBand.right += incr;
549 TRACE("band %d row=%d: extended to (%d,%d)-(%d,%d)\n",
550 rowstart, lpBand->iRow,
551 lpBand->rcBand.left, lpBand->rcBand.top,
552 lpBand->rcBand.right, lpBand->rcBand.bottom);
553 for (i=rowstart+1; i<rowend; i++) {
554 lpBand = &infoPtr->bands[i];
555 if (HIDDENBAND(lpBand)) continue;
556 lpBand->rcBand.left += incr;
557 lpBand->rcBand.right += incr;
558 lpBand->fDraw |= NTF_INVALIDATE;
564 REBAR_CalcHorzBand (HWND hwnd, REBAR_INFO *infoPtr, UINT rstart, UINT rend, BOOL notify, DWORD dwStyle)
565 /* Function: this routine initializes all the rectangles in */
566 /* each band in a row to fit in the adjusted rcBand rect. */
567 /* *** Supports only Horizontal bars. *** */
574 /* MS seems to use GetDlgCtrlID() for above GetWindowLong call */
575 parenthwnd = GetParent (hwnd);
577 for(i=rstart; i<rend; i++){
578 lpBand = &infoPtr->bands[i];
579 if (HIDDENBAND(lpBand)) {
580 SetRect (&lpBand->rcChild,
581 lpBand->rcBand.right, lpBand->rcBand.top,
582 lpBand->rcBand.right, lpBand->rcBand.bottom);
586 oldChild = lpBand->rcChild;
588 /* set initial gripper rectangle */
589 SetRect (&lpBand->rcGripper, lpBand->rcBand.left, lpBand->rcBand.top,
590 lpBand->rcBand.left, lpBand->rcBand.bottom);
592 /* calculate gripper rectangle */
593 if ( lpBand->fStatus & HAS_GRIPPER) {
594 lpBand->fDraw |= DRAW_GRIPPER;
595 lpBand->rcGripper.left += REBAR_PRE_GRIPPER;
596 lpBand->rcGripper.right = lpBand->rcGripper.left + GRIPPER_WIDTH;
597 lpBand->rcGripper.top += 2;
598 lpBand->rcGripper.bottom -= 2;
600 SetRect (&lpBand->rcCapImage,
601 lpBand->rcGripper.right+REBAR_ALWAYS_SPACE, lpBand->rcBand.top,
602 lpBand->rcGripper.right+REBAR_ALWAYS_SPACE, lpBand->rcBand.bottom);
604 else { /* no gripper will be drawn */
606 if (lpBand->fStatus & (HAS_IMAGE | HAS_TEXT))
607 /* if no gripper but either image or text, then leave space */
608 xoff = REBAR_ALWAYS_SPACE;
609 SetRect (&lpBand->rcCapImage,
610 lpBand->rcBand.left+xoff, lpBand->rcBand.top,
611 lpBand->rcBand.left+xoff, lpBand->rcBand.bottom);
614 /* image is visible */
615 if (lpBand->fStatus & HAS_IMAGE) {
616 lpBand->fDraw |= DRAW_IMAGE;
617 lpBand->rcCapImage.right += infoPtr->imageSize.cx;
618 lpBand->rcCapImage.bottom = lpBand->rcCapImage.top + infoPtr->imageSize.cy;
620 /* set initial caption text rectangle */
621 SetRect (&lpBand->rcCapText,
622 lpBand->rcCapImage.right+REBAR_POST_IMAGE, lpBand->rcBand.top+1,
623 lpBand->rcBand.left+lpBand->cxHeader, lpBand->rcBand.bottom-1);
624 /* update band height
625 if (lpBand->uMinHeight < infoPtr->imageSize.cy + 2) {
626 lpBand->uMinHeight = infoPtr->imageSize.cy + 2;
627 lpBand->rcBand.bottom = lpBand->rcBand.top + lpBand->uMinHeight;
631 /* set initial caption text rectangle */
632 SetRect (&lpBand->rcCapText, lpBand->rcCapImage.right, lpBand->rcBand.top+1,
633 lpBand->rcBand.left+lpBand->cxHeader, lpBand->rcBand.bottom-1);
636 /* text is visible */
637 if (lpBand->fStatus & HAS_TEXT) {
638 lpBand->fDraw |= DRAW_TEXT;
639 lpBand->rcCapText.right = max(lpBand->rcCapText.left,
640 lpBand->rcCapText.right-REBAR_POST_TEXT);
643 /* set initial child window rectangle if there is a child */
644 if (lpBand->fMask & RBBIM_CHILD) {
645 xoff = lpBand->offChild.cx;
646 yoff = lpBand->offChild.cy;
647 SetRect (&lpBand->rcChild,
648 lpBand->rcBand.left+lpBand->cxHeader, lpBand->rcBand.top+yoff,
649 lpBand->rcBand.right-xoff, lpBand->rcBand.bottom-yoff);
652 SetRect (&lpBand->rcChild,
653 lpBand->rcBand.left+lpBand->cxHeader, lpBand->rcBand.top,
654 lpBand->rcBand.right, lpBand->rcBand.bottom);
657 /* flag if notify required and invalidate rectangle */
659 ((oldChild.right-oldChild.left != lpBand->rcChild.right-lpBand->rcChild.left) ||
660 (oldChild.bottom-oldChild.top != lpBand->rcChild.bottom-lpBand->rcChild.top))) {
661 TRACE("Child rectangle changed for band %u\n", i);
662 TRACE(" from (%d,%d)-(%d,%d) to (%d,%d)-(%d,%d)\n",
663 oldChild.left, oldChild.top,
664 oldChild.right, oldChild.bottom,
665 lpBand->rcChild.left, lpBand->rcChild.top,
666 lpBand->rcChild.right, lpBand->rcChild.bottom);
667 lpBand->fDraw |= NTF_CHILDSIZE;
669 if (lpBand->fDraw & NTF_INVALIDATE) {
670 TRACE("invalidating (%d,%d)-(%d,%d)\n",
673 lpBand->rcBand.right + ((lpBand->fDraw & DRAW_RIGHTSEP) ? SEP_WIDTH_SIZE : 0),
674 lpBand->rcBand.bottom + ((lpBand->fDraw & DRAW_BOTTOMSEP) ? SEP_WIDTH_SIZE : 0));
675 lpBand->fDraw &= ~NTF_INVALIDATE;
676 work = lpBand->rcBand;
677 if (lpBand->fDraw & DRAW_RIGHTSEP) work.right += SEP_WIDTH_SIZE;
678 if (lpBand->fDraw & DRAW_BOTTOMSEP) work.bottom += SEP_WIDTH_SIZE;
679 InvalidateRect(hwnd, &work, TRUE);
688 REBAR_CalcVertBand (HWND hwnd, REBAR_INFO *infoPtr, UINT rstart, UINT rend, BOOL notify, DWORD dwStyle)
689 /* Function: this routine initializes all the rectangles in */
690 /* each band in a row to fit in the adjusted rcBand rect. */
691 /* *** Supports only Vertical bars. *** */
695 NMREBARCHILDSIZE rbcz;
699 rbcz.hdr.hwndFrom = hwnd;
700 rbcz.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
701 /* MS seems to use GetDlgCtrlID() for above GetWindowLong call */
702 parenthwnd = GetParent (hwnd);
704 for(i=rstart; i<rend; i++){
705 lpBand = &infoPtr->bands[i];
706 if (HIDDENBAND(lpBand)) continue;
707 oldChild = lpBand->rcChild;
709 /* set initial gripper rectangle */
710 SetRect (&lpBand->rcGripper, lpBand->rcBand.left, lpBand->rcBand.top,
711 lpBand->rcBand.right, lpBand->rcBand.top);
713 /* calculate gripper rectangle */
714 if (lpBand->fStatus & HAS_GRIPPER) {
715 lpBand->fDraw |= DRAW_GRIPPER;
717 if (dwStyle & RBS_VERTICALGRIPPER) {
718 /* vertical gripper */
719 lpBand->rcGripper.left += 3;
720 lpBand->rcGripper.right = lpBand->rcGripper.left + GRIPPER_WIDTH;
721 lpBand->rcGripper.top += REBAR_PRE_GRIPPER;
722 lpBand->rcGripper.bottom = lpBand->rcGripper.top + GRIPPER_HEIGHT;
724 /* initialize Caption image rectangle */
725 SetRect (&lpBand->rcCapImage, lpBand->rcBand.left,
726 lpBand->rcGripper.bottom + REBAR_ALWAYS_SPACE,
727 lpBand->rcBand.right,
728 lpBand->rcGripper.bottom + REBAR_ALWAYS_SPACE);
731 /* horizontal gripper */
732 lpBand->rcGripper.left += 3;
733 lpBand->rcGripper.right -= 3;
734 lpBand->rcGripper.top += REBAR_PRE_GRIPPER;
735 lpBand->rcGripper.bottom = lpBand->rcGripper.top + GRIPPER_WIDTH;
737 /* initialize Caption image rectangle */
738 SetRect (&lpBand->rcCapImage, lpBand->rcBand.left,
739 lpBand->rcGripper.bottom + REBAR_ALWAYS_SPACE,
740 lpBand->rcBand.right,
741 lpBand->rcGripper.bottom + REBAR_ALWAYS_SPACE);
744 else { /* no gripper will be drawn */
746 if (lpBand->fStatus & (HAS_IMAGE | HAS_TEXT))
747 /* if no gripper but either image or text, then leave space */
748 xoff = REBAR_ALWAYS_SPACE;
749 /* initialize Caption image rectangle */
750 SetRect (&lpBand->rcCapImage,
751 lpBand->rcBand.left, lpBand->rcBand.top+xoff,
752 lpBand->rcBand.right, lpBand->rcBand.top+xoff);
755 /* image is visible */
756 if (lpBand->fStatus & HAS_IMAGE) {
757 lpBand->fDraw |= DRAW_IMAGE;
759 lpBand->rcCapImage.right = lpBand->rcCapImage.left + infoPtr->imageSize.cx;
760 lpBand->rcCapImage.bottom += infoPtr->imageSize.cy;
762 /* set initial caption text rectangle */
763 SetRect (&lpBand->rcCapText,
764 lpBand->rcBand.left, lpBand->rcCapImage.bottom+REBAR_POST_IMAGE,
765 lpBand->rcBand.right, lpBand->rcBand.top+lpBand->cxHeader);
766 /* update band height *
767 if (lpBand->uMinHeight < infoPtr->imageSize.cx + 2) {
768 lpBand->uMinHeight = infoPtr->imageSize.cx + 2;
769 lpBand->rcBand.right = lpBand->rcBand.left + lpBand->uMinHeight;
773 /* set initial caption text rectangle */
774 SetRect (&lpBand->rcCapText,
775 lpBand->rcBand.left, lpBand->rcCapImage.bottom,
776 lpBand->rcBand.right, lpBand->rcBand.top+lpBand->cxHeader);
779 /* text is visible */
780 if (lpBand->fStatus & HAS_TEXT) {
781 lpBand->fDraw |= DRAW_TEXT;
782 lpBand->rcCapText.bottom = max(lpBand->rcCapText.top,
783 lpBand->rcCapText.bottom-REBAR_POST_TEXT);
786 /* set initial child window rectangle if there is a child */
787 if (lpBand->fMask & RBBIM_CHILD) {
788 yoff = lpBand->offChild.cx;
789 xoff = lpBand->offChild.cy;
790 SetRect (&lpBand->rcChild,
791 lpBand->rcBand.left+xoff, lpBand->rcBand.top+lpBand->cxHeader,
792 lpBand->rcBand.right-xoff, lpBand->rcBand.bottom-yoff);
795 SetRect (&lpBand->rcChild,
796 lpBand->rcBand.left, lpBand->rcBand.top+lpBand->cxHeader,
797 lpBand->rcBand.right, lpBand->rcBand.bottom);
800 /* flag if notify required and invalidate rectangle */
802 ((oldChild.right-oldChild.left != lpBand->rcChild.right-lpBand->rcChild.left) ||
803 (oldChild.bottom-oldChild.top != lpBand->rcChild.bottom-lpBand->rcChild.top))) {
804 TRACE("Child rectangle changed for band %u\n", i);
805 TRACE(" from (%d,%d)-(%d,%d) to (%d,%d)-(%d,%d)\n",
806 oldChild.left, oldChild.top,
807 oldChild.right, oldChild.bottom,
808 lpBand->rcChild.left, lpBand->rcChild.top,
809 lpBand->rcChild.right, lpBand->rcChild.bottom);
810 lpBand->fDraw |= NTF_CHILDSIZE;
812 if (lpBand->fDraw & NTF_INVALIDATE) {
813 TRACE("invalidating (%d,%d)-(%d,%d)\n",
816 lpBand->rcBand.right + ((lpBand->fDraw & DRAW_BOTTOMSEP) ? SEP_WIDTH_SIZE : 0),
817 lpBand->rcBand.bottom + ((lpBand->fDraw & DRAW_RIGHTSEP) ? SEP_WIDTH_SIZE : 0));
818 lpBand->fDraw &= ~NTF_INVALIDATE;
819 work = lpBand->rcBand;
820 if (lpBand->fDraw & DRAW_RIGHTSEP) work.bottom += SEP_WIDTH_SIZE;
821 if (lpBand->fDraw & DRAW_BOTTOMSEP) work.right += SEP_WIDTH_SIZE;
822 InvalidateRect(hwnd, &work, TRUE);
830 REBAR_Layout (HWND hwnd, LPRECT lpRect, BOOL notify, BOOL resetclient)
831 /* Function: This routine is resposible for laying out all */
832 /* the bands in a rebar. It assigns each band to a row and*/
833 /* determines when to start a new row. */
835 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
836 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
837 REBAR_BAND *lpBand, *prevBand;
838 RECT rcClient, rcAdj, rcoldBand;
839 INT x, y, cx, cxsep, mcy, clientcx, clientcy;
840 INT adjcx, adjcy, row, rightx, bottomy, origheight;
841 UINT i, rowstartband;
844 GetClientRect (hwnd, &rcClient);
845 TRACE("Client is (%d,%d)-(%d,%d)\n",
846 rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
850 TRACE("adjustment rect is (%d,%d)-(%d,%d)\n",
851 rcAdj.left, rcAdj.top, rcAdj.right, rcAdj.bottom);
854 CopyRect (&rcAdj, &rcClient);
857 clientcx = rcClient.right - rcClient.left;
858 clientcy = rcClient.bottom - rcClient.top;
859 adjcx = rcAdj.right - rcAdj.left;
860 adjcy = rcAdj.bottom - rcAdj.top;
862 TRACE("window client rect will be set to adj rect\n");
867 /* save height of original control */
868 if (dwStyle & CCS_VERT)
869 origheight = infoPtr->calcSize.cx;
871 origheight = infoPtr->calcSize.cy;
874 /* ******* Start Phase 1 - all bands on row at minimum size ******* */
883 for (i = 0; i < infoPtr->uNumBands; i++) {
884 lpBand = &infoPtr->bands[i];
888 if ((lpBand->fStyle & RBBS_HIDDEN) ||
889 ((dwStyle & CCS_VERT) && (lpBand->fStyle & RBBS_NOVERT)))
892 rcoldBand = lpBand->rcBand;
894 /* separator from previous band */
895 cxsep = ( ((dwStyle & CCS_VERT) ? y : x)==0) ? 0 : SEP_WIDTH;
897 /* Header: includes gripper, text, image */
898 cx = lpBand->cxHeader;
899 if (lpBand->fStyle & RBBS_FIXEDSIZE) cx += lpBand->lcx;
901 if (dwStyle & CCS_VERT)
902 dobreak = (y + cx + cxsep > adjcy);
904 dobreak = (x + cx + cxsep > adjcx);
906 /* This is the check for whether we need to start a new row */
907 if ( ( (lpBand->fStyle & RBBS_BREAK) && (i != 0) ) ||
908 ( ((dwStyle & CCS_VERT) ? (y != 0) : (x != 0)) && dobreak)) {
909 TRACE("Spliting to new row %d on band %u\n", row+1, i);
910 if (dwStyle & CCS_VERT) {
912 x += (mcy + SEP_WIDTH);
916 y += (mcy + SEP_WIDTH);
919 /* FIXME: if not RBS_VARHEIGHT then find max */
927 if (mcy < lpBand->lcy + REBARSPACE) mcy = lpBand->lcy + REBARSPACE;
929 /* if boundary rect specified then limit mcy */
931 if (dwStyle & CCS_VERT) {
934 TRACE("row %u limiting mcy=%d, adjcx=%d, x=%d\n",
941 TRACE("row %u limiting mcy=%d, adjcy=%d, y=%d\n",
947 if (dwStyle & CCS_VERT) {
948 /* bound the bottom side if we have a bounding rectangle */
949 if ((x>0) && (dwStyle & RBS_BANDBORDERS) && prevBand)
950 prevBand->fDraw |= DRAW_RIGHTSEP;
952 bottomy = (lpRect) ? min(clientcy, y+cxsep+cx) : y+cxsep+cx;
953 lpBand->rcBand.left = x;
954 lpBand->rcBand.right = x + min(mcy, lpBand->lcy+REBARSPACE);
955 lpBand->rcBand.top = min(bottomy, y + cxsep);
956 lpBand->rcBand.bottom = bottomy;
957 lpBand->uMinHeight = lpBand->lcy;
958 if (!EqualRect(&rcoldBand, &lpBand->rcBand))
959 lpBand->fDraw |= NTF_INVALIDATE;
963 /* bound the right side if we have a bounding rectangle */
964 if ((x>0) && (dwStyle & RBS_BANDBORDERS) && prevBand)
965 prevBand->fDraw |= DRAW_RIGHTSEP;
966 rightx = (lpRect) ? min(clientcx, x+cxsep+cx) : x+cxsep+cx;
968 lpBand->rcBand.left = min(rightx, x + cxsep);
969 lpBand->rcBand.right = rightx;
970 lpBand->rcBand.top = y;
971 lpBand->rcBand.bottom = y + min(mcy, lpBand->lcy+REBARSPACE);
972 lpBand->uMinHeight = lpBand->lcy;
973 if (!EqualRect(&rcoldBand, &lpBand->rcBand))
974 lpBand->fDraw |= NTF_INVALIDATE;
977 TRACE("band %u, row %d, (%d,%d)-(%d,%d)\n",
979 lpBand->rcBand.left, lpBand->rcBand.top,
980 lpBand->rcBand.right, lpBand->rcBand.bottom);
983 } /* for (i = 0; i < infoPtr->uNumBands... */
985 if (dwStyle & CCS_VERT)
990 if (infoPtr->uNumBands)
991 infoPtr->uNumRows = row;
993 /* ******* End Phase 1 - all bands on row at minimum size ******* */
996 /* ******* Start Phase 2 - split rows till adjustment height full ******* */
998 /* assumes that the following variables contain: */
999 /* y/x current height/width of all rows */
1001 INT i, j, prev_rh, current_rh, new_rh, adj_rh;
1002 REBAR_BAND *prev, *current, *walk;
1004 if (((dwStyle & CCS_VERT) ? (x < adjcx) : (y < adjcy)) &&
1005 (infoPtr->uNumBands > 1)) {
1006 for (i=infoPtr->uNumBands-2; i>=0; i--) {
1007 prev = &infoPtr->bands[i];
1008 prev_rh = ircBrb(prev) - ircBlt(prev);
1009 current = &infoPtr->bands[i+1];
1010 current_rh = ircBrb(current) - ircBlt(current);
1011 if (prev->iRow == current->iRow) {
1012 new_rh = current->lcy + REBARSPACE;
1013 adj_rh = prev_rh + new_rh + SEP_WIDTH - current_rh;
1014 infoPtr->uNumRows++;
1015 current->fDraw |= NTF_INVALIDATE;
1017 if (dwStyle & CCS_VERT) {
1018 current->rcBand.top = 0;
1019 current->rcBand.bottom = clientcy;
1020 current->rcBand.left += (prev_rh + SEP_WIDTH);
1021 current->rcBand.right = current->rcBand.left + new_rh;
1025 current->rcBand.left = 0;
1026 current->rcBand.right = clientcx;
1027 current->rcBand.top += (prev_rh + SEP_WIDTH);
1028 current->rcBand.bottom = current->rcBand.top + new_rh;
1031 TRACE("moving band %d to own row at (%d,%d)-(%d,%d)\n",
1033 current->rcBand.left, current->rcBand.top,
1034 current->rcBand.right, current->rcBand.bottom);
1035 TRACE("prev band %d at (%d,%d)-(%d,%d)\n",
1037 prev->rcBand.left, prev->rcBand.top,
1038 prev->rcBand.right, prev->rcBand.bottom);
1039 TRACE("values: prev_rh=%d, current_rh=%d, new_rh=%d, adj_rh=%d\n",
1040 prev_rh, current_rh, new_rh, adj_rh);
1041 /* for bands below current adjust row # and top/bottom */
1042 for (j = i+2; j<infoPtr->uNumBands; j++) {
1043 walk = &infoPtr->bands[j];
1044 walk->fDraw |= NTF_INVALIDATE;
1046 if (dwStyle & CCS_VERT) {
1047 walk->rcBand.left += adj_rh;
1048 walk->rcBand.right += adj_rh;
1051 walk->rcBand.top += adj_rh;
1052 walk->rcBand.bottom += adj_rh;
1055 if ((dwStyle & CCS_VERT) ? (x >= adjcx) : (y >= adjcy))
1056 break; /* all done */
1062 /* ******* End Phase 2 - split rows till adjustment height full ******* */
1066 /* ******* Start Phase 3 - adjust all bands for width full ******* */
1068 if (infoPtr->uNumBands) {
1069 REBAR_BAND *prev, *current;
1070 /* If RBS_BANDBORDERS set then indicate to draw bottom separator */
1071 if (dwStyle & RBS_BANDBORDERS) {
1072 for (i = 0; i < infoPtr->uNumBands; i++) {
1073 lpBand = &infoPtr->bands[i];
1074 if (HIDDENBAND(lpBand)) continue;
1075 if (lpBand->iRow < infoPtr->uNumRows)
1076 lpBand->fDraw |= DRAW_BOTTOMSEP;
1080 /* Adjust the horizontal and vertical of each band */
1081 prev = &infoPtr->bands[0];
1083 mcy = prev->lcy + REBARSPACE;
1085 for (i=1; i<infoPtr->uNumBands; i++) {
1086 prev = &infoPtr->bands[i-1];
1087 current = &infoPtr->bands[i];
1088 if (prev->iRow != current->iRow) {
1089 REBAR_AdjustBands (infoPtr, rowstartband, i,
1090 (dwStyle & CCS_VERT) ? clientcy : clientcx,
1096 if (mcy < current->lcy + REBARSPACE)
1097 mcy = current->lcy + REBARSPACE;
1099 REBAR_AdjustBands (infoPtr, rowstartband, infoPtr->uNumBands,
1100 (dwStyle & CCS_VERT) ? clientcy : clientcx,
1104 /* Calculate the other rectangles in each band */
1105 if (dwStyle & CCS_VERT) {
1106 REBAR_CalcVertBand (hwnd, infoPtr, 0, infoPtr->uNumBands,
1110 REBAR_CalcHorzBand (hwnd, infoPtr, 0, infoPtr->uNumBands,
1115 /* ******* End Phase 3 - adjust all bands for width full ******* */
1118 /* FIXME: if not RBS_VARHEIGHT then find max mcy and adj rect*/
1120 infoPtr->oldSize = infoPtr->calcSize;
1121 if (dwStyle & CCS_VERT) {
1122 infoPtr->calcSize.cx = x;
1123 infoPtr->calcSize.cy = clientcy;
1124 TRACE("vert, notify=%d, x=%d, origheight=%d\n",
1125 notify, x, origheight);
1126 if (notify && (x != origheight)) infoPtr->fStatus |= NTF_HGHTCHG;
1129 infoPtr->calcSize.cx = clientcx;
1130 infoPtr->calcSize.cy = y;
1131 TRACE("horz, notify=%d, y=%d, origheight=%d\n",
1132 notify, y, origheight);
1133 if (notify && (y != origheight)) infoPtr->fStatus |= NTF_HGHTCHG;
1135 REBAR_DumpBand (hwnd);
1140 REBAR_ForceResize (HWND hwnd)
1141 /* Function: This changes the size of the REBAR window to that */
1142 /* calculated by REBAR_Layout. */
1144 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1147 TRACE( " from [%ld x %ld] to [%ld x %ld]!\n",
1148 infoPtr->oldSize.cx, infoPtr->oldSize.cy,
1149 infoPtr->calcSize.cx, infoPtr->calcSize.cy);
1151 /* if size did not change then skip process */
1152 if ((infoPtr->oldSize.cx == infoPtr->calcSize.cx) &&
1153 (infoPtr->oldSize.cy == infoPtr->calcSize.cy) &&
1154 !(infoPtr->fStatus & RESIZE_ANYHOW))
1157 infoPtr->fStatus &= ~RESIZE_ANYHOW;
1158 /* Set flag to ignore next WM_SIZE message */
1159 infoPtr->fStatus |= AUTO_RESIZE;
1163 rc.right = infoPtr->calcSize.cx;
1164 rc.bottom = infoPtr->calcSize.cy;
1166 if (GetWindowLongA (hwnd, GWL_STYLE) & WS_BORDER) {
1167 InflateRect (&rc, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
1170 SetWindowPos (hwnd, 0, 0, 0,
1171 rc.right - rc.left, rc.bottom - rc.top,
1172 SWP_NOMOVE | SWP_NOZORDER | SWP_SHOWWINDOW);
1177 REBAR_MoveChildWindows (HWND hwnd)
1179 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1181 CHAR szClassName[40];
1183 NMREBARCHILDSIZE rbcz;
1186 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1188 if (!(deferpos = BeginDeferWindowPos(8)))
1189 ERR("BeginDeferWindowPso returned NULL\n");
1191 for (i = 0; i < infoPtr->uNumBands; i++) {
1192 lpBand = &infoPtr->bands[i];
1194 if (HIDDENBAND(lpBand)) continue;
1195 if (lpBand->hwndChild) {
1196 TRACE("hwndChild = %x\n", lpBand->hwndChild);
1198 if (lpBand->fDraw & NTF_CHILDSIZE) {
1199 lpBand->fDraw &= ~NTF_CHILDSIZE;
1201 rbcz.wID = lpBand->wID;
1202 rbcz.rcChild = lpBand->rcChild;
1203 rbcz.rcBand = lpBand->rcBand;
1204 REBAR_Notify (hwnd, (NMHDR *)&rbcz, infoPtr, RBN_CHILDSIZE);
1205 if (!EqualRect (&lpBand->rcChild, &rbcz.rcChild)) {
1206 TRACE("Child rect changed by NOTIFY for band %u\n", i);
1207 TRACE(" from (%d,%d)-(%d,%d) to (%d,%d)-(%d,%d)\n",
1208 lpBand->rcChild.left, lpBand->rcChild.top,
1209 lpBand->rcChild.right, lpBand->rcChild.bottom,
1210 rbcz.rcChild.left, rbcz.rcChild.top,
1211 rbcz.rcChild.right, rbcz.rcChild.bottom);
1215 GetClassNameA (lpBand->hwndChild, szClassName, 40);
1216 if (!lstrcmpA (szClassName, "ComboBox")) {
1217 INT nEditHeight, yPos;
1220 /* special placement code for combo box */
1223 /* get size of edit line */
1224 GetWindowRect (lpBand->hwndChild, &rc);
1225 nEditHeight = rc.bottom - rc.top;
1226 yPos = (lpBand->rcChild.bottom + lpBand->rcChild.top - nEditHeight)/2;
1228 /* center combo box inside child area */
1229 TRACE("moving child %04x to (%d,%d)-(%d,%d)\n",
1231 lpBand->rcChild.left, yPos,
1232 lpBand->rcChild.right - lpBand->rcChild.left,
1234 deferpos = DeferWindowPos (deferpos, lpBand->hwndChild, HWND_TOP,
1235 lpBand->rcChild.left,
1236 /*lpBand->rcChild.top*/ yPos,
1237 lpBand->rcChild.right - lpBand->rcChild.left,
1241 ERR("DeferWindowPos returned NULL\n");
1244 else if (!lstrcmpA (szClassName, WC_COMBOBOXEXA)) {
1245 INT nEditHeight, yPos;
1249 /* special placement code for extended combo box */
1251 /* get size of edit line */
1252 hwndEdit = SendMessageA (lpBand->hwndChild, CBEM_GETEDITCONTROL, 0, 0);
1253 GetWindowRect (hwndEdit, &rc);
1254 nEditHeight = rc.bottom - rc.top;
1255 yPos = (lpBand->rcChild.bottom + lpBand->rcChild.top - nEditHeight)/2;
1257 /* center combo box inside child area */
1258 TRACE("moving child %04x to (%d,%d)-(%d,%d)\n",
1260 lpBand->rcChild.left, yPos,
1261 lpBand->rcChild.right - lpBand->rcChild.left,
1263 deferpos = DeferWindowPos (deferpos, lpBand->hwndChild, HWND_TOP,
1264 lpBand->rcChild.left,
1265 /*lpBand->rcChild.top*/ yPos,
1266 lpBand->rcChild.right - lpBand->rcChild.left,
1270 ERR("DeferWindowPos returned NULL\n");
1274 TRACE("moving child %04x to (%d,%d)-(%d,%d)\n",
1276 lpBand->rcChild.left, lpBand->rcChild.top,
1277 lpBand->rcChild.right - lpBand->rcChild.left,
1278 lpBand->rcChild.bottom - lpBand->rcChild.top);
1279 deferpos = DeferWindowPos (deferpos, lpBand->hwndChild, HWND_TOP,
1280 lpBand->rcChild.left,
1281 lpBand->rcChild.top,
1282 lpBand->rcChild.right - lpBand->rcChild.left,
1283 lpBand->rcChild.bottom - lpBand->rcChild.top,
1286 ERR("DeferWindowPos returned NULL\n");
1290 if (!EndDeferWindowPos(deferpos))
1291 ERR("EndDeferWindowPos returned NULL\n");
1292 if (infoPtr->fStatus & NTF_HGHTCHG) {
1293 infoPtr->fStatus &= ~NTF_HGHTCHG;
1294 REBAR_Notify (hwnd, &heightchange, infoPtr, RBN_HEIGHTCHANGE);
1300 REBAR_ValidateBand (HWND hwnd, REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
1301 /* Function: This routine evaluates the band specs supplied */
1302 /* by the user and updates the following 5 fields in */
1303 /* the internal band structure: cxHeader, lcx, lcy, hcx, hcy*/
1307 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1309 lpBand->fStatus = 0;
1315 /* Data comming in from users into the cx... and cy... fields */
1316 /* may be bad, just garbage, because the user never clears */
1317 /* the fields. RB_{SET|INSERT}BAND{A|W} just passes the data */
1318 /* along if the fields exist in the input area. Here we must */
1319 /* determine if the data is valid. I have no idea how MS does */
1320 /* the validation, but it does because the RB_GETBANDINFO */
1321 /* returns a 0 when I know the sample program passed in an */
1322 /* address. Here I will use the algorithim that if the value */
1323 /* is greater than 65535 then it is bad and replace it with */
1324 /* a zero. Feel free to improve the algorithim. - GA 12/2000 */
1325 if (lpBand->cxMinChild > 65535) lpBand->cxMinChild = 0;
1326 if (lpBand->cyMinChild > 65535) lpBand->cyMinChild = 0;
1327 if (lpBand->cx > 65535) lpBand->cx = 0;
1328 if (lpBand->cyChild > 65535) lpBand->cyChild = 0;
1329 if (lpBand->cyMaxChild > 65535) lpBand->cyMaxChild = 0;
1330 if (lpBand->cyIntegral > 65535) lpBand->cyIntegral = 0;
1331 if (lpBand->cxIdeal > 65535) lpBand->cxIdeal = 0;
1332 if (lpBand->cxHeader > 65535) lpBand->cxHeader = 0;
1334 /* Header is where the image, text and gripper exist */
1335 /* in the band and preceed the child window. */
1337 /* calculate gripper rectangle */
1338 if ( (!(lpBand->fStyle & RBBS_NOGRIPPER)) &&
1339 ( (lpBand->fStyle & RBBS_GRIPPERALWAYS) ||
1340 ( !(lpBand->fStyle & RBBS_FIXEDSIZE) && (infoPtr->uNumBands > 1)))
1342 lpBand->fStatus |= HAS_GRIPPER;
1343 if (dwStyle & CCS_VERT)
1344 if (dwStyle & RBS_VERTICALGRIPPER)
1345 header += (GRIPPER_HEIGHT + REBAR_PRE_GRIPPER);
1347 header += (GRIPPER_WIDTH + REBAR_PRE_GRIPPER);
1349 header += (REBAR_PRE_GRIPPER + GRIPPER_WIDTH);
1350 /* Always have 4 pixels before anything else */
1351 header += REBAR_ALWAYS_SPACE;
1353 else { /* no gripper will be drawn */
1354 if (((lpBand->fMask & RBBIM_IMAGE) && (infoPtr->himl)) ||
1355 ((lpBand->fMask & RBBIM_TEXT) && (lpBand->lpText)))
1356 /* if no gripper but either image or text, then leave space */
1357 header += REBAR_ALWAYS_SPACE;
1361 /* image is visible */
1362 if ((lpBand->fMask & RBBIM_IMAGE) && (infoPtr->himl)) {
1363 lpBand->fStatus |= HAS_IMAGE;
1364 if (dwStyle & CCS_VERT) {
1365 header += (infoPtr->imageSize.cy + REBAR_POST_IMAGE);
1366 lpBand->lcy = infoPtr->imageSize.cx + 2;
1369 header += (infoPtr->imageSize.cx + REBAR_POST_IMAGE);
1370 lpBand->lcy = infoPtr->imageSize.cy + 2;
1374 /* text is visible */
1375 if ((lpBand->fMask & RBBIM_TEXT) && (lpBand->lpText)) {
1376 HDC hdc = GetDC (0);
1377 HFONT hOldFont = SelectObject (hdc, infoPtr->hFont);
1380 lpBand->fStatus |= HAS_TEXT;
1381 GetTextExtentPoint32W (hdc, lpBand->lpText,
1382 lstrlenW (lpBand->lpText), &size);
1383 header += ((dwStyle & CCS_VERT) ? (size.cy + REBAR_POST_TEXT) : (size.cx + REBAR_POST_TEXT));
1384 textheight = (dwStyle & CCS_VERT) ? 0 : size.cy;
1386 SelectObject (hdc, hOldFont);
1390 /* check if user overrode the header value */
1391 if (!(lpBand->fMask & RBBIM_HEADERSIZE))
1392 lpBand->cxHeader = header;
1395 /* Now compute minimum size of child window */
1396 lpBand->offChild.cx = 0;
1397 lpBand->offChild.cy = 0;
1398 lpBand->lcy = textheight;
1399 if (lpBand->fMask & RBBIM_CHILDSIZE) {
1400 if (!(lpBand->fStyle & RBBS_FIXEDSIZE)) {
1401 lpBand->offChild.cx = 4;
1402 lpBand->offChild.cy = 2;
1404 lpBand->lcx = lpBand->cxMinChild;
1405 lpBand->lcy = max(lpBand->lcy, lpBand->cyMinChild);
1406 lpBand->hcy = lpBand->lcy;
1407 if (lpBand->fStyle & RBBS_VARIABLEHEIGHT) {
1408 if (lpBand->cyChild != 0xffffffff)
1409 lpBand->lcy = max (lpBand->cyChild, lpBand->lcy);
1410 lpBand->hcy = lpBand->cyMaxChild;
1412 TRACE("_CHILDSIZE\n");
1414 if (lpBand->fMask & RBBIM_SIZE) {
1415 lpBand->hcx = max (lpBand->cx, lpBand->lcx);
1419 lpBand->hcx = lpBand->lcx;
1424 REBAR_CommonSetupBand (HWND hwnd, LPREBARBANDINFOA lprbbi, REBAR_BAND *lpBand)
1425 /* Function: This routine copies the supplied values from */
1426 /* user input (lprbbi) to the internal band structure. */
1428 lpBand->fMask |= lprbbi->fMask;
1430 if (lprbbi->fMask & RBBIM_STYLE)
1431 lpBand->fStyle = lprbbi->fStyle;
1433 if (lprbbi->fMask & RBBIM_COLORS) {
1434 lpBand->clrFore = lprbbi->clrFore;
1435 lpBand->clrBack = lprbbi->clrBack;
1438 if (lprbbi->fMask & RBBIM_IMAGE)
1439 lpBand->iImage = lprbbi->iImage;
1441 if (lprbbi->fMask & RBBIM_CHILD) {
1442 if (lprbbi->hwndChild) {
1443 lpBand->hwndChild = lprbbi->hwndChild;
1444 lpBand->hwndPrevParent =
1445 SetParent (lpBand->hwndChild, hwnd);
1448 TRACE("child: 0x%x prev parent: 0x%x\n",
1449 lpBand->hwndChild, lpBand->hwndPrevParent);
1450 lpBand->hwndChild = 0;
1451 lpBand->hwndPrevParent = 0;
1455 if (lprbbi->fMask & RBBIM_CHILDSIZE) {
1456 lpBand->cxMinChild = lprbbi->cxMinChild;
1457 lpBand->cyMinChild = lprbbi->cyMinChild;
1458 if (lprbbi->cbSize >= sizeof (REBARBANDINFOA)) {
1459 lpBand->cyChild = lprbbi->cyChild;
1460 lpBand->cyMaxChild = lprbbi->cyMaxChild;
1461 lpBand->cyIntegral = lprbbi->cyIntegral;
1463 else { /* special case - these should be zeroed out since */
1464 /* RBBIM_CHILDSIZE added these in WIN32_IE >= 0x0400 */
1465 lpBand->cyChild = 0;
1466 lpBand->cyMaxChild = 0;
1467 lpBand->cyIntegral = 0;
1471 if (lprbbi->fMask & RBBIM_SIZE)
1472 lpBand->cx = lprbbi->cx;
1474 if (lprbbi->fMask & RBBIM_BACKGROUND)
1475 lpBand->hbmBack = lprbbi->hbmBack;
1477 if (lprbbi->fMask & RBBIM_ID)
1478 lpBand->wID = lprbbi->wID;
1480 /* check for additional data */
1481 if (lprbbi->cbSize >= sizeof (REBARBANDINFOA)) {
1482 if (lprbbi->fMask & RBBIM_IDEALSIZE)
1483 lpBand->cxIdeal = lprbbi->cxIdeal;
1485 if (lprbbi->fMask & RBBIM_LPARAM)
1486 lpBand->lParam = lprbbi->lParam;
1488 if (lprbbi->fMask & RBBIM_HEADERSIZE)
1489 lpBand->cxHeader = lprbbi->cxHeader;
1494 REBAR_InternalEraseBkGnd (HWND hwnd, WPARAM wParam, LPARAM lParam, RECT *clip)
1495 /* Function: This erases the background rectangle with the */
1496 /* default brush, then with any band that has a different */
1497 /* background color. */
1499 HBRUSH hbrBackground = GetClassWord(hwnd, GCW_HBRBACKGROUND);
1500 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1506 FillRect( (HDC) wParam, clip, hbrBackground);
1508 for(i=0; i<infoPtr->uNumBands; i++) {
1509 lpBand = &infoPtr->bands[i];
1510 if (lpBand->clrBack != CLR_NONE) {
1511 if (IntersectRect (&eraserect, clip, &lpBand->rcBand)) {
1512 /* draw background */
1513 HBRUSH brh = CreateSolidBrush (lpBand->clrBack);
1514 TRACE("backround color=0x%06lx, band (%d,%d)-(%d,%d), clip (%d,%d)-(%d,%d)\n",
1516 lpBand->rcBand.left,lpBand->rcBand.top,
1517 lpBand->rcBand.right,lpBand->rcBand.bottom,
1518 clip->left, clip->top,
1519 clip->right, clip->bottom);
1520 FillRect ( (HDC)wParam, &eraserect, brh);
1529 REBAR_InternalHitTest (HWND hwnd, LPPOINT lpPt, UINT *pFlags, INT *pBand)
1531 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1536 GetClientRect (hwnd, &rect);
1538 *pFlags = RBHT_NOWHERE;
1539 if (PtInRect (&rect, *lpPt))
1541 if (infoPtr->uNumBands == 0) {
1542 *pFlags = RBHT_NOWHERE;
1549 /* somewhere inside */
1550 infoPtr->ihitBand = -1;
1551 for (iCount = 0; iCount < infoPtr->uNumBands; iCount++) {
1552 lpBand = &infoPtr->bands[iCount];
1553 if (PtInRect (&lpBand->rcBand, *lpPt)) {
1556 if (PtInRect (&lpBand->rcGripper, *lpPt)) {
1557 *pFlags = RBHT_GRABBER;
1558 infoPtr->ihitBand = iCount;
1559 TRACE("ON GRABBER %d\n", iCount);
1562 else if (PtInRect (&lpBand->rcCapImage, *lpPt)) {
1563 *pFlags = RBHT_CAPTION;
1564 TRACE("ON CAPTION %d\n", iCount);
1567 else if (PtInRect (&lpBand->rcCapText, *lpPt)) {
1568 *pFlags = RBHT_CAPTION;
1569 TRACE("ON CAPTION %d\n", iCount);
1572 else if (PtInRect (&lpBand->rcChild, *lpPt)) {
1573 *pFlags = RBHT_CLIENT;
1574 TRACE("ON CLIENT %d\n", iCount);
1578 *pFlags = RBHT_NOWHERE;
1579 TRACE("NOWHERE %d\n", iCount);
1585 *pFlags = RBHT_NOWHERE;
1594 *pFlags = RBHT_NOWHERE;
1601 TRACE("flags=0x%X\n", *pFlags);
1605 #define READJ(b,i) {if(dwStyle & CCS_VERT) b->rcBand.bottom+=(i); \
1606 else b->rcBand.right += (i);}
1607 #define LEADJ(b,i) {if(dwStyle & CCS_VERT) b->rcBand.top+=(i); \
1608 else b->rcBand.left += (i);}
1612 REBAR_Shrink (REBAR_BAND *band, INT movement, INT i, DWORD dwStyle)
1613 /* Function: This attempts to shrink the given band by the */
1614 /* the amount in "movement". A shrink to the left is indi- */
1615 /* cated by "movement" being negative. "i" is merely the */
1616 /* band index for trace messages. */
1618 INT Leadjust, Readjust, avail, ret;
1620 /* Note: a left drag is indicated by "movement" being negative. */
1621 /* Similarly, a right drag is indicated by "movement" */
1622 /* being positive. "movement" should never be 0, but if */
1623 /* it is then the band does not move. */
1625 avail = rcBrb(band) - rcBlt(band) - band->cxHeader - band->lcx;
1627 /* now compute the Left End adjustment factor and Right End */
1628 /* adjustment factor. They may be different if shrinking. */
1630 /* if this band is not shrinkable, then just move it */
1631 Leadjust = Readjust = movement;
1637 if (avail <= abs(movement)) {
1638 Readjust = movement;
1639 Leadjust = movement + avail;
1643 Readjust = movement;
1650 if (avail <= abs(movement)) {
1651 Leadjust = movement;
1652 Readjust = movement - avail;
1656 Leadjust = movement;
1663 /* Reasonability Check */
1664 if (rcBlt(band) + Leadjust < 0) {
1665 ERR("adjustment will fail, band %d: left=%d, right=%d, move=%d, rtn=%d\n",
1666 i, Leadjust, Readjust, movement, ret);
1669 LEADJ(band, Leadjust);
1670 READJ(band, Readjust);
1672 TRACE("band %d: left=%d, right=%d, move=%d, rtn=%d, rcBand=(%d,%d)-(%d,%d)\n",
1673 i, Leadjust, Readjust, movement, ret,
1674 band->rcBand.left, band->rcBand.top,
1675 band->rcBand.right, band->rcBand.bottom);
1681 REBAR_HandleLRDrag (HWND hwnd, REBAR_INFO *infoPtr, POINTS *ptsmove, DWORD dwStyle)
1682 /* Function: This will implement the functionality of a */
1683 /* Gripper drag within a row. It will not implement "out- */
1684 /* of-row" drags. (They are detected and handled in */
1685 /* REBAR_MouseMove.) */
1686 /* **** FIXME Switching order of bands in a row not **** */
1687 /* **** yet implemented. **** */
1689 REBAR_BAND *hitBand, *band, *prevband, *mindBand, *maxdBand;
1691 NMREBARCHILDSIZE cs;
1693 INT imindBand = -1, imaxdBand, ihitBand, i, movement, tempx;
1694 INT RHeaderSum = 0, LHeaderSum = 0;
1697 /* on first significant mouse movement, issue notify */
1699 if (!(infoPtr->fStatus & BEGIN_DRAG_ISSUED)) {
1700 if (REBAR_Notify_NMREBAR (hwnd, infoPtr, -1, RBN_BEGINDRAG)) {
1701 /* Notify returned TRUE - abort drag */
1702 infoPtr->dragStart.x = 0;
1703 infoPtr->dragStart.y = 0;
1704 infoPtr->dragNow = infoPtr->dragStart;
1705 infoPtr->ihitBand = -1;
1709 infoPtr->fStatus |= BEGIN_DRAG_ISSUED;
1712 ihitBand = infoPtr->ihitBand;
1713 hitBand = &infoPtr->bands[ihitBand];
1714 imaxdBand = ihitBand; /* to suppress warning message */
1716 /* find all the bands in the row of the one whose Gripper was seized */
1717 for (i=0; i<infoPtr->uNumBands; i++) {
1718 band = &infoPtr->bands[i];
1719 if (HIDDENBAND(band)) continue;
1720 if (band->iRow == hitBand->iRow) {
1722 if (imindBand == -1) imindBand = i;
1723 /* minimum size of each band is size of header plus */
1724 /* size of minimum child plus offset of child from header plus */
1725 /* a one to separate each band. */
1727 LHeaderSum += (band->cxHeader + band->lcx + SEP_WIDTH);
1729 RHeaderSum += (band->cxHeader + band->lcx + SEP_WIDTH);
1733 if (RHeaderSum) RHeaderSum -= SEP_WIDTH; /* no separator afterlast band */
1735 mindBand = &infoPtr->bands[imindBand];
1736 maxdBand = &infoPtr->bands[imaxdBand];
1738 if (imindBand == imaxdBand) return; /* nothing to drag agains */
1739 if (imindBand == ihitBand) return; /* first band in row, cant drag */
1741 /* limit movement to inside adjustable bands - Left */
1742 if ( (ptsmove->x < mindBand->rcBand.left) ||
1743 (ptsmove->x > maxdBand->rcBand.right) ||
1744 (ptsmove->y < mindBand->rcBand.top) ||
1745 (ptsmove->y > maxdBand->rcBand.bottom))
1746 return; /* should swap bands */
1748 if (dwStyle & CCS_VERT)
1749 movement = ptsmove->y - ((hitBand->rcBand.top+REBAR_PRE_GRIPPER) -
1750 infoPtr->ihitoffset);
1752 movement = ptsmove->x - ((hitBand->rcBand.left+REBAR_PRE_GRIPPER) -
1753 infoPtr->ihitoffset);
1754 infoPtr->dragNow = *ptsmove;
1756 TRACE("before: movement=%d (%d,%d), imindBand=%d, ihitBand=%d, imaxdBand=%d, LSum=%d, RSum=%d\n",
1757 movement, ptsmove->x, ptsmove->y, imindBand, ihitBand,
1758 imaxdBand, LHeaderSum, RHeaderSum);
1759 REBAR_DumpBand (hwnd);
1763 /* *** Drag left/up *** */
1764 compress = rcBlt(hitBand) - rcBlt(mindBand) -
1766 if (compress < abs(movement)) {
1767 TRACE("limiting left drag, was %d changed to %d\n",
1768 movement, -compress);
1769 movement = -compress;
1771 for (i=ihitBand; i>=imindBand; i--) {
1772 band = &infoPtr->bands[i];
1773 if (i == ihitBand) {
1774 prevband = &infoPtr->bands[i-1];
1775 if (rcBlt(band) - movement <= rcBlt(prevband)) {
1776 tempx = movement - (rcBrb(prevband)-rcBlt(band)+1);
1777 ERR("movement bad. BUG!! was %d, left=%d, right=%d, setting to %d\n",
1778 movement, rcBlt(band), rcBlt(prevband), tempx);
1781 LEADJ(band, movement)
1784 movement = REBAR_Shrink (band, movement, i, dwStyle);
1789 /* *** Drag right/down *** */
1790 compress = rcBrb(maxdBand) - rcBlt(hitBand) -
1792 if (compress < abs(movement)) {
1793 TRACE("limiting right drag, was %d changed to %d\n",
1794 movement, compress);
1795 movement = compress;
1797 for (i=ihitBand-1; i<=imaxdBand; i++) {
1798 band = &infoPtr->bands[i];
1799 if (HIDDENBAND(band)) continue;
1800 if (i == ihitBand-1) {
1801 READJ(band, movement)
1804 movement = REBAR_Shrink (band, movement, i, dwStyle);
1808 /* recompute all rectangles */
1809 if (dwStyle & CCS_VERT) {
1810 REBAR_CalcVertBand (hwnd, infoPtr, imindBand, imaxdBand+1,
1814 REBAR_CalcHorzBand (hwnd, infoPtr, imindBand, imaxdBand+1,
1818 TRACE("bands after adjustment, see band # %d, %d\n",
1819 imindBand, imaxdBand);
1820 REBAR_DumpBand (hwnd);
1823 mindBand->rcBand.left,
1824 mindBand->rcBand.top,
1825 maxdBand->rcBand.right,
1826 maxdBand->rcBand.bottom);
1828 if (!(deferpos = BeginDeferWindowPos (4))) {
1829 ERR("BeginDeferWindowPos returned NULL\n");
1832 for (i=imindBand; i<=imaxdBand; i++) {
1833 band = &infoPtr->bands[i];
1834 if ((band->fMask & RBBIM_CHILD) && band->hwndChild) {
1837 cs.rcChild = band->rcChild;
1838 cs.rcBand = band->rcBand;
1839 REBAR_Notify (hwnd, (NMHDR *) &cs, infoPtr, RBN_CHILDSIZE);
1840 deferpos = DeferWindowPos (deferpos, band->hwndChild, HWND_TOP,
1841 cs.rcChild.left, cs.rcChild.top,
1842 cs.rcChild.right - cs.rcChild.left,
1843 cs.rcChild.bottom - cs.rcChild.top,
1846 ERR("DeferWindowPos returned NULL\n");
1851 if (!EndDeferWindowPos (deferpos)) {
1852 ERR("EndDeferWindowPos failed\n");
1855 InvalidateRect (hwnd, &newrect, TRUE);
1856 UpdateWindow (hwnd);
1864 /* << REBAR_BeginDrag >> */
1868 REBAR_DeleteBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
1870 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1871 UINT uBand = (UINT)wParam;
1875 if (uBand >= infoPtr->uNumBands)
1878 TRACE("deleting band %u!\n", uBand);
1879 lpBand = &infoPtr->bands[uBand];
1880 REBAR_Notify_NMREBAR (hwnd, infoPtr, uBand, RBN_DELETINGBAND);
1882 if (infoPtr->uNumBands == 1) {
1883 TRACE(" simple delete!\n");
1884 if ((lpBand->fMask & RBBIM_CHILD) && lpBand->hwndChild)
1885 childhwnd = lpBand->hwndChild;
1886 COMCTL32_Free (infoPtr->bands);
1887 infoPtr->bands = NULL;
1888 infoPtr->uNumBands = 0;
1891 REBAR_BAND *oldBands = infoPtr->bands;
1892 TRACE("complex delete! [uBand=%u]\n", uBand);
1894 if ((lpBand->fMask & RBBIM_CHILD) && lpBand->hwndChild)
1895 childhwnd = lpBand->hwndChild;
1897 infoPtr->uNumBands--;
1898 infoPtr->bands = COMCTL32_Alloc (sizeof (REBAR_BAND) * infoPtr->uNumBands);
1900 memcpy (&infoPtr->bands[0], &oldBands[0],
1901 uBand * sizeof(REBAR_BAND));
1904 if (uBand < infoPtr->uNumBands) {
1905 memcpy (&infoPtr->bands[uBand], &oldBands[uBand+1],
1906 (infoPtr->uNumBands - uBand) * sizeof(REBAR_BAND));
1909 COMCTL32_Free (oldBands);
1913 ShowWindow (childhwnd, SW_HIDE);
1915 REBAR_Notify_NMREBAR (hwnd, infoPtr, -1, RBN_DELETEDBAND);
1917 /* if only 1 band left the re-validate to possible eliminate gripper */
1918 if (infoPtr->uNumBands == 1)
1919 REBAR_ValidateBand (hwnd, infoPtr, &infoPtr->bands[0]);
1921 REBAR_Layout (hwnd, NULL, TRUE, FALSE);
1922 infoPtr->fStatus |= RESIZE_ANYHOW;
1923 REBAR_ForceResize (hwnd);
1924 REBAR_MoveChildWindows (hwnd);
1930 /* << REBAR_DragMove >> */
1931 /* << REBAR_EndDrag >> */
1935 REBAR_GetBandBorders (HWND hwnd, WPARAM wParam, LPARAM lParam)
1937 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1938 LPRECT lpRect = (LPRECT)lParam;
1940 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1944 if ((UINT)wParam >= infoPtr->uNumBands)
1947 lpBand = &infoPtr->bands[(UINT)wParam];
1949 /* FIXME - the following values were determined by experimentation */
1950 /* with the REBAR Control Spy. I have guesses as to what the 4 and */
1951 /* 1 are, but I am not sure. There doesn't seem to be any actual */
1952 /* difference in size of the control area with and without the */
1954 if (GetWindowLongA (hwnd, GWL_STYLE) & RBS_BANDBORDERS) {
1955 if (dwStyle & CCS_VERT) {
1957 lpRect->top = lpBand->cxHeader + 4;
1962 lpRect->left = lpBand->cxHeader + 4;
1969 lpRect->left = lpBand->cxHeader;
1976 inline static LRESULT
1977 REBAR_GetBandCount (HWND hwnd)
1979 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1981 TRACE("band count %u!\n", infoPtr->uNumBands);
1983 return infoPtr->uNumBands;
1988 REBAR_GetBandInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1990 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1991 LPREBARBANDINFOA lprbbi = (LPREBARBANDINFOA)lParam;
1996 if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEA)
1998 if ((UINT)wParam >= infoPtr->uNumBands)
2001 TRACE("index %u\n", (UINT)wParam);
2003 /* copy band information */
2004 lpBand = &infoPtr->bands[(UINT)wParam];
2006 if (lprbbi->fMask & RBBIM_STYLE)
2007 lprbbi->fStyle = lpBand->fStyle;
2009 if (lprbbi->fMask & RBBIM_COLORS) {
2010 lprbbi->clrFore = lpBand->clrFore;
2011 lprbbi->clrBack = lpBand->clrBack;
2012 if (lprbbi->clrBack == CLR_NONE)
2013 lprbbi->clrBack = GetSysColor (COLOR_BTNFACE);
2016 if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) {
2017 if (lpBand->lpText && (lpBand->fMask & RBBIM_TEXT))
2019 if (!WideCharToMultiByte( CP_ACP, 0, lpBand->lpText, -1,
2020 lprbbi->lpText, lprbbi->cch, NULL, NULL ))
2021 lprbbi->lpText[lprbbi->cch-1] = 0;
2024 *lprbbi->lpText = 0;
2027 if (lprbbi->fMask & RBBIM_IMAGE) {
2028 if (lpBand->fMask & RBBIM_IMAGE)
2029 lprbbi->iImage = lpBand->iImage;
2031 lprbbi->iImage = -1;
2034 if (lprbbi->fMask & RBBIM_CHILD)
2035 lprbbi->hwndChild = lpBand->hwndChild;
2037 if (lprbbi->fMask & RBBIM_CHILDSIZE) {
2038 lprbbi->cxMinChild = lpBand->cxMinChild;
2039 lprbbi->cyMinChild = lpBand->cyMinChild;
2040 if (lprbbi->cbSize >= sizeof (REBARBANDINFOA)) {
2041 lprbbi->cyChild = lpBand->cyChild;
2042 lprbbi->cyMaxChild = lpBand->cyMaxChild;
2043 lprbbi->cyIntegral = lpBand->cyIntegral;
2047 if (lprbbi->fMask & RBBIM_SIZE)
2048 lprbbi->cx = lpBand->cx;
2050 if (lprbbi->fMask & RBBIM_BACKGROUND)
2051 lprbbi->hbmBack = lpBand->hbmBack;
2053 if (lprbbi->fMask & RBBIM_ID)
2054 lprbbi->wID = lpBand->wID;
2056 /* check for additional data */
2057 if (lprbbi->cbSize >= sizeof (REBARBANDINFOA)) {
2058 if (lprbbi->fMask & RBBIM_IDEALSIZE)
2059 lprbbi->cxIdeal = lpBand->cxIdeal;
2061 if (lprbbi->fMask & RBBIM_LPARAM)
2062 lprbbi->lParam = lpBand->lParam;
2064 if (lprbbi->fMask & RBBIM_HEADERSIZE)
2065 lprbbi->cxHeader = lpBand->cxHeader;
2068 REBAR_DumpBandInfo (lprbbi);
2075 REBAR_GetBandInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2077 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2078 LPREBARBANDINFOW lprbbi = (LPREBARBANDINFOW)lParam;
2083 if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEW)
2085 if ((UINT)wParam >= infoPtr->uNumBands)
2088 TRACE("index %u\n", (UINT)wParam);
2090 /* copy band information */
2091 lpBand = &infoPtr->bands[(UINT)wParam];
2093 if (lprbbi->fMask & RBBIM_STYLE)
2094 lprbbi->fStyle = lpBand->fStyle;
2096 if (lprbbi->fMask & RBBIM_COLORS) {
2097 lprbbi->clrFore = lpBand->clrFore;
2098 lprbbi->clrBack = lpBand->clrBack;
2099 if (lprbbi->clrBack == CLR_NONE)
2100 lprbbi->clrBack = GetSysColor (COLOR_BTNFACE);
2103 if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) {
2104 if (lpBand->lpText && (lpBand->fMask & RBBIM_TEXT))
2105 lstrcpynW (lprbbi->lpText, lpBand->lpText, lprbbi->cch);
2107 *lprbbi->lpText = 0;
2110 if (lprbbi->fMask & RBBIM_IMAGE) {
2111 if (lpBand->fMask & RBBIM_IMAGE)
2112 lprbbi->iImage = lpBand->iImage;
2114 lprbbi->iImage = -1;
2117 if (lprbbi->fMask & RBBIM_CHILD)
2118 lprbbi->hwndChild = lpBand->hwndChild;
2120 if (lprbbi->fMask & RBBIM_CHILDSIZE) {
2121 lprbbi->cxMinChild = lpBand->cxMinChild;
2122 lprbbi->cyMinChild = lpBand->cyMinChild;
2123 if (lprbbi->cbSize >= sizeof (REBARBANDINFOW)) {
2124 lprbbi->cyChild = lpBand->cyChild;
2125 lprbbi->cyMaxChild = lpBand->cyMaxChild;
2126 lprbbi->cyIntegral = lpBand->cyIntegral;
2130 if (lprbbi->fMask & RBBIM_SIZE)
2131 lprbbi->cx = lpBand->cx;
2133 if (lprbbi->fMask & RBBIM_BACKGROUND)
2134 lprbbi->hbmBack = lpBand->hbmBack;
2136 if (lprbbi->fMask & RBBIM_ID)
2137 lprbbi->wID = lpBand->wID;
2139 /* check for additional data */
2140 if (lprbbi->cbSize >= sizeof (REBARBANDINFOW)) {
2141 if (lprbbi->fMask & RBBIM_IDEALSIZE)
2142 lprbbi->cxIdeal = lpBand->cxIdeal;
2144 if (lprbbi->fMask & RBBIM_LPARAM)
2145 lprbbi->lParam = lpBand->lParam;
2147 if (lprbbi->fMask & RBBIM_HEADERSIZE)
2148 lprbbi->cxHeader = lpBand->cxHeader;
2151 REBAR_DumpBandInfo ((LPREBARBANDINFOA)lprbbi);
2158 REBAR_GetBarHeight (HWND hwnd, WPARAM wParam, LPARAM lParam)
2160 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2162 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
2164 nHeight = (dwStyle & CCS_VERT) ? infoPtr->calcSize.cx : infoPtr->calcSize.cy;
2166 TRACE("height = %d\n", nHeight);
2173 REBAR_GetBarInfo (HWND hwnd, WPARAM wParam, LPARAM lParam)
2175 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2176 LPREBARINFO lpInfo = (LPREBARINFO)lParam;
2181 if (lpInfo->cbSize < sizeof (REBARINFO))
2184 TRACE("getting bar info!\n");
2186 if (infoPtr->himl) {
2187 lpInfo->himl = infoPtr->himl;
2188 lpInfo->fMask |= RBIM_IMAGELIST;
2195 inline static LRESULT
2196 REBAR_GetBkColor (HWND hwnd)
2198 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2199 COLORREF clr = infoPtr->clrBk;
2201 if (clr == CLR_NONE)
2202 clr = GetSysColor (COLOR_BTNFACE);
2204 TRACE("background color 0x%06lx!\n", clr);
2210 /* << REBAR_GetColorScheme >> */
2211 /* << REBAR_GetDropTarget >> */
2215 REBAR_GetPalette (HWND hwnd, WPARAM wParam, LPARAM lParam)
2217 FIXME("empty stub!\n");
2224 REBAR_GetRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
2226 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2227 INT iBand = (INT)wParam;
2228 LPRECT lprc = (LPRECT)lParam;
2231 if ((iBand < 0) && ((UINT)iBand >= infoPtr->uNumBands))
2236 lpBand = &infoPtr->bands[iBand];
2237 CopyRect (lprc, &lpBand->rcBand);
2239 TRACE("band %d, (%d,%d)-(%d,%d)\n", iBand,
2240 lprc->left, lprc->top, lprc->right, lprc->bottom);
2246 inline static LRESULT
2247 REBAR_GetRowCount (HWND hwnd)
2249 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2251 TRACE("%u\n", infoPtr->uNumRows);
2253 return infoPtr->uNumRows;
2258 REBAR_GetRowHeight (HWND hwnd, WPARAM wParam, LPARAM lParam)
2260 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2261 INT iRow = (INT)wParam;
2265 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
2267 for (i=0; i<infoPtr->uNumBands; i++) {
2268 lpBand = &infoPtr->bands[i];
2269 if (HIDDENBAND(lpBand)) continue;
2270 if (lpBand->iRow != iRow) continue;
2271 if (dwStyle & CCS_VERT)
2272 j = lpBand->rcBand.right - lpBand->rcBand.left;
2274 j = lpBand->rcBand.bottom - lpBand->rcBand.top;
2275 if (j > ret) ret = j;
2278 TRACE("row %d, height %d\n", iRow, ret);
2284 inline static LRESULT
2285 REBAR_GetTextColor (HWND hwnd)
2287 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2289 TRACE("text color 0x%06lx!\n", infoPtr->clrText);
2291 return infoPtr->clrText;
2295 inline static LRESULT
2296 REBAR_GetToolTips (HWND hwnd)
2298 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2299 return infoPtr->hwndToolTip;
2303 inline static LRESULT
2304 REBAR_GetUnicodeFormat (HWND hwnd)
2306 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2307 return infoPtr->bUnicode;
2311 inline static LRESULT
2312 REBAR_GetVersion (HWND hwnd)
2314 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2315 TRACE("version %d\n", infoPtr->iVersion);
2316 return infoPtr->iVersion;
2321 REBAR_HitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
2323 /* REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */
2324 LPRBHITTESTINFO lprbht = (LPRBHITTESTINFO)lParam;
2329 REBAR_InternalHitTest (hwnd, &lprbht->pt, &lprbht->flags, &lprbht->iBand);
2331 return lprbht->iBand;
2336 REBAR_IdToIndex (HWND hwnd, WPARAM wParam, LPARAM lParam)
2338 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2341 if (infoPtr == NULL)
2344 if (infoPtr->uNumBands < 1)
2347 for (i = 0; i < infoPtr->uNumBands; i++) {
2348 if (infoPtr->bands[i].wID == (UINT)wParam) {
2349 TRACE("id %u is band %u found!\n", (UINT)wParam, i);
2354 TRACE("id %u is not found\n", (UINT)wParam);
2360 REBAR_InsertBandA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2362 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2363 LPREBARBANDINFOA lprbbi = (LPREBARBANDINFOA)lParam;
2364 UINT uIndex = (UINT)wParam;
2367 if (infoPtr == NULL)
2371 if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEA)
2374 /* trace the index as signed to see the -1 */
2375 TRACE("insert band at %d!\n", (INT)uIndex);
2376 REBAR_DumpBandInfo (lprbbi);
2378 if (infoPtr->uNumBands == 0) {
2379 infoPtr->bands = (REBAR_BAND *)COMCTL32_Alloc (sizeof (REBAR_BAND));
2383 REBAR_BAND *oldBands = infoPtr->bands;
2385 (REBAR_BAND *)COMCTL32_Alloc ((infoPtr->uNumBands+1)*sizeof(REBAR_BAND));
2386 if (((INT)uIndex == -1) || (uIndex > infoPtr->uNumBands))
2387 uIndex = infoPtr->uNumBands;
2389 /* pre insert copy */
2391 memcpy (&infoPtr->bands[0], &oldBands[0],
2392 uIndex * sizeof(REBAR_BAND));
2396 if (uIndex < infoPtr->uNumBands - 1) {
2397 memcpy (&infoPtr->bands[uIndex+1], &oldBands[uIndex],
2398 (infoPtr->uNumBands - uIndex - 1) * sizeof(REBAR_BAND));
2401 COMCTL32_Free (oldBands);
2404 infoPtr->uNumBands++;
2406 TRACE("index %u!\n", uIndex);
2408 /* initialize band (infoPtr->bands[uIndex])*/
2409 lpBand = &infoPtr->bands[uIndex];
2411 lpBand->fStatus = 0;
2412 lpBand->clrFore = infoPtr->clrText;
2413 lpBand->clrBack = infoPtr->clrBk;
2414 lpBand->hwndChild = 0;
2415 lpBand->hwndPrevParent = 0;
2417 REBAR_CommonSetupBand (hwnd, lprbbi, lpBand);
2418 lpBand->lpText = NULL;
2419 if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) {
2420 INT len = MultiByteToWideChar( CP_ACP, 0, lprbbi->lpText, -1, NULL, 0 );
2422 lpBand->lpText = (LPWSTR)COMCTL32_Alloc (len*sizeof(WCHAR));
2423 MultiByteToWideChar( CP_ACP, 0, lprbbi->lpText, -1, lpBand->lpText, len );
2427 REBAR_ValidateBand (hwnd, infoPtr, lpBand);
2429 REBAR_DumpBand (hwnd);
2431 REBAR_Layout (hwnd, NULL, TRUE, FALSE);
2432 REBAR_ForceResize (hwnd);
2433 REBAR_MoveChildWindows (hwnd);
2440 REBAR_InsertBandW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2442 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2443 LPREBARBANDINFOW lprbbi = (LPREBARBANDINFOW)lParam;
2444 UINT uIndex = (UINT)wParam;
2447 if (infoPtr == NULL)
2451 if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEW)
2454 /* trace the index as signed to see the -1 */
2455 TRACE("insert band at %d!\n", (INT)uIndex);
2456 REBAR_DumpBandInfo ((LPREBARBANDINFOA)lprbbi);
2458 if (infoPtr->uNumBands == 0) {
2459 infoPtr->bands = (REBAR_BAND *)COMCTL32_Alloc (sizeof (REBAR_BAND));
2463 REBAR_BAND *oldBands = infoPtr->bands;
2465 (REBAR_BAND *)COMCTL32_Alloc ((infoPtr->uNumBands+1)*sizeof(REBAR_BAND));
2466 if (((INT)uIndex == -1) || (uIndex > infoPtr->uNumBands))
2467 uIndex = infoPtr->uNumBands;
2469 /* pre insert copy */
2471 memcpy (&infoPtr->bands[0], &oldBands[0],
2472 uIndex * sizeof(REBAR_BAND));
2476 if (uIndex < infoPtr->uNumBands - 1) {
2477 memcpy (&infoPtr->bands[uIndex+1], &oldBands[uIndex],
2478 (infoPtr->uNumBands - uIndex - 1) * sizeof(REBAR_BAND));
2481 COMCTL32_Free (oldBands);
2484 infoPtr->uNumBands++;
2486 TRACE("index %u!\n", uIndex);
2488 /* initialize band (infoPtr->bands[uIndex])*/
2489 lpBand = &infoPtr->bands[uIndex];
2491 lpBand->fStatus = 0;
2492 lpBand->clrFore = infoPtr->clrText;
2493 lpBand->clrBack = infoPtr->clrBk;
2494 lpBand->hwndChild = 0;
2495 lpBand->hwndPrevParent = 0;
2497 REBAR_CommonSetupBand (hwnd, (LPREBARBANDINFOA)lprbbi, lpBand);
2498 lpBand->lpText = NULL;
2499 if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) {
2500 INT len = lstrlenW (lprbbi->lpText);
2502 lpBand->lpText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
2503 strcpyW (lpBand->lpText, lprbbi->lpText);
2507 REBAR_ValidateBand (hwnd, infoPtr, lpBand);
2509 REBAR_DumpBand (hwnd);
2511 REBAR_Layout (hwnd, NULL, TRUE, FALSE);
2512 REBAR_ForceResize (hwnd);
2513 REBAR_MoveChildWindows (hwnd);
2520 REBAR_MaximizeBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
2522 /* REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */
2524 FIXME("(uBand = %u fIdeal = %s) stub\n",
2525 (UINT)wParam, lParam ? "TRUE" : "FALSE");
2533 REBAR_MinimizeBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
2535 /* REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */
2537 FIXME("(uBand = %u) stub\n", (UINT)wParam);
2545 REBAR_MoveBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
2547 /* REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */
2549 FIXME("(iFrom = %u iTof = %u) stub\n",
2550 (UINT)wParam, (UINT)lParam);
2558 REBAR_SetBandInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2560 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2561 LPREBARBANDINFOA lprbbi = (LPREBARBANDINFOA)lParam;
2566 if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEA)
2568 if ((UINT)wParam >= infoPtr->uNumBands)
2571 TRACE("index %u\n", (UINT)wParam);
2572 REBAR_DumpBandInfo (lprbbi);
2574 /* set band information */
2575 lpBand = &infoPtr->bands[(UINT)wParam];
2577 REBAR_CommonSetupBand (hwnd, lprbbi, lpBand);
2578 if (lprbbi->fMask & RBBIM_TEXT) {
2579 if (lpBand->lpText) {
2580 COMCTL32_Free (lpBand->lpText);
2581 lpBand->lpText = NULL;
2583 if (lprbbi->lpText) {
2584 INT len = MultiByteToWideChar( CP_ACP, 0, lprbbi->lpText, -1, NULL, 0 );
2585 lpBand->lpText = (LPWSTR)COMCTL32_Alloc (len*sizeof(WCHAR));
2586 MultiByteToWideChar( CP_ACP, 0, lprbbi->lpText, -1, lpBand->lpText, len );
2590 REBAR_ValidateBand (hwnd, infoPtr, lpBand);
2592 REBAR_DumpBand (hwnd);
2594 if (lprbbi->fMask & (RBBIM_CHILDSIZE | RBBIM_SIZE)) {
2595 REBAR_Layout (hwnd, NULL, TRUE, FALSE);
2596 REBAR_ForceResize (hwnd);
2597 REBAR_MoveChildWindows (hwnd);
2605 REBAR_SetBandInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2607 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2608 LPREBARBANDINFOW lprbbi = (LPREBARBANDINFOW)lParam;
2613 if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEW)
2615 if ((UINT)wParam >= infoPtr->uNumBands)
2618 TRACE("index %u\n", (UINT)wParam);
2619 REBAR_DumpBandInfo ((LPREBARBANDINFOA)lprbbi);
2621 /* set band information */
2622 lpBand = &infoPtr->bands[(UINT)wParam];
2624 REBAR_CommonSetupBand (hwnd, (LPREBARBANDINFOA)lprbbi, lpBand);
2625 if (lprbbi->fMask & RBBIM_TEXT) {
2626 if (lpBand->lpText) {
2627 COMCTL32_Free (lpBand->lpText);
2628 lpBand->lpText = NULL;
2630 if (lprbbi->lpText) {
2631 INT len = lstrlenW (lprbbi->lpText);
2632 lpBand->lpText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
2633 strcpyW (lpBand->lpText, lprbbi->lpText);
2637 REBAR_ValidateBand (hwnd, infoPtr, lpBand);
2639 REBAR_DumpBand (hwnd);
2641 if (lprbbi->fMask & (RBBIM_CHILDSIZE | RBBIM_SIZE)) {
2642 REBAR_Layout (hwnd, NULL, TRUE, FALSE);
2643 REBAR_ForceResize (hwnd);
2644 REBAR_MoveChildWindows (hwnd);
2652 REBAR_SetBarInfo (HWND hwnd, WPARAM wParam, LPARAM lParam)
2654 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2655 LPREBARINFO lpInfo = (LPREBARINFO)lParam;
2662 if (lpInfo->cbSize < sizeof (REBARINFO))
2665 TRACE("setting bar info!\n");
2667 if (lpInfo->fMask & RBIM_IMAGELIST) {
2668 infoPtr->himl = lpInfo->himl;
2669 if (infoPtr->himl) {
2671 ImageList_GetIconSize (infoPtr->himl, &cx, &cy);
2672 infoPtr->imageSize.cx = cx;
2673 infoPtr->imageSize.cy = cy;
2676 infoPtr->imageSize.cx = 0;
2677 infoPtr->imageSize.cy = 0;
2679 TRACE("new image cx=%ld, cy=%ld\n", infoPtr->imageSize.cx,
2680 infoPtr->imageSize.cy);
2683 /* revalidate all bands to reset flags for images in headers of bands */
2684 for (i=0; i<infoPtr->uNumBands; i++) {
2685 lpBand = &infoPtr->bands[i];
2686 REBAR_ValidateBand (hwnd, infoPtr, lpBand);
2694 REBAR_SetBkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
2696 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2699 clrTemp = infoPtr->clrBk;
2700 infoPtr->clrBk = (COLORREF)lParam;
2702 TRACE("background color 0x%06lx!\n", infoPtr->clrBk);
2708 /* << REBAR_SetColorScheme >> */
2709 /* << REBAR_SetPalette >> */
2713 REBAR_SetParent (HWND hwnd, WPARAM wParam, LPARAM lParam)
2715 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2716 HWND hwndTemp = infoPtr->hwndNotify;
2718 infoPtr->hwndNotify = (HWND)wParam;
2720 return (LRESULT)hwndTemp;
2725 REBAR_SetTextColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
2727 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2730 clrTemp = infoPtr->clrText;
2731 infoPtr->clrText = (COLORREF)lParam;
2733 TRACE("text color 0x%06lx!\n", infoPtr->clrText);
2739 /* << REBAR_SetTooltips >> */
2742 inline static LRESULT
2743 REBAR_SetUnicodeFormat (HWND hwnd, WPARAM wParam)
2745 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2746 BOOL bTemp = infoPtr->bUnicode;
2747 infoPtr->bUnicode = (BOOL)wParam;
2753 REBAR_SetVersion (HWND hwnd, INT iVersion)
2755 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2756 INT iOldVersion = infoPtr->iVersion;
2758 if (iVersion > COMCTL32_VERSION)
2761 infoPtr->iVersion = iVersion;
2763 TRACE("new version %d\n", iVersion);
2770 REBAR_ShowBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
2772 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2775 if (((INT)wParam < 0) || ((INT)wParam > infoPtr->uNumBands))
2778 lpBand = &infoPtr->bands[(INT)wParam];
2781 TRACE("show band %d\n", (INT)wParam);
2782 lpBand->fStyle = lpBand->fStyle & ~RBBS_HIDDEN;
2783 if (IsWindow (lpBand->hwndChild))
2784 ShowWindow (lpBand->hwndChild, SW_SHOW);
2787 TRACE("hide band %d\n", (INT)wParam);
2788 lpBand->fStyle = lpBand->fStyle | RBBS_HIDDEN;
2789 if (IsWindow (lpBand->hwndChild))
2790 ShowWindow (lpBand->hwndChild, SW_HIDE);
2793 REBAR_Layout (hwnd, NULL, TRUE, FALSE);
2794 REBAR_ForceResize (hwnd);
2795 REBAR_MoveChildWindows (hwnd);
2802 REBAR_SizeToRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
2804 LPRECT lpRect = (LPRECT)lParam;
2810 TRACE("[%d %d %d %d]\n",
2811 lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
2813 /* what is going on???? */
2814 GetWindowRect(hwnd, &t1);
2815 TRACE("window rect [%d %d %d %d]\n",
2816 t1.left, t1.top, t1.right, t1.bottom);
2817 GetClientRect(hwnd, &t1);
2818 TRACE("client rect [%d %d %d %d]\n",
2819 t1.left, t1.top, t1.right, t1.bottom);
2821 REBAR_Layout (hwnd, lpRect, TRUE, FALSE);
2822 REBAR_ForceResize (hwnd);
2823 REBAR_MoveChildWindows (hwnd);
2830 REBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
2832 REBAR_INFO *infoPtr;
2834 /* allocate memory for info structure */
2835 infoPtr = (REBAR_INFO *)COMCTL32_Alloc (sizeof(REBAR_INFO));
2836 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
2838 /* initialize info structure - initial values are 0 */
2839 infoPtr->clrBk = CLR_NONE;
2840 infoPtr->clrText = GetSysColor (COLOR_BTNTEXT);
2841 infoPtr->ihitBand = -1;
2843 infoPtr->hcurArrow = LoadCursorA (0, IDC_ARROWA);
2844 infoPtr->hcurHorz = LoadCursorA (0, IDC_SIZEWEA);
2845 infoPtr->hcurVert = LoadCursorA (0, IDC_SIZENSA);
2846 infoPtr->hcurDrag = LoadCursorA (0, IDC_SIZEA);
2848 infoPtr->bUnicode = IsWindowUnicode (hwnd);
2850 if (GetWindowLongA (hwnd, GWL_STYLE) & RBS_AUTOSIZE)
2851 FIXME("style RBS_AUTOSIZE set!\n");
2854 SendMessageA (hwnd, WM_NOTIFYFORMAT, (WPARAM)hwnd, NF_QUERY);
2857 TRACE("created!\n");
2863 REBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
2865 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2870 /* free rebar bands */
2871 if ((infoPtr->uNumBands > 0) && infoPtr->bands) {
2872 /* clean up each band */
2873 for (i = 0; i < infoPtr->uNumBands; i++) {
2874 lpBand = &infoPtr->bands[i];
2876 /* delete text strings */
2877 if (lpBand->lpText) {
2878 COMCTL32_Free (lpBand->lpText);
2879 lpBand->lpText = NULL;
2881 /* destroy child window */
2882 DestroyWindow (lpBand->hwndChild);
2885 /* free band array */
2886 COMCTL32_Free (infoPtr->bands);
2887 infoPtr->bands = NULL;
2890 DeleteObject (infoPtr->hcurArrow);
2891 DeleteObject (infoPtr->hcurHorz);
2892 DeleteObject (infoPtr->hcurVert);
2893 DeleteObject (infoPtr->hcurDrag);
2895 /* free rebar info data */
2896 COMCTL32_Free (infoPtr);
2897 SetWindowLongA (hwnd, 0, 0);
2898 TRACE("destroyed!\n");
2904 REBAR_EraseBkGnd (HWND hwnd, WPARAM wParam, LPARAM lParam)
2908 if (GetClipBox ( (HDC)wParam, &cliprect))
2909 return REBAR_InternalEraseBkGnd (hwnd, wParam, lParam, &cliprect);
2915 REBAR_GetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
2917 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2919 return (LRESULT)infoPtr->hFont;
2924 REBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
2926 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2928 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
2930 /* If InternalHitTest did not find a hit on the Gripper, */
2931 /* then ignore the button click. */
2932 if (infoPtr->ihitBand == -1) return 0;
2936 /* save off the LOWORD and HIWORD of lParam as initial x,y */
2937 lpBand = &infoPtr->bands[infoPtr->ihitBand];
2938 infoPtr->dragStart = MAKEPOINTS(lParam);
2939 infoPtr->dragNow = infoPtr->dragStart;
2940 if (dwStyle & CCS_VERT)
2941 infoPtr->ihitoffset = infoPtr->dragStart.y - (lpBand->rcBand.top+REBAR_PRE_GRIPPER);
2943 infoPtr->ihitoffset = infoPtr->dragStart.x - (lpBand->rcBand.left+REBAR_PRE_GRIPPER);
2950 REBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
2952 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2956 /* If InternalHitTest did not find a hit on the Gripper, */
2957 /* then ignore the button click. */
2958 if (infoPtr->ihitBand == -1) return 0;
2960 infoPtr->dragStart.x = 0;
2961 infoPtr->dragStart.y = 0;
2962 infoPtr->dragNow = infoPtr->dragStart;
2963 infoPtr->ihitBand = -1;
2967 if (infoPtr->fStatus & BEGIN_DRAG_ISSUED) {
2968 REBAR_Notify(hwnd, (NMHDR *) &layout, infoPtr, RBN_LAYOUTCHANGED);
2969 REBAR_Notify_NMREBAR (hwnd, infoPtr, -1, RBN_ENDDRAG);
2970 infoPtr->fStatus &= ~BEGIN_DRAG_ISSUED;
2973 GetClientRect(hwnd, &rect);
2974 InvalidateRect(hwnd, NULL, TRUE);
2981 REBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
2983 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2984 REBAR_BAND *band1, *band2;
2986 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
2988 /* Validate entry as hit on Gripper has occured */
2989 if (GetCapture() != hwnd) return 0;
2990 if (infoPtr->ihitBand == -1) return 0;
2992 ptsmove = MAKEPOINTS(lParam);
2994 /* if mouse did not move much, exit */
2995 if ((abs(ptsmove.x - infoPtr->dragNow.x) <= mindragx) &&
2996 (abs(ptsmove.y - infoPtr->dragNow.y) <= mindragy)) return 0;
2998 band1 = &infoPtr->bands[infoPtr->ihitBand-1];
2999 band2 = &infoPtr->bands[infoPtr->ihitBand];
3001 /* Test for valid drag case - must not be first band in row */
3002 if (dwStyle & CCS_VERT) {
3003 if ((ptsmove.x < band2->rcBand.left) ||
3004 (ptsmove.x > band2->rcBand.right) ||
3005 ((infoPtr->ihitBand > 0) && (band1->iRow != band2->iRow))) {
3006 FIXME("Cannot drag to other rows yet!!\n");
3009 REBAR_HandleLRDrag (hwnd, infoPtr, &ptsmove, dwStyle);
3013 if ((ptsmove.y < band2->rcBand.top) ||
3014 (ptsmove.y > band2->rcBand.bottom) ||
3015 ((infoPtr->ihitBand > 0) && (band1->iRow != band2->iRow))) {
3016 FIXME("Cannot drag to other rows yet!!\n");
3019 REBAR_HandleLRDrag (hwnd, infoPtr, &ptsmove, dwStyle);
3026 inline static LRESULT
3027 REBAR_NCCalcSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
3029 if (GetWindowLongA (hwnd, GWL_STYLE) & WS_BORDER) {
3030 ((LPRECT)lParam)->left += GetSystemMetrics(SM_CXEDGE);
3031 ((LPRECT)lParam)->top += GetSystemMetrics(SM_CYEDGE);
3032 ((LPRECT)lParam)->right -= GetSystemMetrics(SM_CXEDGE);
3033 ((LPRECT)lParam)->bottom -= GetSystemMetrics(SM_CYEDGE);
3041 REBAR_NCPaint (HWND hwnd, WPARAM wParam, LPARAM lParam)
3043 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3047 if (dwStyle & WS_MINIMIZE)
3048 return 0; /* Nothing to do */
3050 DefWindowProcA (hwnd, WM_NCPAINT, wParam, lParam);
3052 if (!(hdc = GetDCEx( hwnd, 0, DCX_USESTYLE | DCX_WINDOW )))
3055 if (dwStyle & WS_BORDER) {
3056 GetWindowRect (hwnd, &rcWindow);
3057 OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
3058 DrawEdge (hdc, &rcWindow, EDGE_ETCHED, BF_RECT);
3061 ReleaseDC( hwnd, hdc );
3068 REBAR_Paint (HWND hwnd, WPARAM wParam, LPARAM lParam)
3073 hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
3075 TRACE("painting (%d,%d)-(%d,%d)\n",
3076 ps.rcPaint.left, ps.rcPaint.top,
3077 ps.rcPaint.right, ps.rcPaint.bottom);
3080 /* Erase area of paint if requested */
3081 REBAR_InternalEraseBkGnd (hwnd, wParam, lParam, &ps.rcPaint);
3084 REBAR_Refresh (hwnd, hdc);
3086 EndPaint (hwnd, &ps);
3092 REBAR_SetCursor (HWND hwnd, WPARAM wParam, LPARAM lParam)
3094 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
3095 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3099 TRACE("code=0x%X id=0x%X\n", LOWORD(lParam), HIWORD(lParam));
3102 ScreenToClient (hwnd, &pt);
3104 REBAR_InternalHitTest (hwnd, &pt, &flags, NULL);
3106 if (flags == RBHT_GRABBER) {
3107 if ((dwStyle & CCS_VERT) &&
3108 !(dwStyle & RBS_VERTICALGRIPPER))
3109 SetCursor (infoPtr->hcurVert);
3111 SetCursor (infoPtr->hcurHorz);
3113 else if (flags != RBHT_CLIENT)
3114 SetCursor (infoPtr->hcurArrow);
3121 REBAR_SetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
3123 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
3128 infoPtr->hFont = (HFONT)wParam;
3130 /* revalidate all bands to change sizes of text in headers of bands */
3131 for (i=0; i<infoPtr->uNumBands; i++) {
3132 lpBand = &infoPtr->bands[i];
3133 REBAR_ValidateBand (hwnd, infoPtr, lpBand);
3138 GetClientRect (hwnd, &rcClient);
3139 REBAR_Layout (hwnd, &rcClient, FALSE, TRUE);
3140 REBAR_ForceResize (hwnd);
3141 REBAR_MoveChildWindows (hwnd);
3148 REBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
3150 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
3153 /* auto resize deadlock check */
3154 if (infoPtr->fStatus & AUTO_RESIZE) {
3155 infoPtr->fStatus &= ~AUTO_RESIZE;
3156 TRACE("AUTO_RESIZE was set, reset, fStatus=%08x\n",
3161 GetClientRect (hwnd, &rcClient);
3162 if ((lParam == 0) && (rcClient.right == 0) && (rcClient.bottom == 0)) {
3163 /* native control seems to do this */
3164 GetClientRect (GetParent(hwnd), &rcClient);
3165 TRACE("sizing rebar, message and client zero, parent client (%d,%d)\n",
3166 rcClient.right, rcClient.bottom);
3169 TRACE("sizing rebar from (%ld,%ld) to (%d,%d), client (%d,%d)\n",
3170 infoPtr->calcSize.cx, infoPtr->calcSize.cy,
3171 LOWORD(lParam), HIWORD(lParam),
3172 rcClient.right, rcClient.bottom);
3175 REBAR_Layout (hwnd, &rcClient, FALSE, TRUE);
3176 REBAR_ForceResize (hwnd);
3177 infoPtr->fStatus &= ~AUTO_RESIZE;
3178 REBAR_MoveChildWindows (hwnd);
3184 static LRESULT WINAPI
3185 REBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
3187 TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n", hwnd, uMsg, wParam, lParam);
3188 if (!REBAR_GetInfoPtr (hwnd) && (uMsg != WM_CREATE))
3189 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
3192 /* case RB_BEGINDRAG: */
3195 return REBAR_DeleteBand (hwnd, wParam, lParam);
3197 /* case RB_DRAGMOVE: */
3198 /* case RB_ENDDRAG: */
3200 case RB_GETBANDBORDERS:
3201 return REBAR_GetBandBorders (hwnd, wParam, lParam);
3203 case RB_GETBANDCOUNT:
3204 return REBAR_GetBandCount (hwnd);
3206 case RB_GETBANDINFO: /* obsoleted after IE3, but we have to
3207 support it anyway. */
3208 case RB_GETBANDINFOA:
3209 return REBAR_GetBandInfoA (hwnd, wParam, lParam);
3211 case RB_GETBANDINFOW:
3212 return REBAR_GetBandInfoW (hwnd, wParam, lParam);
3214 case RB_GETBARHEIGHT:
3215 return REBAR_GetBarHeight (hwnd, wParam, lParam);
3218 return REBAR_GetBarInfo (hwnd, wParam, lParam);
3221 return REBAR_GetBkColor (hwnd);
3223 /* case RB_GETCOLORSCHEME: */
3224 /* case RB_GETDROPTARGET: */
3227 return REBAR_GetPalette (hwnd, wParam, lParam);
3230 return REBAR_GetRect (hwnd, wParam, lParam);
3232 case RB_GETROWCOUNT:
3233 return REBAR_GetRowCount (hwnd);
3235 case RB_GETROWHEIGHT:
3236 return REBAR_GetRowHeight (hwnd, wParam, lParam);
3238 case RB_GETTEXTCOLOR:
3239 return REBAR_GetTextColor (hwnd);
3241 case RB_GETTOOLTIPS:
3242 return REBAR_GetToolTips (hwnd);
3244 case RB_GETUNICODEFORMAT:
3245 return REBAR_GetUnicodeFormat (hwnd);
3247 case CCM_GETVERSION:
3248 return REBAR_GetVersion (hwnd);
3251 return REBAR_HitTest (hwnd, wParam, lParam);
3254 return REBAR_IdToIndex (hwnd, wParam, lParam);
3256 case RB_INSERTBANDA:
3257 return REBAR_InsertBandA (hwnd, wParam, lParam);
3259 case RB_INSERTBANDW:
3260 return REBAR_InsertBandW (hwnd, wParam, lParam);
3262 case RB_MAXIMIZEBAND:
3263 return REBAR_MaximizeBand (hwnd, wParam, lParam);
3265 case RB_MINIMIZEBAND:
3266 return REBAR_MinimizeBand (hwnd, wParam, lParam);
3269 return REBAR_MoveBand (hwnd, wParam, lParam);
3271 case RB_SETBANDINFOA:
3272 return REBAR_SetBandInfoA (hwnd, wParam, lParam);
3274 case RB_SETBANDINFOW:
3275 return REBAR_SetBandInfoW (hwnd, wParam, lParam);
3278 return REBAR_SetBarInfo (hwnd, wParam, lParam);
3281 return REBAR_SetBkColor (hwnd, wParam, lParam);
3283 /* case RB_SETCOLORSCHEME: */
3284 /* case RB_SETPALETTE: */
3285 /* return REBAR_GetPalette (hwnd, wParam, lParam); */
3288 return REBAR_SetParent (hwnd, wParam, lParam);
3290 case RB_SETTEXTCOLOR:
3291 return REBAR_SetTextColor (hwnd, wParam, lParam);
3293 /* case RB_SETTOOLTIPS: */
3295 case RB_SETUNICODEFORMAT:
3296 return REBAR_SetUnicodeFormat (hwnd, wParam);
3298 case CCM_SETVERSION:
3299 return REBAR_SetVersion (hwnd, (INT)wParam);
3302 return REBAR_ShowBand (hwnd, wParam, lParam);
3305 return REBAR_SizeToRect (hwnd, wParam, lParam);
3308 /* Messages passed to parent */
3312 return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
3315 /* case WM_CHARTOITEM: supported according to ControlSpy */
3318 return REBAR_Create (hwnd, wParam, lParam);
3321 return REBAR_Destroy (hwnd, wParam, lParam);
3324 return REBAR_EraseBkGnd (hwnd, wParam, lParam);
3327 return REBAR_GetFont (hwnd, wParam, lParam);
3329 /* case WM_LBUTTONDBLCLK: supported according to ControlSpy */
3331 case WM_LBUTTONDOWN:
3332 return REBAR_LButtonDown (hwnd, wParam, lParam);
3335 return REBAR_LButtonUp (hwnd, wParam, lParam);
3337 /* case WM_MEASUREITEM: supported according to ControlSpy */
3340 return REBAR_MouseMove (hwnd, wParam, lParam);
3343 return REBAR_NCCalcSize (hwnd, wParam, lParam);
3345 /* case WM_NCCREATE: supported according to ControlSpy */
3346 /* case WM_NCHITTEST: supported according to ControlSpy */
3349 return REBAR_NCPaint (hwnd, wParam, lParam);
3351 /* case WM_NOTIFYFORMAT: supported according to ControlSpy */
3354 return REBAR_Paint (hwnd, wParam, lParam);
3356 /* case WM_PALETTECHANGED: supported according to ControlSpy */
3357 /* case WM_PRINTCLIENT: supported according to ControlSpy */
3358 /* case WM_QUERYNEWPALETTE:supported according to ControlSpy */
3359 /* case WM_RBUTTONDOWN: supported according to ControlSpy */
3360 /* case WM_RBUTTONUP: supported according to ControlSpy */
3363 return REBAR_SetCursor (hwnd, wParam, lParam);
3366 return REBAR_SetFont (hwnd, wParam, lParam);
3368 /* case WM_SETREDRAW: supported according to ControlSpy */
3371 return REBAR_Size (hwnd, wParam, lParam);
3373 /* case WM_STYLECHANGED: supported according to ControlSpy */
3374 /* case WM_SYSCOLORCHANGE: supported according to ControlSpy */
3375 /* case WM_VKEYTOITEM: supported according to ControlSpy */
3376 /* case WM_WININICHANGE: */
3379 if (uMsg >= WM_USER)
3380 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
3381 uMsg, wParam, lParam);
3382 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
3389 REBAR_Register (void)
3393 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
3394 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
3395 wndClass.lpfnWndProc = (WNDPROC)REBAR_WindowProc;
3396 wndClass.cbClsExtra = 0;
3397 wndClass.cbWndExtra = sizeof(REBAR_INFO *);
3398 wndClass.hCursor = 0;
3399 wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
3400 wndClass.lpszClassName = REBARCLASSNAMEA;
3402 RegisterClassA (&wndClass);
3404 mindragx = GetSystemMetrics (SM_CXDRAG);
3405 mindragy = GetSystemMetrics (SM_CYDRAG);
3411 REBAR_Unregister (void)
3413 UnregisterClassA (REBARCLASSNAMEA, (HINSTANCE)NULL);