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)
48 * 12. Fixup RBN_CHILDSIZE notify. The rcBand rectangle should start
49 * after the header. (6d)
50 * 13. Flags for DeferWindowPos seem to always be SWP_NOZORDER in the
52 * 14. Make handling of ComboBox and ComboBoxEx the same in
53 * _MoveChildWindow. (6d)
54 * 15. Changes in phase 2 of _Layout for WinRAR example. (6e)
55 * 16. Do notify change size of children for WM_SIZE message. (6e)
56 * 17. Re-validate first band when second is added (for gripper add). (6e)
61 * 1. default row height should be the max height of all visible bands
62 * 2. Following still not handled: RBBS_FIXEDBMP, RBBS_CHILDEDGE,
64 * 3. RBS_VARHEIGHT is assumed to always be on.
65 * 4. RBBS_HIDDEN (and the CCS_VERT + RBBS_NOVERT case) is not really
66 * supported by the following functions:
67 * _Layout (phase 2), _InternalEraseBkgnd, _InternalHitTest,
69 * 5. _HandleLRDrag does not properly position ComboBox or ComboBoxEx
70 * children. (See code in _MoveChildWindow.)
79 #include "wine/unicode.h"
81 #include "debugtools.h"
83 DEFAULT_DEBUG_CHANNEL(rebar);
105 UINT lcx; /* minimum cx for band */
106 UINT hcx; /* maximum cx for band */
107 UINT lcy; /* minimum cy for band */
108 UINT hcy; /* maximum cy for band */
110 SIZE offChild; /* x,y offset if child is not FIXEDSIZE */
112 INT iRow; /* row this band assigned to */
113 UINT fStatus; /* status flags, reset only by _Validate */
114 UINT fDraw; /* drawing flags, reset only by _Layout */
115 RECT rcBand; /* calculated band rectangle */
116 RECT rcGripper; /* calculated gripper rectangle */
117 RECT rcCapImage; /* calculated caption image rectangle */
118 RECT rcCapText; /* calculated caption text rectangle */
119 RECT rcChild; /* calculated child rectangle */
126 #define HAS_GRIPPER 0x00000001
127 #define HAS_IMAGE 0x00000002
128 #define HAS_TEXT 0x00000004
131 #define DRAW_GRIPPER 0x00000001
132 #define DRAW_IMAGE 0x00000002
133 #define DRAW_TEXT 0x00000004
134 #define DRAW_RIGHTSEP 0x00000010
135 #define DRAW_BOTTOMSEP 0x00000020
136 #define DRAW_SEPBOTH (DRAW_RIGHTSEP | DRAW_BOTTOMSEP)
137 #define NTF_INVALIDATE 0x01000000
138 #define NTF_CHILDSIZE 0x02000000
143 COLORREF clrBk; /* background color */
144 COLORREF clrText; /* text color */
145 HIMAGELIST himl; /* handle to imagelist */
146 UINT uNumBands; /* number of bands in the rebar */
147 UINT uNumRows; /* number of rows of bands */
148 HWND hwndToolTip; /* handle to the tool tip control */
149 HWND hwndNotify; /* notification window (parent) */
150 HFONT hFont; /* handle to the rebar's font */
151 SIZE imageSize; /* image size (image list) */
153 SIZE calcSize; /* calculated rebar size */
154 SIZE oldSize; /* previous calculated rebar size */
155 BOOL bUnicode; /* Unicode flag */
156 UINT fStatus; /* Status flags (see below) */
157 HCURSOR hcurArrow; /* handle to the arrow cursor */
158 HCURSOR hcurHorz; /* handle to the EW cursor */
159 HCURSOR hcurVert; /* handle to the NS cursor */
160 HCURSOR hcurDrag; /* handle to the drag cursor */
161 INT iVersion; /* version number */
162 POINTS dragStart; /* x,y of button down */
163 POINTS dragNow; /* x,y of this MouseMove */
164 INT ihitBand; /* band number of band whose gripper was grabbed */
165 INT ihitoffset; /* offset of hotspot from gripper.left */
167 REBAR_BAND *bands; /* pointer to the array of rebar bands */
171 #define BEGIN_DRAG_ISSUED 1
172 #define AUTO_RESIZE 2
173 #define RESIZE_ANYHOW 4
174 #define NTF_HGHTCHG 8
176 /* ---- REBAR layout constants. Mostly determined by ---- */
177 /* ---- experiment on WIN 98. ---- */
179 /* Width (or height) of separators between bands (either horz. or */
180 /* vert.). True only if RBS_BANDBORDERS is set */
181 #define SEP_WIDTH_SIZE 2
182 #define SEP_WIDTH ((dwStyle & RBS_BANDBORDERS) ? SEP_WIDTH_SIZE : 0)
184 /* Blank (background color) space between Gripper (if present) */
185 /* and next item (image, text, or window). Always present */
186 #define REBAR_ALWAYS_SPACE 4
188 /* Blank (background color) space after Image (if present). */
189 #define REBAR_POST_IMAGE 2
191 /* Blank (background color) space after Text (if present). */
192 #define REBAR_POST_TEXT 4
194 /* Height of vertical gripper in a CCS_VERT rebar. */
195 #define GRIPPER_HEIGHT 16
197 /* Blank (background color) space before Gripper (if present). */
198 #define REBAR_PRE_GRIPPER 2
200 /* Width (of normal vertical gripper) or height (of horz. gripper) */
202 #define GRIPPER_WIDTH 3
204 /* This is the increment that is used over the band height */
205 /* Determined by experiment. */
208 /* ---- End of REBAR layout constants. ---- */
211 /* The following 4 defines return the proper rcBand element */
212 /* depending on whether CCS_VERT was set. */
213 #define rcBlt(b) ((dwStyle & CCS_VERT) ? b->rcBand.top : b->rcBand.left)
214 #define rcBrb(b) ((dwStyle & CCS_VERT) ? b->rcBand.bottom : b->rcBand.right)
215 #define ircBlt(b) ((dwStyle & CCS_VERT) ? b->rcBand.left : b->rcBand.top)
216 #define ircBrb(b) ((dwStyle & CCS_VERT) ? b->rcBand.right : b->rcBand.bottom)
218 /* The following define determines if a given band is hidden */
219 #define HIDDENBAND(a) (((a)->fStyle & RBBS_HIDDEN) || \
220 ((dwStyle & CCS_VERT) && \
221 ((a)->fStyle & RBBS_NOVERT)))
224 #define REBAR_GetInfoPtr(wndPtr) ((REBAR_INFO *)GetWindowLongA (hwnd, 0))
227 /* "constant values" retrieved when DLL was initialized */
228 /* FIXME we do this when the classes are registered. */
229 static UINT mindragx = 0;
230 static UINT mindragy = 0;
234 REBAR_DumpBandInfo( LPREBARBANDINFOA pB)
236 TRACE("band info: ID=%u, size=%u, style=0x%08x, mask=0x%08x, child=%04x\n",
237 pB->wID, pB->cbSize, pB->fStyle, pB->fMask, pB->hwndChild);
238 TRACE("band info: cx=%u, xMin=%u, yMin=%u, yChild=%u, yMax=%u, yIntgl=%u\n",
239 pB->cx, pB->cxMinChild,
240 pB->cyMinChild, pB->cyChild, pB->cyMaxChild, pB->cyIntegral);
241 TRACE("band info: xIdeal=%u, xHeader=%u, lParam=0x%08lx, clrF=0x%06lx, clrB=0x%06lx\n",
242 pB->cxIdeal, pB->cxHeader, pB->lParam, pB->clrFore, pB->clrBack);
246 REBAR_DumpBand (HWND hwnd)
248 REBAR_INFO *iP = REBAR_GetInfoPtr (hwnd);
252 if( TRACE_ON(rebar) ) {
254 TRACE("hwnd=%04x: color=%08lx/%08lx, bands=%u, rows=%u, cSize=%ld,%ld\n",
255 hwnd, iP->clrText, iP->clrBk, iP->uNumBands, iP->uNumRows,
256 iP->calcSize.cx, iP->calcSize.cy);
257 TRACE("hwnd=%04x: flags=%08x, dragStart=%d,%d, dragNow=%d,%d, ihitBand=%d\n",
258 hwnd, iP->fStatus, iP->dragStart.x, iP->dragStart.y,
259 iP->dragNow.x, iP->dragNow.y,
261 for (i = 0; i < iP->uNumBands; i++) {
263 TRACE("band # %u: ID=%u, mask=0x%08x, style=0x%08x, child=%04x, row=%u\n",
264 i, pB->wID, pB->fMask, pB->fStyle, pB->hwndChild, pB->iRow);
265 TRACE("band # %u: xMin=%u, yMin=%u, cx=%u, yChild=%u, yMax=%u, yIntgl=%u, uMinH=%u,\n",
266 i, pB->cxMinChild, pB->cyMinChild, pB->cx,
267 pB->cyChild, pB->cyMaxChild, pB->cyIntegral, pB->uMinHeight);
268 TRACE("band # %u: header=%u, lcx=%u, hcx=%u, lcy=%u, hcy=%u, offChild=%ld,%ld\n",
269 i, pB->cxHeader, pB->lcx, pB->hcx, pB->lcy, pB->hcy, pB->offChild.cx, pB->offChild.cy);
270 TRACE("band # %u: fStatus=%08x, fDraw=%08x, Band=(%d,%d)-(%d,%d), Grip=(%d,%d)-(%d,%d)\n",
271 i, pB->fStatus, pB->fDraw,
272 pB->rcBand.left, pB->rcBand.top, pB->rcBand.right, pB->rcBand.bottom,
273 pB->rcGripper.left, pB->rcGripper.top, pB->rcGripper.right, pB->rcGripper.bottom);
274 TRACE("band # %u: Img=(%d,%d)-(%d,%d), Txt=(%d,%d)-(%d,%d), Child=(%d,%d)-(%d,%d)\n",
276 pB->rcCapImage.left, pB->rcCapImage.top, pB->rcCapImage.right, pB->rcCapImage.bottom,
277 pB->rcCapText.left, pB->rcCapText.top, pB->rcCapText.right, pB->rcCapText.bottom,
278 pB->rcChild.left, pB->rcChild.top, pB->rcChild.right, pB->rcChild.bottom);
285 REBAR_Notify (HWND hwnd, NMHDR *nmhdr, REBAR_INFO *infoPtr, UINT code)
289 parent = infoPtr->hwndNotify;
291 parent = GetParent (hwnd);
292 owner = GetWindow (hwnd, GW_OWNER);
293 if (owner) parent = owner;
295 nmhdr->idFrom = GetDlgCtrlID (hwnd);
296 nmhdr->hwndFrom = hwnd;
299 return SendMessageA (parent, WM_NOTIFY, (WPARAM) nmhdr->idFrom,
304 REBAR_Notify_NMREBAR (HWND hwnd, REBAR_INFO *infoPtr, UINT uBand, UINT code)
306 NMREBAR notify_rebar;
309 notify_rebar.dwMask = 0;
311 lpBand = &infoPtr->bands[uBand];
312 if (lpBand->fMask & RBBIM_ID) {
313 notify_rebar.dwMask |= RBNM_ID;
314 notify_rebar.wID = lpBand->wID;
316 if (lpBand->fMask & RBBIM_LPARAM) {
317 notify_rebar.dwMask |= RBNM_LPARAM;
318 notify_rebar.lParam = lpBand->lParam;
320 if (lpBand->fMask & RBBIM_STYLE) {
321 notify_rebar.dwMask |= RBNM_STYLE;
322 notify_rebar.fStyle = lpBand->fStyle;
325 notify_rebar.uBand = uBand;
326 return REBAR_Notify (hwnd, (NMHDR *)¬ify_rebar, infoPtr, code);
330 REBAR_DrawBand (HDC hdc, REBAR_INFO *infoPtr, REBAR_BAND *lpBand, DWORD dwStyle)
333 /* draw separators on both the bottom and right */
334 if ((lpBand->fDraw & DRAW_SEPBOTH) == DRAW_SEPBOTH) {
339 lpBand->rcBand.right + SEP_WIDTH_SIZE,
340 lpBand->rcBand.bottom + SEP_WIDTH_SIZE);
341 DrawEdge (hdc, &rcSep, EDGE_ETCHED, BF_BOTTOMRIGHT);
342 TRACE("drawing band separator both (%d,%d)-(%d,%d)\n",
343 rcSep.left, rcSep.top, rcSep.right, rcSep.bottom);
346 /* draw band separator between bands in a row */
347 if ((lpBand->fDraw & DRAW_SEPBOTH) == DRAW_RIGHTSEP) {
349 if (dwStyle & CCS_VERT) {
352 lpBand->rcBand.bottom,
353 lpBand->rcBand.right,
354 lpBand->rcBand.bottom + SEP_WIDTH_SIZE);
355 DrawEdge (hdc, &rcSep, EDGE_ETCHED, BF_BOTTOM);
359 lpBand->rcBand.right,
361 lpBand->rcBand.right + SEP_WIDTH_SIZE,
362 lpBand->rcBand.bottom);
363 DrawEdge (hdc, &rcSep, EDGE_ETCHED, BF_RIGHT);
365 TRACE("drawing band separator right (%d,%d)-(%d,%d)\n",
366 rcSep.left, rcSep.top, rcSep.right, rcSep.bottom);
369 /* draw band separator between rows */
370 if ((lpBand->fDraw & DRAW_SEPBOTH) == DRAW_BOTTOMSEP) {
372 if (dwStyle & CCS_VERT) {
374 lpBand->rcBand.right,
376 lpBand->rcBand.right + SEP_WIDTH_SIZE,
377 lpBand->rcBand.bottom);
378 DrawEdge (hdc, &rcRowSep, EDGE_ETCHED, BF_RIGHT);
383 lpBand->rcBand.bottom,
384 lpBand->rcBand.right,
385 lpBand->rcBand.bottom + SEP_WIDTH_SIZE);
386 DrawEdge (hdc, &rcRowSep, EDGE_ETCHED, BF_BOTTOM);
388 TRACE ("drawing band separator bottom (%d,%d)-(%d,%d)\n",
389 rcRowSep.left, rcRowSep.top,
390 rcRowSep.right, rcRowSep.bottom);
394 if (lpBand->fDraw & DRAW_GRIPPER)
395 DrawEdge (hdc, &lpBand->rcGripper, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE);
397 /* draw caption image */
398 if (lpBand->fDraw & DRAW_IMAGE) {
402 pt.y = (lpBand->rcCapImage.bottom + lpBand->rcCapImage.top - infoPtr->imageSize.cy)/2;
403 pt.x = (lpBand->rcCapImage.right + lpBand->rcCapImage.left - infoPtr->imageSize.cx)/2;
405 ImageList_Draw (infoPtr->himl, lpBand->iImage, hdc,
410 /* draw caption text */
411 if (lpBand->fDraw & DRAW_TEXT) {
412 HFONT hOldFont = SelectObject (hdc, infoPtr->hFont);
413 INT oldBkMode = SetBkMode (hdc, TRANSPARENT);
414 COLORREF oldcolor = CLR_NONE;
415 if (lpBand->clrFore != CLR_NONE)
416 oldcolor = SetTextColor (hdc, lpBand->clrFore);
417 DrawTextW (hdc, lpBand->lpText, -1, &lpBand->rcCapText,
418 DT_CENTER | DT_VCENTER | DT_SINGLELINE);
419 if (oldBkMode != TRANSPARENT)
420 SetBkMode (hdc, oldBkMode);
421 if (lpBand->clrFore != CLR_NONE)
422 SetTextColor (hdc, oldcolor);
423 SelectObject (hdc, hOldFont);
429 REBAR_Refresh (HWND hwnd, HDC hdc)
431 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
434 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
436 oldrow = infoPtr->bands[0].iRow;
437 for (i = 0; i < infoPtr->uNumBands; i++) {
438 lpBand = &infoPtr->bands[i];
440 if ((lpBand->fStyle & RBBS_HIDDEN) ||
441 ((dwStyle & CCS_VERT) &&
442 (lpBand->fStyle & RBBS_NOVERT)))
445 /* now draw the band */
446 REBAR_DrawBand (hdc, infoPtr, lpBand, dwStyle);
452 REBAR_AdjustBands (REBAR_INFO *infoPtr, UINT rowstart, UINT rowend,
453 INT maxx, INT usedx, INT mcy, DWORD dwStyle)
454 /* Function: This routine distributes the extra space in a row */
455 /* by increasing bands from left to right to their "cx" width.*/
456 /* Uses "cxHeader"+"cxMinChild" if it is bigger than "cx". */
461 INT incr, current_width, lastx=0;
464 TRACE("start=%u, end=%u, max x=%d, used x=%d, max y=%d\n",
465 rowstart, rowend-1, maxx, usedx, mcy);
469 for (i = rowstart; i<rowend; i++) {
470 lpBand = &infoPtr->bands[i];
471 if (HIDDENBAND(lpBand)) continue;
474 oldband = lpBand->rcBand;
476 /* get the current width of the band */
477 if (dwStyle & CCS_VERT)
478 current_width = lpBand->rcBand.bottom - lpBand->rcBand.top;
480 current_width = lpBand->rcBand.right - lpBand->rcBand.left;
482 /* compute (in "j") the adjustment for this band */
483 /* FIXME ??? should this not use "cx" and "cxHeader" and "cxMinChild" */
484 if (!(lpBand->fStyle & RBBS_FIXEDSIZE)) {
485 if ((lpBand->fMask & RBBIM_SIZE) && (lpBand->cx > 0))
486 j = min(lpBand->cx - current_width, incr);
487 if ((lpBand->fMask & RBBIM_CHILDSIZE) &&
488 (lpBand->cxMinChild > 0) &&
489 (lpBand->fMask & RBBIM_CHILD) &&
490 (lpBand->hwndChild)) {
491 k = lpBand->cxHeader + lpBand->cxMinChild - current_width;
501 /* validate values */
503 ERR("failed, incr=%d, current_width=%d, j=%d, k=%d\n",
504 incr, current_width, j, k);
508 if (lastx + j + current_width > maxx) {
509 ERR("exceeded maximum, lastx=%d, j=%d, current_width=%d\n",
510 lastx, j, current_width);
511 j = maxx - lastx - current_width;
515 /* adjust the band rectangle for adding width */
516 /* and setting height of all bands in row. */
517 if (dwStyle & CCS_VERT) {
518 lpBand->rcBand.top = lastx;
519 lpBand->rcBand.bottom = lastx + j + current_width;
520 if ((lpBand->rcBand.top != oldband.top) ||
521 (lpBand->rcBand.bottom != oldband.bottom))
522 lpBand->fDraw |= NTF_INVALIDATE;
523 if (lpBand->rcBand.right != lpBand->rcBand.left + mcy) {
524 lpBand->rcBand.right = lpBand->rcBand.left + mcy;
525 lpBand->fDraw |= NTF_INVALIDATE;
529 lpBand->rcBand.left = lastx;
530 lpBand->rcBand.right = lastx + j + current_width;
531 if ((lpBand->rcBand.left != oldband.left) ||
532 (lpBand->rcBand.right != oldband.right))
533 lpBand->fDraw |= NTF_INVALIDATE;
534 if (lpBand->rcBand.bottom != lpBand->rcBand.top + mcy) {
535 lpBand->rcBand.bottom = lpBand->rcBand.top + mcy;
536 lpBand->fDraw |= NTF_INVALIDATE;
540 /* update to the next band start */
541 lastx += (j + current_width + SEP_WIDTH);
543 TRACE("band %d row=%d: changed to (%d,%d)-(%d,%d)\n",
545 lpBand->rcBand.left, lpBand->rcBand.top,
546 lpBand->rcBand.right, lpBand->rcBand.bottom);
549 TRACE("band %d row=%d: unchanged (%d,%d)-(%d,%d)\n",
551 lpBand->rcBand.left, lpBand->rcBand.top,
552 lpBand->rcBand.right, lpBand->rcBand.bottom);
556 /* if any remaining space then add to the rowstart band */
558 lpBand = &infoPtr->bands[rowstart];
559 lpBand->rcBand.right += incr;
560 TRACE("band %d row=%d: extended to (%d,%d)-(%d,%d)\n",
561 rowstart, lpBand->iRow,
562 lpBand->rcBand.left, lpBand->rcBand.top,
563 lpBand->rcBand.right, lpBand->rcBand.bottom);
564 for (i=rowstart+1; i<rowend; i++) {
565 lpBand = &infoPtr->bands[i];
566 if (HIDDENBAND(lpBand)) continue;
567 lpBand->rcBand.left += incr;
568 lpBand->rcBand.right += incr;
569 lpBand->fDraw |= NTF_INVALIDATE;
575 REBAR_CalcHorzBand (HWND hwnd, REBAR_INFO *infoPtr, UINT rstart, UINT rend, BOOL notify, DWORD dwStyle)
576 /* Function: this routine initializes all the rectangles in */
577 /* each band in a row to fit in the adjusted rcBand rect. */
578 /* *** Supports only Horizontal bars. *** */
585 /* MS seems to use GetDlgCtrlID() for above GetWindowLong call */
586 parenthwnd = GetParent (hwnd);
588 for(i=rstart; i<rend; i++){
589 lpBand = &infoPtr->bands[i];
590 if (HIDDENBAND(lpBand)) {
591 SetRect (&lpBand->rcChild,
592 lpBand->rcBand.right, lpBand->rcBand.top,
593 lpBand->rcBand.right, lpBand->rcBand.bottom);
597 oldChild = lpBand->rcChild;
599 /* set initial gripper rectangle */
600 SetRect (&lpBand->rcGripper, lpBand->rcBand.left, lpBand->rcBand.top,
601 lpBand->rcBand.left, lpBand->rcBand.bottom);
603 /* calculate gripper rectangle */
604 if ( lpBand->fStatus & HAS_GRIPPER) {
605 lpBand->fDraw |= DRAW_GRIPPER;
606 lpBand->rcGripper.left += REBAR_PRE_GRIPPER;
607 lpBand->rcGripper.right = lpBand->rcGripper.left + GRIPPER_WIDTH;
608 lpBand->rcGripper.top += 2;
609 lpBand->rcGripper.bottom -= 2;
611 SetRect (&lpBand->rcCapImage,
612 lpBand->rcGripper.right+REBAR_ALWAYS_SPACE, lpBand->rcBand.top,
613 lpBand->rcGripper.right+REBAR_ALWAYS_SPACE, lpBand->rcBand.bottom);
615 else { /* no gripper will be drawn */
617 if (lpBand->fStatus & (HAS_IMAGE | HAS_TEXT))
618 /* if no gripper but either image or text, then leave space */
619 xoff = REBAR_ALWAYS_SPACE;
620 SetRect (&lpBand->rcCapImage,
621 lpBand->rcBand.left+xoff, lpBand->rcBand.top,
622 lpBand->rcBand.left+xoff, lpBand->rcBand.bottom);
625 /* image is visible */
626 if (lpBand->fStatus & HAS_IMAGE) {
627 lpBand->fDraw |= DRAW_IMAGE;
628 lpBand->rcCapImage.right += infoPtr->imageSize.cx;
629 lpBand->rcCapImage.bottom = lpBand->rcCapImage.top + infoPtr->imageSize.cy;
631 /* set initial caption text rectangle */
632 SetRect (&lpBand->rcCapText,
633 lpBand->rcCapImage.right+REBAR_POST_IMAGE, lpBand->rcBand.top+1,
634 lpBand->rcBand.left+lpBand->cxHeader, lpBand->rcBand.bottom-1);
635 /* update band height
636 if (lpBand->uMinHeight < infoPtr->imageSize.cy + 2) {
637 lpBand->uMinHeight = infoPtr->imageSize.cy + 2;
638 lpBand->rcBand.bottom = lpBand->rcBand.top + lpBand->uMinHeight;
642 /* set initial caption text rectangle */
643 SetRect (&lpBand->rcCapText, lpBand->rcCapImage.right, lpBand->rcBand.top+1,
644 lpBand->rcBand.left+lpBand->cxHeader, lpBand->rcBand.bottom-1);
647 /* text is visible */
648 if (lpBand->fStatus & HAS_TEXT) {
649 lpBand->fDraw |= DRAW_TEXT;
650 lpBand->rcCapText.right = max(lpBand->rcCapText.left,
651 lpBand->rcCapText.right-REBAR_POST_TEXT);
654 /* set initial child window rectangle if there is a child */
655 if (lpBand->fMask & RBBIM_CHILD) {
656 xoff = lpBand->offChild.cx;
657 yoff = lpBand->offChild.cy;
658 SetRect (&lpBand->rcChild,
659 lpBand->rcBand.left+lpBand->cxHeader, lpBand->rcBand.top+yoff,
660 lpBand->rcBand.right-xoff, lpBand->rcBand.bottom-yoff);
663 SetRect (&lpBand->rcChild,
664 lpBand->rcBand.left+lpBand->cxHeader, lpBand->rcBand.top,
665 lpBand->rcBand.right, lpBand->rcBand.bottom);
668 /* flag if notify required and invalidate rectangle */
670 ((oldChild.right-oldChild.left != lpBand->rcChild.right-lpBand->rcChild.left) ||
671 (oldChild.bottom-oldChild.top != lpBand->rcChild.bottom-lpBand->rcChild.top))) {
672 TRACE("Child rectangle changed for band %u\n", i);
673 TRACE(" from (%d,%d)-(%d,%d) to (%d,%d)-(%d,%d)\n",
674 oldChild.left, oldChild.top,
675 oldChild.right, oldChild.bottom,
676 lpBand->rcChild.left, lpBand->rcChild.top,
677 lpBand->rcChild.right, lpBand->rcChild.bottom);
678 lpBand->fDraw |= NTF_CHILDSIZE;
680 if (lpBand->fDraw & NTF_INVALIDATE) {
681 TRACE("invalidating (%d,%d)-(%d,%d)\n",
684 lpBand->rcBand.right + ((lpBand->fDraw & DRAW_RIGHTSEP) ? SEP_WIDTH_SIZE : 0),
685 lpBand->rcBand.bottom + ((lpBand->fDraw & DRAW_BOTTOMSEP) ? SEP_WIDTH_SIZE : 0));
686 lpBand->fDraw &= ~NTF_INVALIDATE;
687 work = lpBand->rcBand;
688 if (lpBand->fDraw & DRAW_RIGHTSEP) work.right += SEP_WIDTH_SIZE;
689 if (lpBand->fDraw & DRAW_BOTTOMSEP) work.bottom += SEP_WIDTH_SIZE;
690 InvalidateRect(hwnd, &work, TRUE);
699 REBAR_CalcVertBand (HWND hwnd, REBAR_INFO *infoPtr, UINT rstart, UINT rend, BOOL notify, DWORD dwStyle)
700 /* Function: this routine initializes all the rectangles in */
701 /* each band in a row to fit in the adjusted rcBand rect. */
702 /* *** Supports only Vertical bars. *** */
706 NMREBARCHILDSIZE rbcz;
710 rbcz.hdr.hwndFrom = hwnd;
711 rbcz.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
712 /* MS seems to use GetDlgCtrlID() for above GetWindowLong call */
713 parenthwnd = GetParent (hwnd);
715 for(i=rstart; i<rend; i++){
716 lpBand = &infoPtr->bands[i];
717 if (HIDDENBAND(lpBand)) continue;
718 oldChild = lpBand->rcChild;
720 /* set initial gripper rectangle */
721 SetRect (&lpBand->rcGripper, lpBand->rcBand.left, lpBand->rcBand.top,
722 lpBand->rcBand.right, lpBand->rcBand.top);
724 /* calculate gripper rectangle */
725 if (lpBand->fStatus & HAS_GRIPPER) {
726 lpBand->fDraw |= DRAW_GRIPPER;
728 if (dwStyle & RBS_VERTICALGRIPPER) {
729 /* vertical gripper */
730 lpBand->rcGripper.left += 3;
731 lpBand->rcGripper.right = lpBand->rcGripper.left + GRIPPER_WIDTH;
732 lpBand->rcGripper.top += REBAR_PRE_GRIPPER;
733 lpBand->rcGripper.bottom = lpBand->rcGripper.top + GRIPPER_HEIGHT;
735 /* initialize Caption image rectangle */
736 SetRect (&lpBand->rcCapImage, lpBand->rcBand.left,
737 lpBand->rcGripper.bottom + REBAR_ALWAYS_SPACE,
738 lpBand->rcBand.right,
739 lpBand->rcGripper.bottom + REBAR_ALWAYS_SPACE);
742 /* horizontal gripper */
743 lpBand->rcGripper.left += 3;
744 lpBand->rcGripper.right -= 3;
745 lpBand->rcGripper.top += REBAR_PRE_GRIPPER;
746 lpBand->rcGripper.bottom = lpBand->rcGripper.top + GRIPPER_WIDTH;
748 /* initialize Caption image rectangle */
749 SetRect (&lpBand->rcCapImage, lpBand->rcBand.left,
750 lpBand->rcGripper.bottom + REBAR_ALWAYS_SPACE,
751 lpBand->rcBand.right,
752 lpBand->rcGripper.bottom + REBAR_ALWAYS_SPACE);
755 else { /* no gripper will be drawn */
757 if (lpBand->fStatus & (HAS_IMAGE | HAS_TEXT))
758 /* if no gripper but either image or text, then leave space */
759 xoff = REBAR_ALWAYS_SPACE;
760 /* initialize Caption image rectangle */
761 SetRect (&lpBand->rcCapImage,
762 lpBand->rcBand.left, lpBand->rcBand.top+xoff,
763 lpBand->rcBand.right, lpBand->rcBand.top+xoff);
766 /* image is visible */
767 if (lpBand->fStatus & HAS_IMAGE) {
768 lpBand->fDraw |= DRAW_IMAGE;
770 lpBand->rcCapImage.right = lpBand->rcCapImage.left + infoPtr->imageSize.cx;
771 lpBand->rcCapImage.bottom += infoPtr->imageSize.cy;
773 /* set initial caption text rectangle */
774 SetRect (&lpBand->rcCapText,
775 lpBand->rcBand.left, lpBand->rcCapImage.bottom+REBAR_POST_IMAGE,
776 lpBand->rcBand.right, lpBand->rcBand.top+lpBand->cxHeader);
777 /* update band height *
778 if (lpBand->uMinHeight < infoPtr->imageSize.cx + 2) {
779 lpBand->uMinHeight = infoPtr->imageSize.cx + 2;
780 lpBand->rcBand.right = lpBand->rcBand.left + lpBand->uMinHeight;
784 /* set initial caption text rectangle */
785 SetRect (&lpBand->rcCapText,
786 lpBand->rcBand.left, lpBand->rcCapImage.bottom,
787 lpBand->rcBand.right, lpBand->rcBand.top+lpBand->cxHeader);
790 /* text is visible */
791 if (lpBand->fStatus & HAS_TEXT) {
792 lpBand->fDraw |= DRAW_TEXT;
793 lpBand->rcCapText.bottom = max(lpBand->rcCapText.top,
794 lpBand->rcCapText.bottom-REBAR_POST_TEXT);
797 /* set initial child window rectangle if there is a child */
798 if (lpBand->fMask & RBBIM_CHILD) {
799 yoff = lpBand->offChild.cx;
800 xoff = lpBand->offChild.cy;
801 SetRect (&lpBand->rcChild,
802 lpBand->rcBand.left+xoff, lpBand->rcBand.top+lpBand->cxHeader,
803 lpBand->rcBand.right-xoff, lpBand->rcBand.bottom-yoff);
806 SetRect (&lpBand->rcChild,
807 lpBand->rcBand.left, lpBand->rcBand.top+lpBand->cxHeader,
808 lpBand->rcBand.right, lpBand->rcBand.bottom);
811 /* flag if notify required and invalidate rectangle */
813 ((oldChild.right-oldChild.left != lpBand->rcChild.right-lpBand->rcChild.left) ||
814 (oldChild.bottom-oldChild.top != lpBand->rcChild.bottom-lpBand->rcChild.top))) {
815 TRACE("Child rectangle changed for band %u\n", i);
816 TRACE(" from (%d,%d)-(%d,%d) to (%d,%d)-(%d,%d)\n",
817 oldChild.left, oldChild.top,
818 oldChild.right, oldChild.bottom,
819 lpBand->rcChild.left, lpBand->rcChild.top,
820 lpBand->rcChild.right, lpBand->rcChild.bottom);
821 lpBand->fDraw |= NTF_CHILDSIZE;
823 if (lpBand->fDraw & NTF_INVALIDATE) {
824 TRACE("invalidating (%d,%d)-(%d,%d)\n",
827 lpBand->rcBand.right + ((lpBand->fDraw & DRAW_BOTTOMSEP) ? SEP_WIDTH_SIZE : 0),
828 lpBand->rcBand.bottom + ((lpBand->fDraw & DRAW_RIGHTSEP) ? SEP_WIDTH_SIZE : 0));
829 lpBand->fDraw &= ~NTF_INVALIDATE;
830 work = lpBand->rcBand;
831 if (lpBand->fDraw & DRAW_RIGHTSEP) work.bottom += SEP_WIDTH_SIZE;
832 if (lpBand->fDraw & DRAW_BOTTOMSEP) work.right += SEP_WIDTH_SIZE;
833 InvalidateRect(hwnd, &work, TRUE);
841 REBAR_Layout (HWND hwnd, LPRECT lpRect, BOOL notify, BOOL resetclient)
842 /* Function: This routine is resposible for laying out all */
843 /* the bands in a rebar. It assigns each band to a row and*/
844 /* determines when to start a new row. */
846 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
847 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
848 REBAR_BAND *lpBand, *prevBand;
849 RECT rcClient, rcAdj, rcoldBand;
850 INT x, y, cx, cxsep, mcy, clientcx, clientcy;
851 INT adjcx, adjcy, row, rightx, bottomy, origheight;
852 UINT i, rowstartband;
855 GetClientRect (hwnd, &rcClient);
856 TRACE("Client is (%d,%d)-(%d,%d)\n",
857 rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
861 TRACE("adjustment rect is (%d,%d)-(%d,%d)\n",
862 rcAdj.left, rcAdj.top, rcAdj.right, rcAdj.bottom);
865 CopyRect (&rcAdj, &rcClient);
868 clientcx = rcClient.right - rcClient.left;
869 clientcy = rcClient.bottom - rcClient.top;
870 adjcx = rcAdj.right - rcAdj.left;
871 adjcy = rcAdj.bottom - rcAdj.top;
873 TRACE("window client rect will be set to adj rect\n");
878 /* save height of original control */
879 if (dwStyle & CCS_VERT)
880 origheight = infoPtr->calcSize.cx;
882 origheight = infoPtr->calcSize.cy;
885 /* ******* Start Phase 1 - all bands on row at minimum size ******* */
894 for (i = 0; i < infoPtr->uNumBands; i++) {
895 lpBand = &infoPtr->bands[i];
899 if ((lpBand->fStyle & RBBS_HIDDEN) ||
900 ((dwStyle & CCS_VERT) && (lpBand->fStyle & RBBS_NOVERT)))
903 rcoldBand = lpBand->rcBand;
905 /* separator from previous band */
906 cxsep = ( ((dwStyle & CCS_VERT) ? y : x)==0) ? 0 : SEP_WIDTH;
908 /* Header: includes gripper, text, image */
909 cx = lpBand->cxHeader;
910 if (lpBand->fStyle & RBBS_FIXEDSIZE) cx += lpBand->lcx;
912 if (dwStyle & CCS_VERT)
913 dobreak = (y + cx + cxsep > adjcy);
915 dobreak = (x + cx + cxsep > adjcx);
917 /* This is the check for whether we need to start a new row */
918 if ( ( (lpBand->fStyle & RBBS_BREAK) && (i != 0) ) ||
919 ( ((dwStyle & CCS_VERT) ? (y != 0) : (x != 0)) && dobreak)) {
920 TRACE("Spliting to new row %d on band %u\n", row+1, i);
921 if (dwStyle & CCS_VERT) {
923 x += (mcy + SEP_WIDTH);
927 y += (mcy + SEP_WIDTH);
930 /* FIXME: if not RBS_VARHEIGHT then find max */
938 if (mcy < lpBand->lcy + REBARSPACE) mcy = lpBand->lcy + REBARSPACE;
940 /* if boundary rect specified then limit mcy */
942 if (dwStyle & CCS_VERT) {
945 TRACE("row %u limiting mcy=%d, adjcx=%d, x=%d\n",
952 TRACE("row %u limiting mcy=%d, adjcy=%d, y=%d\n",
958 if (dwStyle & CCS_VERT) {
959 /* bound the bottom side if we have a bounding rectangle */
960 if ((x>0) && (dwStyle & RBS_BANDBORDERS) && prevBand)
961 prevBand->fDraw |= DRAW_RIGHTSEP;
963 bottomy = (lpRect) ? min(clientcy, y+cxsep+cx) : y+cxsep+cx;
964 lpBand->rcBand.left = x;
965 lpBand->rcBand.right = x + min(mcy, lpBand->lcy+REBARSPACE);
966 lpBand->rcBand.top = min(bottomy, y + cxsep);
967 lpBand->rcBand.bottom = bottomy;
968 lpBand->uMinHeight = lpBand->lcy;
969 if (!EqualRect(&rcoldBand, &lpBand->rcBand))
970 lpBand->fDraw |= NTF_INVALIDATE;
974 /* bound the right side if we have a bounding rectangle */
975 if ((x>0) && (dwStyle & RBS_BANDBORDERS) && prevBand)
976 prevBand->fDraw |= DRAW_RIGHTSEP;
977 rightx = (lpRect) ? min(clientcx, x+cxsep+cx) : x+cxsep+cx;
979 lpBand->rcBand.left = min(rightx, x + cxsep);
980 lpBand->rcBand.right = rightx;
981 lpBand->rcBand.top = y;
982 lpBand->rcBand.bottom = y + min(mcy, lpBand->lcy+REBARSPACE);
983 lpBand->uMinHeight = lpBand->lcy;
984 if (!EqualRect(&rcoldBand, &lpBand->rcBand))
985 lpBand->fDraw |= NTF_INVALIDATE;
988 TRACE("band %u, row %d, (%d,%d)-(%d,%d)\n",
990 lpBand->rcBand.left, lpBand->rcBand.top,
991 lpBand->rcBand.right, lpBand->rcBand.bottom);
994 } /* for (i = 0; i < infoPtr->uNumBands... */
996 if (dwStyle & CCS_VERT)
1001 if (infoPtr->uNumBands)
1002 infoPtr->uNumRows = row;
1004 /* ******* End Phase 1 - all bands on row at minimum size ******* */
1007 /* ******* Start Phase 2 - split rows till adjustment height full ******* */
1009 /* assumes that the following variables contain: */
1010 /* y/x current height/width of all rows */
1012 INT i, j, prev_rh, current_rh, new_rh, adj_rh;
1013 REBAR_BAND *prev, *current, *walk;
1015 /* if (((dwStyle & CCS_VERT) ? (x < adjcx) : (y < adjcy)) && */
1017 if (((dwStyle & CCS_VERT) ? (adjcx - x > 4) : (adjcy - y > 4)) &&
1018 (infoPtr->uNumBands > 1)) {
1019 for (i=infoPtr->uNumBands-2; i>=0; i--) {
1020 TRACE("adjcx=%d, adjcy=%d, x=%d, y=%d\n",
1021 adjcx, adjcy, x, y);
1022 prev = &infoPtr->bands[i];
1023 prev_rh = ircBrb(prev) - ircBlt(prev);
1024 current = &infoPtr->bands[i+1];
1025 current_rh = ircBrb(current) - ircBlt(current);
1026 if (prev->iRow == current->iRow) {
1027 new_rh = current->lcy + REBARSPACE;
1028 adj_rh = prev_rh + new_rh + SEP_WIDTH - current_rh;
1029 infoPtr->uNumRows++;
1030 current->fDraw |= NTF_INVALIDATE;
1032 if (dwStyle & CCS_VERT) {
1033 current->rcBand.top = 0;
1034 current->rcBand.bottom = clientcy;
1035 current->rcBand.left += (prev_rh + SEP_WIDTH);
1036 current->rcBand.right = current->rcBand.left + new_rh;
1040 current->rcBand.left = 0;
1041 current->rcBand.right = clientcx;
1042 current->rcBand.top += (prev_rh + SEP_WIDTH);
1043 current->rcBand.bottom = current->rcBand.top + new_rh;
1046 TRACE("moving band %d to own row at (%d,%d)-(%d,%d)\n",
1048 current->rcBand.left, current->rcBand.top,
1049 current->rcBand.right, current->rcBand.bottom);
1050 TRACE("prev band %d at (%d,%d)-(%d,%d)\n",
1052 prev->rcBand.left, prev->rcBand.top,
1053 prev->rcBand.right, prev->rcBand.bottom);
1054 TRACE("values: prev_rh=%d, current_rh=%d, new_rh=%d, adj_rh=%d\n",
1055 prev_rh, current_rh, new_rh, adj_rh);
1056 /* for bands below current adjust row # and top/bottom */
1057 for (j = i+2; j<infoPtr->uNumBands; j++) {
1058 walk = &infoPtr->bands[j];
1059 walk->fDraw |= NTF_INVALIDATE;
1061 if (dwStyle & CCS_VERT) {
1062 walk->rcBand.left += adj_rh;
1063 walk->rcBand.right += adj_rh;
1066 walk->rcBand.top += adj_rh;
1067 walk->rcBand.bottom += adj_rh;
1070 if ((dwStyle & CCS_VERT) ? (x >= adjcx) : (y >= adjcy))
1071 break; /* all done */
1077 /* ******* End Phase 2 - split rows till adjustment height full ******* */
1081 /* ******* Start Phase 3 - adjust all bands for width full ******* */
1083 if (infoPtr->uNumBands) {
1084 REBAR_BAND *prev, *current;
1085 /* If RBS_BANDBORDERS set then indicate to draw bottom separator */
1086 if (dwStyle & RBS_BANDBORDERS) {
1087 for (i = 0; i < infoPtr->uNumBands; i++) {
1088 lpBand = &infoPtr->bands[i];
1089 if (HIDDENBAND(lpBand)) continue;
1090 if (lpBand->iRow < infoPtr->uNumRows)
1091 lpBand->fDraw |= DRAW_BOTTOMSEP;
1095 /* Adjust the horizontal and vertical of each band */
1096 prev = &infoPtr->bands[0];
1098 mcy = prev->lcy + REBARSPACE;
1100 for (i=1; i<infoPtr->uNumBands; i++) {
1101 prev = &infoPtr->bands[i-1];
1102 current = &infoPtr->bands[i];
1103 if (prev->iRow != current->iRow) {
1104 REBAR_AdjustBands (infoPtr, rowstartband, i,
1105 (dwStyle & CCS_VERT) ? clientcy : clientcx,
1111 if (mcy < current->lcy + REBARSPACE)
1112 mcy = current->lcy + REBARSPACE;
1114 REBAR_AdjustBands (infoPtr, rowstartband, infoPtr->uNumBands,
1115 (dwStyle & CCS_VERT) ? clientcy : clientcx,
1119 /* Calculate the other rectangles in each band */
1120 if (dwStyle & CCS_VERT) {
1121 REBAR_CalcVertBand (hwnd, infoPtr, 0, infoPtr->uNumBands,
1125 REBAR_CalcHorzBand (hwnd, infoPtr, 0, infoPtr->uNumBands,
1130 /* ******* End Phase 3 - adjust all bands for width full ******* */
1133 /* FIXME: if not RBS_VARHEIGHT then find max mcy and adj rect*/
1135 infoPtr->oldSize = infoPtr->calcSize;
1136 if (dwStyle & CCS_VERT) {
1137 infoPtr->calcSize.cx = x;
1138 infoPtr->calcSize.cy = clientcy;
1139 TRACE("vert, notify=%d, x=%d, origheight=%d\n",
1140 notify, x, origheight);
1141 if (notify && (x != origheight)) infoPtr->fStatus |= NTF_HGHTCHG;
1144 infoPtr->calcSize.cx = clientcx;
1145 infoPtr->calcSize.cy = y;
1146 TRACE("horz, notify=%d, y=%d, origheight=%d\n",
1147 notify, y, origheight);
1148 if (notify && (y != origheight)) infoPtr->fStatus |= NTF_HGHTCHG;
1150 REBAR_DumpBand (hwnd);
1155 REBAR_ForceResize (HWND hwnd)
1156 /* Function: This changes the size of the REBAR window to that */
1157 /* calculated by REBAR_Layout. */
1159 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1162 TRACE( " from [%ld x %ld] to [%ld x %ld]!\n",
1163 infoPtr->oldSize.cx, infoPtr->oldSize.cy,
1164 infoPtr->calcSize.cx, infoPtr->calcSize.cy);
1166 /* if size did not change then skip process */
1167 if ((infoPtr->oldSize.cx == infoPtr->calcSize.cx) &&
1168 (infoPtr->oldSize.cy == infoPtr->calcSize.cy) &&
1169 !(infoPtr->fStatus & RESIZE_ANYHOW))
1172 infoPtr->fStatus &= ~RESIZE_ANYHOW;
1173 /* Set flag to ignore next WM_SIZE message */
1174 infoPtr->fStatus |= AUTO_RESIZE;
1178 rc.right = infoPtr->calcSize.cx;
1179 rc.bottom = infoPtr->calcSize.cy;
1181 if (GetWindowLongA (hwnd, GWL_STYLE) & WS_BORDER) {
1182 InflateRect (&rc, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
1185 SetWindowPos (hwnd, 0, 0, 0,
1186 rc.right - rc.left, rc.bottom - rc.top,
1187 SWP_NOMOVE | SWP_NOZORDER | SWP_SHOWWINDOW);
1192 REBAR_MoveChildWindows (HWND hwnd)
1194 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1196 CHAR szClassName[40];
1198 NMREBARCHILDSIZE rbcz;
1201 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1203 if (!(deferpos = BeginDeferWindowPos(8)))
1204 ERR("BeginDeferWindowPso returned NULL\n");
1206 for (i = 0; i < infoPtr->uNumBands; i++) {
1207 lpBand = &infoPtr->bands[i];
1209 if (HIDDENBAND(lpBand)) continue;
1210 if (lpBand->hwndChild) {
1211 TRACE("hwndChild = %x\n", lpBand->hwndChild);
1213 if (lpBand->fDraw & NTF_CHILDSIZE) {
1214 lpBand->fDraw &= ~NTF_CHILDSIZE;
1216 rbcz.wID = lpBand->wID;
1217 rbcz.rcChild = lpBand->rcChild;
1218 rbcz.rcBand = lpBand->rcBand;
1219 rbcz.rcBand.left += lpBand->cxHeader;
1220 REBAR_Notify (hwnd, (NMHDR *)&rbcz, infoPtr, RBN_CHILDSIZE);
1221 if (!EqualRect (&lpBand->rcChild, &rbcz.rcChild)) {
1222 TRACE("Child rect changed by NOTIFY for band %u\n", i);
1223 TRACE(" from (%d,%d)-(%d,%d) to (%d,%d)-(%d,%d)\n",
1224 lpBand->rcChild.left, lpBand->rcChild.top,
1225 lpBand->rcChild.right, lpBand->rcChild.bottom,
1226 rbcz.rcChild.left, rbcz.rcChild.top,
1227 rbcz.rcChild.right, rbcz.rcChild.bottom);
1231 GetClassNameA (lpBand->hwndChild, szClassName, 40);
1232 if (!lstrcmpA (szClassName, "ComboBox") ||
1233 !lstrcmpA (szClassName, WC_COMBOBOXEXA)) {
1234 INT nEditHeight, yPos;
1237 /* special placement code for combo or comboex box */
1240 /* get size of edit line */
1241 GetWindowRect (lpBand->hwndChild, &rc);
1242 nEditHeight = rc.bottom - rc.top;
1243 yPos = (lpBand->rcChild.bottom + lpBand->rcChild.top - nEditHeight)/2;
1245 /* center combo box inside child area */
1246 TRACE("moving child (Combo(Ex)) %04x to (%d,%d)-(%d,%d)\n",
1248 lpBand->rcChild.left, yPos,
1249 lpBand->rcChild.right - lpBand->rcChild.left,
1251 deferpos = DeferWindowPos (deferpos, lpBand->hwndChild, HWND_TOP,
1252 lpBand->rcChild.left,
1253 /*lpBand->rcChild.top*/ yPos,
1254 lpBand->rcChild.right - lpBand->rcChild.left,
1258 ERR("DeferWindowPos returned NULL\n");
1261 TRACE("moving child (Other) %04x to (%d,%d)-(%d,%d)\n",
1263 lpBand->rcChild.left, lpBand->rcChild.top,
1264 lpBand->rcChild.right - lpBand->rcChild.left,
1265 lpBand->rcChild.bottom - lpBand->rcChild.top);
1266 deferpos = DeferWindowPos (deferpos, lpBand->hwndChild, HWND_TOP,
1267 lpBand->rcChild.left,
1268 lpBand->rcChild.top,
1269 lpBand->rcChild.right - lpBand->rcChild.left,
1270 lpBand->rcChild.bottom - lpBand->rcChild.top,
1273 ERR("DeferWindowPos returned NULL\n");
1277 if (!EndDeferWindowPos(deferpos))
1278 ERR("EndDeferWindowPos returned NULL\n");
1279 if (infoPtr->fStatus & NTF_HGHTCHG) {
1280 infoPtr->fStatus &= ~NTF_HGHTCHG;
1281 REBAR_Notify (hwnd, &heightchange, infoPtr, RBN_HEIGHTCHANGE);
1287 REBAR_ValidateBand (HWND hwnd, REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
1288 /* Function: This routine evaluates the band specs supplied */
1289 /* by the user and updates the following 5 fields in */
1290 /* the internal band structure: cxHeader, lcx, lcy, hcx, hcy*/
1294 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1296 lpBand->fStatus = 0;
1302 /* Data comming in from users into the cx... and cy... fields */
1303 /* may be bad, just garbage, because the user never clears */
1304 /* the fields. RB_{SET|INSERT}BAND{A|W} just passes the data */
1305 /* along if the fields exist in the input area. Here we must */
1306 /* determine if the data is valid. I have no idea how MS does */
1307 /* the validation, but it does because the RB_GETBANDINFO */
1308 /* returns a 0 when I know the sample program passed in an */
1309 /* address. Here I will use the algorithim that if the value */
1310 /* is greater than 65535 then it is bad and replace it with */
1311 /* a zero. Feel free to improve the algorithim. - GA 12/2000 */
1312 if (lpBand->cxMinChild > 65535) lpBand->cxMinChild = 0;
1313 if (lpBand->cyMinChild > 65535) lpBand->cyMinChild = 0;
1314 if (lpBand->cx > 65535) lpBand->cx = 0;
1315 if (lpBand->cyChild > 65535) lpBand->cyChild = 0;
1316 if (lpBand->cyMaxChild > 65535) lpBand->cyMaxChild = 0;
1317 if (lpBand->cyIntegral > 65535) lpBand->cyIntegral = 0;
1318 if (lpBand->cxIdeal > 65535) lpBand->cxIdeal = 0;
1319 if (lpBand->cxHeader > 65535) lpBand->cxHeader = 0;
1321 /* Header is where the image, text and gripper exist */
1322 /* in the band and preceed the child window. */
1324 /* calculate gripper rectangle */
1325 if ( (!(lpBand->fStyle & RBBS_NOGRIPPER)) &&
1326 ( (lpBand->fStyle & RBBS_GRIPPERALWAYS) ||
1327 ( !(lpBand->fStyle & RBBS_FIXEDSIZE) && (infoPtr->uNumBands > 1)))
1329 lpBand->fStatus |= HAS_GRIPPER;
1330 if (dwStyle & CCS_VERT)
1331 if (dwStyle & RBS_VERTICALGRIPPER)
1332 header += (GRIPPER_HEIGHT + REBAR_PRE_GRIPPER);
1334 header += (GRIPPER_WIDTH + REBAR_PRE_GRIPPER);
1336 header += (REBAR_PRE_GRIPPER + GRIPPER_WIDTH);
1337 /* Always have 4 pixels before anything else */
1338 header += REBAR_ALWAYS_SPACE;
1341 /* image is visible */
1342 if ((lpBand->fMask & RBBIM_IMAGE) && (infoPtr->himl)) {
1343 lpBand->fStatus |= HAS_IMAGE;
1344 if (dwStyle & CCS_VERT) {
1345 header += (infoPtr->imageSize.cy + REBAR_POST_IMAGE);
1346 lpBand->lcy = infoPtr->imageSize.cx + 2;
1349 header += (infoPtr->imageSize.cx + REBAR_POST_IMAGE);
1350 lpBand->lcy = infoPtr->imageSize.cy + 2;
1354 /* text is visible */
1355 if ((lpBand->fMask & RBBIM_TEXT) && (lpBand->lpText)) {
1356 HDC hdc = GetDC (0);
1357 HFONT hOldFont = SelectObject (hdc, infoPtr->hFont);
1360 lpBand->fStatus |= HAS_TEXT;
1361 GetTextExtentPoint32W (hdc, lpBand->lpText,
1362 lstrlenW (lpBand->lpText), &size);
1363 header += ((dwStyle & CCS_VERT) ? (size.cy + REBAR_POST_TEXT) : (size.cx + REBAR_POST_TEXT));
1364 textheight = (dwStyle & CCS_VERT) ? 0 : size.cy;
1366 SelectObject (hdc, hOldFont);
1370 /* if no gripper but either image or text, then leave space */
1371 if ((lpBand->fStatus & (HAS_IMAGE | HAS_TEXT)) &&
1372 !(lpBand->fStatus & HAS_GRIPPER)) {
1373 header += REBAR_ALWAYS_SPACE;
1376 /* check if user overrode the header value */
1377 if (!(lpBand->fMask & RBBIM_HEADERSIZE))
1378 lpBand->cxHeader = header;
1381 /* Now compute minimum size of child window */
1382 lpBand->offChild.cx = 0;
1383 lpBand->offChild.cy = 0;
1384 lpBand->lcy = textheight;
1385 if (lpBand->fMask & RBBIM_CHILDSIZE) {
1386 if (!(lpBand->fStyle & RBBS_FIXEDSIZE)) {
1387 lpBand->offChild.cx = 4;
1388 lpBand->offChild.cy = 2;
1390 lpBand->lcx = lpBand->cxMinChild;
1391 lpBand->lcy = max(lpBand->lcy, lpBand->cyMinChild);
1392 lpBand->hcy = lpBand->lcy;
1393 if (lpBand->fStyle & RBBS_VARIABLEHEIGHT) {
1394 if (lpBand->cyChild != 0xffffffff)
1395 lpBand->lcy = max (lpBand->cyChild, lpBand->lcy);
1396 lpBand->hcy = lpBand->cyMaxChild;
1398 TRACE("_CHILDSIZE\n");
1400 if (lpBand->fMask & RBBIM_SIZE) {
1401 lpBand->hcx = max (lpBand->cx, lpBand->lcx);
1405 lpBand->hcx = lpBand->lcx;
1410 REBAR_CommonSetupBand (HWND hwnd, LPREBARBANDINFOA lprbbi, REBAR_BAND *lpBand)
1411 /* Function: This routine copies the supplied values from */
1412 /* user input (lprbbi) to the internal band structure. */
1414 lpBand->fMask |= lprbbi->fMask;
1416 if (lprbbi->fMask & RBBIM_STYLE)
1417 lpBand->fStyle = lprbbi->fStyle;
1419 if (lprbbi->fMask & RBBIM_COLORS) {
1420 lpBand->clrFore = lprbbi->clrFore;
1421 lpBand->clrBack = lprbbi->clrBack;
1424 if (lprbbi->fMask & RBBIM_IMAGE)
1425 lpBand->iImage = lprbbi->iImage;
1427 if (lprbbi->fMask & RBBIM_CHILD) {
1428 if (lprbbi->hwndChild) {
1429 lpBand->hwndChild = lprbbi->hwndChild;
1430 lpBand->hwndPrevParent =
1431 SetParent (lpBand->hwndChild, hwnd);
1434 TRACE("child: 0x%x prev parent: 0x%x\n",
1435 lpBand->hwndChild, lpBand->hwndPrevParent);
1436 lpBand->hwndChild = 0;
1437 lpBand->hwndPrevParent = 0;
1441 if (lprbbi->fMask & RBBIM_CHILDSIZE) {
1442 lpBand->cxMinChild = lprbbi->cxMinChild;
1443 lpBand->cyMinChild = lprbbi->cyMinChild;
1444 if (lprbbi->cbSize >= sizeof (REBARBANDINFOA)) {
1445 lpBand->cyChild = lprbbi->cyChild;
1446 lpBand->cyMaxChild = lprbbi->cyMaxChild;
1447 lpBand->cyIntegral = lprbbi->cyIntegral;
1449 else { /* special case - these should be zeroed out since */
1450 /* RBBIM_CHILDSIZE added these in WIN32_IE >= 0x0400 */
1451 lpBand->cyChild = 0;
1452 lpBand->cyMaxChild = 0;
1453 lpBand->cyIntegral = 0;
1457 if (lprbbi->fMask & RBBIM_SIZE)
1458 lpBand->cx = lprbbi->cx;
1460 if (lprbbi->fMask & RBBIM_BACKGROUND)
1461 lpBand->hbmBack = lprbbi->hbmBack;
1463 if (lprbbi->fMask & RBBIM_ID)
1464 lpBand->wID = lprbbi->wID;
1466 /* check for additional data */
1467 if (lprbbi->cbSize >= sizeof (REBARBANDINFOA)) {
1468 if (lprbbi->fMask & RBBIM_IDEALSIZE)
1469 lpBand->cxIdeal = lprbbi->cxIdeal;
1471 if (lprbbi->fMask & RBBIM_LPARAM)
1472 lpBand->lParam = lprbbi->lParam;
1474 if (lprbbi->fMask & RBBIM_HEADERSIZE)
1475 lpBand->cxHeader = lprbbi->cxHeader;
1480 REBAR_InternalEraseBkGnd (HWND hwnd, WPARAM wParam, LPARAM lParam, RECT *clip)
1481 /* Function: This erases the background rectangle with the */
1482 /* default brush, then with any band that has a different */
1483 /* background color. */
1485 HBRUSH hbrBackground = GetClassWord(hwnd, GCW_HBRBACKGROUND);
1486 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1492 FillRect( (HDC) wParam, clip, hbrBackground);
1494 for(i=0; i<infoPtr->uNumBands; i++) {
1495 lpBand = &infoPtr->bands[i];
1496 if (lpBand->clrBack != CLR_NONE) {
1497 if (IntersectRect (&eraserect, clip, &lpBand->rcBand)) {
1498 /* draw background */
1499 HBRUSH brh = CreateSolidBrush (lpBand->clrBack);
1500 TRACE("backround color=0x%06lx, band (%d,%d)-(%d,%d), clip (%d,%d)-(%d,%d)\n",
1502 lpBand->rcBand.left,lpBand->rcBand.top,
1503 lpBand->rcBand.right,lpBand->rcBand.bottom,
1504 clip->left, clip->top,
1505 clip->right, clip->bottom);
1506 FillRect ( (HDC)wParam, &eraserect, brh);
1515 REBAR_InternalHitTest (HWND hwnd, LPPOINT lpPt, UINT *pFlags, INT *pBand)
1517 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1522 GetClientRect (hwnd, &rect);
1524 *pFlags = RBHT_NOWHERE;
1525 if (PtInRect (&rect, *lpPt))
1527 if (infoPtr->uNumBands == 0) {
1528 *pFlags = RBHT_NOWHERE;
1535 /* somewhere inside */
1536 infoPtr->ihitBand = -1;
1537 for (iCount = 0; iCount < infoPtr->uNumBands; iCount++) {
1538 lpBand = &infoPtr->bands[iCount];
1539 if (PtInRect (&lpBand->rcBand, *lpPt)) {
1542 if (PtInRect (&lpBand->rcGripper, *lpPt)) {
1543 *pFlags = RBHT_GRABBER;
1544 infoPtr->ihitBand = iCount;
1545 TRACE("ON GRABBER %d\n", iCount);
1548 else if (PtInRect (&lpBand->rcCapImage, *lpPt)) {
1549 *pFlags = RBHT_CAPTION;
1550 TRACE("ON CAPTION %d\n", iCount);
1553 else if (PtInRect (&lpBand->rcCapText, *lpPt)) {
1554 *pFlags = RBHT_CAPTION;
1555 TRACE("ON CAPTION %d\n", iCount);
1558 else if (PtInRect (&lpBand->rcChild, *lpPt)) {
1559 *pFlags = RBHT_CLIENT;
1560 TRACE("ON CLIENT %d\n", iCount);
1564 *pFlags = RBHT_NOWHERE;
1565 TRACE("NOWHERE %d\n", iCount);
1571 *pFlags = RBHT_NOWHERE;
1580 *pFlags = RBHT_NOWHERE;
1587 TRACE("flags=0x%X\n", *pFlags);
1591 #define READJ(b,i) {if(dwStyle & CCS_VERT) b->rcBand.bottom+=(i); \
1592 else b->rcBand.right += (i);}
1593 #define LEADJ(b,i) {if(dwStyle & CCS_VERT) b->rcBand.top+=(i); \
1594 else b->rcBand.left += (i);}
1598 REBAR_Shrink (REBAR_BAND *band, INT movement, INT i, DWORD dwStyle)
1599 /* Function: This attempts to shrink the given band by the */
1600 /* the amount in "movement". A shrink to the left is indi- */
1601 /* cated by "movement" being negative. "i" is merely the */
1602 /* band index for trace messages. */
1604 INT Leadjust, Readjust, avail, ret;
1606 /* Note: a left drag is indicated by "movement" being negative. */
1607 /* Similarly, a right drag is indicated by "movement" */
1608 /* being positive. "movement" should never be 0, but if */
1609 /* it is then the band does not move. */
1611 avail = rcBrb(band) - rcBlt(band) - band->cxHeader - band->lcx;
1613 /* now compute the Left End adjustment factor and Right End */
1614 /* adjustment factor. They may be different if shrinking. */
1616 /* if this band is not shrinkable, then just move it */
1617 Leadjust = Readjust = movement;
1623 if (avail <= abs(movement)) {
1624 Readjust = movement;
1625 Leadjust = movement + avail;
1629 Readjust = movement;
1636 if (avail <= abs(movement)) {
1637 Leadjust = movement;
1638 Readjust = movement - avail;
1642 Leadjust = movement;
1649 /* Reasonability Check */
1650 if (rcBlt(band) + Leadjust < 0) {
1651 ERR("adjustment will fail, band %d: left=%d, right=%d, move=%d, rtn=%d\n",
1652 i, Leadjust, Readjust, movement, ret);
1655 LEADJ(band, Leadjust);
1656 READJ(band, Readjust);
1658 TRACE("band %d: left=%d, right=%d, move=%d, rtn=%d, rcBand=(%d,%d)-(%d,%d)\n",
1659 i, Leadjust, Readjust, movement, ret,
1660 band->rcBand.left, band->rcBand.top,
1661 band->rcBand.right, band->rcBand.bottom);
1667 REBAR_HandleLRDrag (HWND hwnd, REBAR_INFO *infoPtr, POINTS *ptsmove, DWORD dwStyle)
1668 /* Function: This will implement the functionality of a */
1669 /* Gripper drag within a row. It will not implement "out- */
1670 /* of-row" drags. (They are detected and handled in */
1671 /* REBAR_MouseMove.) */
1672 /* **** FIXME Switching order of bands in a row not **** */
1673 /* **** yet implemented. **** */
1675 REBAR_BAND *hitBand, *band, *prevband, *mindBand, *maxdBand;
1677 NMREBARCHILDSIZE cs;
1679 INT imindBand = -1, imaxdBand, ihitBand, i, movement, tempx;
1680 INT RHeaderSum = 0, LHeaderSum = 0;
1683 /* on first significant mouse movement, issue notify */
1685 if (!(infoPtr->fStatus & BEGIN_DRAG_ISSUED)) {
1686 if (REBAR_Notify_NMREBAR (hwnd, infoPtr, -1, RBN_BEGINDRAG)) {
1687 /* Notify returned TRUE - abort drag */
1688 infoPtr->dragStart.x = 0;
1689 infoPtr->dragStart.y = 0;
1690 infoPtr->dragNow = infoPtr->dragStart;
1691 infoPtr->ihitBand = -1;
1695 infoPtr->fStatus |= BEGIN_DRAG_ISSUED;
1698 ihitBand = infoPtr->ihitBand;
1699 hitBand = &infoPtr->bands[ihitBand];
1700 imaxdBand = ihitBand; /* to suppress warning message */
1702 /* find all the bands in the row of the one whose Gripper was seized */
1703 for (i=0; i<infoPtr->uNumBands; i++) {
1704 band = &infoPtr->bands[i];
1705 if (HIDDENBAND(band)) continue;
1706 if (band->iRow == hitBand->iRow) {
1708 if (imindBand == -1) imindBand = i;
1709 /* minimum size of each band is size of header plus */
1710 /* size of minimum child plus offset of child from header plus */
1711 /* a one to separate each band. */
1713 LHeaderSum += (band->cxHeader + band->lcx + SEP_WIDTH);
1715 RHeaderSum += (band->cxHeader + band->lcx + SEP_WIDTH);
1719 if (RHeaderSum) RHeaderSum -= SEP_WIDTH; /* no separator afterlast band */
1721 mindBand = &infoPtr->bands[imindBand];
1722 maxdBand = &infoPtr->bands[imaxdBand];
1724 if (imindBand == imaxdBand) return; /* nothing to drag agains */
1725 if (imindBand == ihitBand) return; /* first band in row, cant drag */
1727 /* limit movement to inside adjustable bands - Left */
1728 if ( (ptsmove->x < mindBand->rcBand.left) ||
1729 (ptsmove->x > maxdBand->rcBand.right) ||
1730 (ptsmove->y < mindBand->rcBand.top) ||
1731 (ptsmove->y > maxdBand->rcBand.bottom))
1732 return; /* should swap bands */
1734 if (dwStyle & CCS_VERT)
1735 movement = ptsmove->y - ((hitBand->rcBand.top+REBAR_PRE_GRIPPER) -
1736 infoPtr->ihitoffset);
1738 movement = ptsmove->x - ((hitBand->rcBand.left+REBAR_PRE_GRIPPER) -
1739 infoPtr->ihitoffset);
1740 infoPtr->dragNow = *ptsmove;
1742 TRACE("before: movement=%d (%d,%d), imindBand=%d, ihitBand=%d, imaxdBand=%d, LSum=%d, RSum=%d\n",
1743 movement, ptsmove->x, ptsmove->y, imindBand, ihitBand,
1744 imaxdBand, LHeaderSum, RHeaderSum);
1745 REBAR_DumpBand (hwnd);
1749 /* *** Drag left/up *** */
1750 compress = rcBlt(hitBand) - rcBlt(mindBand) -
1752 if (compress < abs(movement)) {
1753 TRACE("limiting left drag, was %d changed to %d\n",
1754 movement, -compress);
1755 movement = -compress;
1757 for (i=ihitBand; i>=imindBand; i--) {
1758 band = &infoPtr->bands[i];
1759 if (i == ihitBand) {
1760 prevband = &infoPtr->bands[i-1];
1761 if (rcBlt(band) - movement <= rcBlt(prevband)) {
1762 tempx = movement - (rcBrb(prevband)-rcBlt(band)+1);
1763 ERR("movement bad. BUG!! was %d, left=%d, right=%d, setting to %d\n",
1764 movement, rcBlt(band), rcBlt(prevband), tempx);
1767 LEADJ(band, movement)
1770 movement = REBAR_Shrink (band, movement, i, dwStyle);
1775 /* *** Drag right/down *** */
1776 compress = rcBrb(maxdBand) - rcBlt(hitBand) -
1778 if (compress < abs(movement)) {
1779 TRACE("limiting right drag, was %d changed to %d\n",
1780 movement, compress);
1781 movement = compress;
1783 for (i=ihitBand-1; i<=imaxdBand; i++) {
1784 band = &infoPtr->bands[i];
1785 if (HIDDENBAND(band)) continue;
1786 if (i == ihitBand-1) {
1787 READJ(band, movement)
1790 movement = REBAR_Shrink (band, movement, i, dwStyle);
1794 /* recompute all rectangles */
1795 if (dwStyle & CCS_VERT) {
1796 REBAR_CalcVertBand (hwnd, infoPtr, imindBand, imaxdBand+1,
1800 REBAR_CalcHorzBand (hwnd, infoPtr, imindBand, imaxdBand+1,
1804 TRACE("bands after adjustment, see band # %d, %d\n",
1805 imindBand, imaxdBand);
1806 REBAR_DumpBand (hwnd);
1809 mindBand->rcBand.left,
1810 mindBand->rcBand.top,
1811 maxdBand->rcBand.right,
1812 maxdBand->rcBand.bottom);
1814 if (!(deferpos = BeginDeferWindowPos (4))) {
1815 ERR("BeginDeferWindowPos returned NULL\n");
1818 for (i=imindBand; i<=imaxdBand; i++) {
1819 band = &infoPtr->bands[i];
1820 if ((band->fMask & RBBIM_CHILD) && band->hwndChild) {
1823 cs.rcChild = band->rcChild;
1824 cs.rcBand = band->rcBand;
1825 cs.rcBand.left += band->cxHeader;
1826 REBAR_Notify (hwnd, (NMHDR *) &cs, infoPtr, RBN_CHILDSIZE);
1827 deferpos = DeferWindowPos (deferpos, band->hwndChild, HWND_TOP,
1828 cs.rcChild.left, cs.rcChild.top,
1829 cs.rcChild.right - cs.rcChild.left,
1830 cs.rcChild.bottom - cs.rcChild.top,
1833 ERR("DeferWindowPos returned NULL\n");
1838 if (!EndDeferWindowPos (deferpos)) {
1839 ERR("EndDeferWindowPos failed\n");
1842 InvalidateRect (hwnd, &newrect, TRUE);
1843 UpdateWindow (hwnd);
1851 /* << REBAR_BeginDrag >> */
1855 REBAR_DeleteBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
1857 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1858 UINT uBand = (UINT)wParam;
1862 if (uBand >= infoPtr->uNumBands)
1865 TRACE("deleting band %u!\n", uBand);
1866 lpBand = &infoPtr->bands[uBand];
1867 REBAR_Notify_NMREBAR (hwnd, infoPtr, uBand, RBN_DELETINGBAND);
1869 if (infoPtr->uNumBands == 1) {
1870 TRACE(" simple delete!\n");
1871 if ((lpBand->fMask & RBBIM_CHILD) && lpBand->hwndChild)
1872 childhwnd = lpBand->hwndChild;
1873 COMCTL32_Free (infoPtr->bands);
1874 infoPtr->bands = NULL;
1875 infoPtr->uNumBands = 0;
1878 REBAR_BAND *oldBands = infoPtr->bands;
1879 TRACE("complex delete! [uBand=%u]\n", uBand);
1881 if ((lpBand->fMask & RBBIM_CHILD) && lpBand->hwndChild)
1882 childhwnd = lpBand->hwndChild;
1884 infoPtr->uNumBands--;
1885 infoPtr->bands = COMCTL32_Alloc (sizeof (REBAR_BAND) * infoPtr->uNumBands);
1887 memcpy (&infoPtr->bands[0], &oldBands[0],
1888 uBand * sizeof(REBAR_BAND));
1891 if (uBand < infoPtr->uNumBands) {
1892 memcpy (&infoPtr->bands[uBand], &oldBands[uBand+1],
1893 (infoPtr->uNumBands - uBand) * sizeof(REBAR_BAND));
1896 COMCTL32_Free (oldBands);
1900 ShowWindow (childhwnd, SW_HIDE);
1902 REBAR_Notify_NMREBAR (hwnd, infoPtr, -1, RBN_DELETEDBAND);
1904 /* if only 1 band left the re-validate to possible eliminate gripper */
1905 if (infoPtr->uNumBands == 1)
1906 REBAR_ValidateBand (hwnd, infoPtr, &infoPtr->bands[0]);
1908 REBAR_Layout (hwnd, NULL, TRUE, FALSE);
1909 infoPtr->fStatus |= RESIZE_ANYHOW;
1910 REBAR_ForceResize (hwnd);
1911 REBAR_MoveChildWindows (hwnd);
1917 /* << REBAR_DragMove >> */
1918 /* << REBAR_EndDrag >> */
1922 REBAR_GetBandBorders (HWND hwnd, WPARAM wParam, LPARAM lParam)
1924 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1925 LPRECT lpRect = (LPRECT)lParam;
1927 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1931 if ((UINT)wParam >= infoPtr->uNumBands)
1934 lpBand = &infoPtr->bands[(UINT)wParam];
1936 /* FIXME - the following values were determined by experimentation */
1937 /* with the REBAR Control Spy. I have guesses as to what the 4 and */
1938 /* 1 are, but I am not sure. There doesn't seem to be any actual */
1939 /* difference in size of the control area with and without the */
1941 if (GetWindowLongA (hwnd, GWL_STYLE) & RBS_BANDBORDERS) {
1942 if (dwStyle & CCS_VERT) {
1944 lpRect->top = lpBand->cxHeader + 4;
1949 lpRect->left = lpBand->cxHeader + 4;
1956 lpRect->left = lpBand->cxHeader;
1963 inline static LRESULT
1964 REBAR_GetBandCount (HWND hwnd)
1966 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1968 TRACE("band count %u!\n", infoPtr->uNumBands);
1970 return infoPtr->uNumBands;
1975 REBAR_GetBandInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
1977 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
1978 LPREBARBANDINFOA lprbbi = (LPREBARBANDINFOA)lParam;
1983 if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEA)
1985 if ((UINT)wParam >= infoPtr->uNumBands)
1988 TRACE("index %u\n", (UINT)wParam);
1990 /* copy band information */
1991 lpBand = &infoPtr->bands[(UINT)wParam];
1993 if (lprbbi->fMask & RBBIM_STYLE)
1994 lprbbi->fStyle = lpBand->fStyle;
1996 if (lprbbi->fMask & RBBIM_COLORS) {
1997 lprbbi->clrFore = lpBand->clrFore;
1998 lprbbi->clrBack = lpBand->clrBack;
1999 if (lprbbi->clrBack == CLR_NONE)
2000 lprbbi->clrBack = GetSysColor (COLOR_BTNFACE);
2003 if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) {
2004 if (lpBand->lpText && (lpBand->fMask & RBBIM_TEXT))
2006 if (!WideCharToMultiByte( CP_ACP, 0, lpBand->lpText, -1,
2007 lprbbi->lpText, lprbbi->cch, NULL, NULL ))
2008 lprbbi->lpText[lprbbi->cch-1] = 0;
2011 *lprbbi->lpText = 0;
2014 if (lprbbi->fMask & RBBIM_IMAGE) {
2015 if (lpBand->fMask & RBBIM_IMAGE)
2016 lprbbi->iImage = lpBand->iImage;
2018 lprbbi->iImage = -1;
2021 if (lprbbi->fMask & RBBIM_CHILD)
2022 lprbbi->hwndChild = lpBand->hwndChild;
2024 if (lprbbi->fMask & RBBIM_CHILDSIZE) {
2025 lprbbi->cxMinChild = lpBand->cxMinChild;
2026 lprbbi->cyMinChild = lpBand->cyMinChild;
2027 if (lprbbi->cbSize >= sizeof (REBARBANDINFOA)) {
2028 lprbbi->cyChild = lpBand->cyChild;
2029 lprbbi->cyMaxChild = lpBand->cyMaxChild;
2030 lprbbi->cyIntegral = lpBand->cyIntegral;
2034 if (lprbbi->fMask & RBBIM_SIZE)
2035 lprbbi->cx = lpBand->cx;
2037 if (lprbbi->fMask & RBBIM_BACKGROUND)
2038 lprbbi->hbmBack = lpBand->hbmBack;
2040 if (lprbbi->fMask & RBBIM_ID)
2041 lprbbi->wID = lpBand->wID;
2043 /* check for additional data */
2044 if (lprbbi->cbSize >= sizeof (REBARBANDINFOA)) {
2045 if (lprbbi->fMask & RBBIM_IDEALSIZE)
2046 lprbbi->cxIdeal = lpBand->cxIdeal;
2048 if (lprbbi->fMask & RBBIM_LPARAM)
2049 lprbbi->lParam = lpBand->lParam;
2051 if (lprbbi->fMask & RBBIM_HEADERSIZE)
2052 lprbbi->cxHeader = lpBand->cxHeader;
2055 REBAR_DumpBandInfo (lprbbi);
2062 REBAR_GetBandInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2064 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2065 LPREBARBANDINFOW lprbbi = (LPREBARBANDINFOW)lParam;
2070 if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEW)
2072 if ((UINT)wParam >= infoPtr->uNumBands)
2075 TRACE("index %u\n", (UINT)wParam);
2077 /* copy band information */
2078 lpBand = &infoPtr->bands[(UINT)wParam];
2080 if (lprbbi->fMask & RBBIM_STYLE)
2081 lprbbi->fStyle = lpBand->fStyle;
2083 if (lprbbi->fMask & RBBIM_COLORS) {
2084 lprbbi->clrFore = lpBand->clrFore;
2085 lprbbi->clrBack = lpBand->clrBack;
2086 if (lprbbi->clrBack == CLR_NONE)
2087 lprbbi->clrBack = GetSysColor (COLOR_BTNFACE);
2090 if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) {
2091 if (lpBand->lpText && (lpBand->fMask & RBBIM_TEXT))
2092 lstrcpynW (lprbbi->lpText, lpBand->lpText, lprbbi->cch);
2094 *lprbbi->lpText = 0;
2097 if (lprbbi->fMask & RBBIM_IMAGE) {
2098 if (lpBand->fMask & RBBIM_IMAGE)
2099 lprbbi->iImage = lpBand->iImage;
2101 lprbbi->iImage = -1;
2104 if (lprbbi->fMask & RBBIM_CHILD)
2105 lprbbi->hwndChild = lpBand->hwndChild;
2107 if (lprbbi->fMask & RBBIM_CHILDSIZE) {
2108 lprbbi->cxMinChild = lpBand->cxMinChild;
2109 lprbbi->cyMinChild = lpBand->cyMinChild;
2110 if (lprbbi->cbSize >= sizeof (REBARBANDINFOW)) {
2111 lprbbi->cyChild = lpBand->cyChild;
2112 lprbbi->cyMaxChild = lpBand->cyMaxChild;
2113 lprbbi->cyIntegral = lpBand->cyIntegral;
2117 if (lprbbi->fMask & RBBIM_SIZE)
2118 lprbbi->cx = lpBand->cx;
2120 if (lprbbi->fMask & RBBIM_BACKGROUND)
2121 lprbbi->hbmBack = lpBand->hbmBack;
2123 if (lprbbi->fMask & RBBIM_ID)
2124 lprbbi->wID = lpBand->wID;
2126 /* check for additional data */
2127 if (lprbbi->cbSize >= sizeof (REBARBANDINFOW)) {
2128 if (lprbbi->fMask & RBBIM_IDEALSIZE)
2129 lprbbi->cxIdeal = lpBand->cxIdeal;
2131 if (lprbbi->fMask & RBBIM_LPARAM)
2132 lprbbi->lParam = lpBand->lParam;
2134 if (lprbbi->fMask & RBBIM_HEADERSIZE)
2135 lprbbi->cxHeader = lpBand->cxHeader;
2138 REBAR_DumpBandInfo ((LPREBARBANDINFOA)lprbbi);
2145 REBAR_GetBarHeight (HWND hwnd, WPARAM wParam, LPARAM lParam)
2147 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2149 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
2151 nHeight = (dwStyle & CCS_VERT) ? infoPtr->calcSize.cx : infoPtr->calcSize.cy;
2153 TRACE("height = %d\n", nHeight);
2160 REBAR_GetBarInfo (HWND hwnd, WPARAM wParam, LPARAM lParam)
2162 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2163 LPREBARINFO lpInfo = (LPREBARINFO)lParam;
2168 if (lpInfo->cbSize < sizeof (REBARINFO))
2171 TRACE("getting bar info!\n");
2173 if (infoPtr->himl) {
2174 lpInfo->himl = infoPtr->himl;
2175 lpInfo->fMask |= RBIM_IMAGELIST;
2182 inline static LRESULT
2183 REBAR_GetBkColor (HWND hwnd)
2185 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2186 COLORREF clr = infoPtr->clrBk;
2188 if (clr == CLR_NONE)
2189 clr = GetSysColor (COLOR_BTNFACE);
2191 TRACE("background color 0x%06lx!\n", clr);
2197 /* << REBAR_GetColorScheme >> */
2198 /* << REBAR_GetDropTarget >> */
2202 REBAR_GetPalette (HWND hwnd, WPARAM wParam, LPARAM lParam)
2204 FIXME("empty stub!\n");
2211 REBAR_GetRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
2213 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2214 INT iBand = (INT)wParam;
2215 LPRECT lprc = (LPRECT)lParam;
2218 if ((iBand < 0) && ((UINT)iBand >= infoPtr->uNumBands))
2223 lpBand = &infoPtr->bands[iBand];
2224 CopyRect (lprc, &lpBand->rcBand);
2226 TRACE("band %d, (%d,%d)-(%d,%d)\n", iBand,
2227 lprc->left, lprc->top, lprc->right, lprc->bottom);
2233 inline static LRESULT
2234 REBAR_GetRowCount (HWND hwnd)
2236 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2238 TRACE("%u\n", infoPtr->uNumRows);
2240 return infoPtr->uNumRows;
2245 REBAR_GetRowHeight (HWND hwnd, WPARAM wParam, LPARAM lParam)
2247 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2248 INT iRow = (INT)wParam;
2252 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
2254 for (i=0; i<infoPtr->uNumBands; i++) {
2255 lpBand = &infoPtr->bands[i];
2256 if (HIDDENBAND(lpBand)) continue;
2257 if (lpBand->iRow != iRow) continue;
2258 if (dwStyle & CCS_VERT)
2259 j = lpBand->rcBand.right - lpBand->rcBand.left;
2261 j = lpBand->rcBand.bottom - lpBand->rcBand.top;
2262 if (j > ret) ret = j;
2265 TRACE("row %d, height %d\n", iRow, ret);
2271 inline static LRESULT
2272 REBAR_GetTextColor (HWND hwnd)
2274 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2276 TRACE("text color 0x%06lx!\n", infoPtr->clrText);
2278 return infoPtr->clrText;
2282 inline static LRESULT
2283 REBAR_GetToolTips (HWND hwnd)
2285 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2286 return infoPtr->hwndToolTip;
2290 inline static LRESULT
2291 REBAR_GetUnicodeFormat (HWND hwnd)
2293 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2294 return infoPtr->bUnicode;
2298 inline static LRESULT
2299 REBAR_GetVersion (HWND hwnd)
2301 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2302 TRACE("version %d\n", infoPtr->iVersion);
2303 return infoPtr->iVersion;
2308 REBAR_HitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
2310 /* REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */
2311 LPRBHITTESTINFO lprbht = (LPRBHITTESTINFO)lParam;
2316 REBAR_InternalHitTest (hwnd, &lprbht->pt, &lprbht->flags, &lprbht->iBand);
2318 return lprbht->iBand;
2323 REBAR_IdToIndex (HWND hwnd, WPARAM wParam, LPARAM lParam)
2325 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2328 if (infoPtr == NULL)
2331 if (infoPtr->uNumBands < 1)
2334 for (i = 0; i < infoPtr->uNumBands; i++) {
2335 if (infoPtr->bands[i].wID == (UINT)wParam) {
2336 TRACE("id %u is band %u found!\n", (UINT)wParam, i);
2341 TRACE("id %u is not found\n", (UINT)wParam);
2347 REBAR_InsertBandA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2349 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2350 LPREBARBANDINFOA lprbbi = (LPREBARBANDINFOA)lParam;
2351 UINT uIndex = (UINT)wParam;
2354 if (infoPtr == NULL)
2358 if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEA)
2361 /* trace the index as signed to see the -1 */
2362 TRACE("insert band at %d!\n", (INT)uIndex);
2363 REBAR_DumpBandInfo (lprbbi);
2365 if (infoPtr->uNumBands == 0) {
2366 infoPtr->bands = (REBAR_BAND *)COMCTL32_Alloc (sizeof (REBAR_BAND));
2370 REBAR_BAND *oldBands = infoPtr->bands;
2372 (REBAR_BAND *)COMCTL32_Alloc ((infoPtr->uNumBands+1)*sizeof(REBAR_BAND));
2373 if (((INT)uIndex == -1) || (uIndex > infoPtr->uNumBands))
2374 uIndex = infoPtr->uNumBands;
2376 /* pre insert copy */
2378 memcpy (&infoPtr->bands[0], &oldBands[0],
2379 uIndex * sizeof(REBAR_BAND));
2383 if (uIndex < infoPtr->uNumBands - 1) {
2384 memcpy (&infoPtr->bands[uIndex+1], &oldBands[uIndex],
2385 (infoPtr->uNumBands - uIndex - 1) * sizeof(REBAR_BAND));
2388 COMCTL32_Free (oldBands);
2391 infoPtr->uNumBands++;
2393 TRACE("index %u!\n", uIndex);
2395 /* initialize band (infoPtr->bands[uIndex])*/
2396 lpBand = &infoPtr->bands[uIndex];
2398 lpBand->fStatus = 0;
2399 lpBand->clrFore = infoPtr->clrText;
2400 lpBand->clrBack = infoPtr->clrBk;
2401 lpBand->hwndChild = 0;
2402 lpBand->hwndPrevParent = 0;
2404 REBAR_CommonSetupBand (hwnd, lprbbi, lpBand);
2405 lpBand->lpText = NULL;
2406 if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) {
2407 INT len = MultiByteToWideChar( CP_ACP, 0, lprbbi->lpText, -1, NULL, 0 );
2409 lpBand->lpText = (LPWSTR)COMCTL32_Alloc (len*sizeof(WCHAR));
2410 MultiByteToWideChar( CP_ACP, 0, lprbbi->lpText, -1, lpBand->lpText, len );
2414 REBAR_ValidateBand (hwnd, infoPtr, lpBand);
2415 /* On insert of second band, revalidate band 1 to possible add gripper */
2416 if (infoPtr->uNumBands == 2)
2417 REBAR_ValidateBand (hwnd, infoPtr, &infoPtr->bands[0]);
2419 REBAR_DumpBand (hwnd);
2421 REBAR_Layout (hwnd, NULL, TRUE, FALSE);
2422 REBAR_ForceResize (hwnd);
2423 REBAR_MoveChildWindows (hwnd);
2430 REBAR_InsertBandW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2432 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2433 LPREBARBANDINFOW lprbbi = (LPREBARBANDINFOW)lParam;
2434 UINT uIndex = (UINT)wParam;
2437 if (infoPtr == NULL)
2441 if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEW)
2444 /* trace the index as signed to see the -1 */
2445 TRACE("insert band at %d!\n", (INT)uIndex);
2446 REBAR_DumpBandInfo ((LPREBARBANDINFOA)lprbbi);
2448 if (infoPtr->uNumBands == 0) {
2449 infoPtr->bands = (REBAR_BAND *)COMCTL32_Alloc (sizeof (REBAR_BAND));
2453 REBAR_BAND *oldBands = infoPtr->bands;
2455 (REBAR_BAND *)COMCTL32_Alloc ((infoPtr->uNumBands+1)*sizeof(REBAR_BAND));
2456 if (((INT)uIndex == -1) || (uIndex > infoPtr->uNumBands))
2457 uIndex = infoPtr->uNumBands;
2459 /* pre insert copy */
2461 memcpy (&infoPtr->bands[0], &oldBands[0],
2462 uIndex * sizeof(REBAR_BAND));
2466 if (uIndex < infoPtr->uNumBands - 1) {
2467 memcpy (&infoPtr->bands[uIndex+1], &oldBands[uIndex],
2468 (infoPtr->uNumBands - uIndex - 1) * sizeof(REBAR_BAND));
2471 COMCTL32_Free (oldBands);
2474 infoPtr->uNumBands++;
2476 TRACE("index %u!\n", uIndex);
2478 /* initialize band (infoPtr->bands[uIndex])*/
2479 lpBand = &infoPtr->bands[uIndex];
2481 lpBand->fStatus = 0;
2482 lpBand->clrFore = infoPtr->clrText;
2483 lpBand->clrBack = infoPtr->clrBk;
2484 lpBand->hwndChild = 0;
2485 lpBand->hwndPrevParent = 0;
2487 REBAR_CommonSetupBand (hwnd, (LPREBARBANDINFOA)lprbbi, lpBand);
2488 lpBand->lpText = NULL;
2489 if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) {
2490 INT len = lstrlenW (lprbbi->lpText);
2492 lpBand->lpText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
2493 strcpyW (lpBand->lpText, lprbbi->lpText);
2497 REBAR_ValidateBand (hwnd, infoPtr, lpBand);
2498 /* On insert of second band, revalidate band 1 to possible add gripper */
2499 if (infoPtr->uNumBands == 2)
2500 REBAR_ValidateBand (hwnd, infoPtr, &infoPtr->bands[0]);
2502 REBAR_DumpBand (hwnd);
2504 REBAR_Layout (hwnd, NULL, TRUE, FALSE);
2505 REBAR_ForceResize (hwnd);
2506 REBAR_MoveChildWindows (hwnd);
2513 REBAR_MaximizeBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
2515 /* REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */
2517 FIXME("(uBand = %u fIdeal = %s) stub\n",
2518 (UINT)wParam, lParam ? "TRUE" : "FALSE");
2526 REBAR_MinimizeBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
2528 /* REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */
2530 FIXME("(uBand = %u) stub\n", (UINT)wParam);
2538 REBAR_MoveBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
2540 /* REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */
2542 FIXME("(iFrom = %u iTof = %u) stub\n",
2543 (UINT)wParam, (UINT)lParam);
2551 REBAR_SetBandInfoA (HWND hwnd, WPARAM wParam, LPARAM lParam)
2553 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2554 LPREBARBANDINFOA lprbbi = (LPREBARBANDINFOA)lParam;
2559 if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEA)
2561 if ((UINT)wParam >= infoPtr->uNumBands)
2564 TRACE("index %u\n", (UINT)wParam);
2565 REBAR_DumpBandInfo (lprbbi);
2567 /* set band information */
2568 lpBand = &infoPtr->bands[(UINT)wParam];
2570 REBAR_CommonSetupBand (hwnd, lprbbi, lpBand);
2571 if (lprbbi->fMask & RBBIM_TEXT) {
2572 if (lpBand->lpText) {
2573 COMCTL32_Free (lpBand->lpText);
2574 lpBand->lpText = NULL;
2576 if (lprbbi->lpText) {
2577 INT len = MultiByteToWideChar( CP_ACP, 0, lprbbi->lpText, -1, NULL, 0 );
2578 lpBand->lpText = (LPWSTR)COMCTL32_Alloc (len*sizeof(WCHAR));
2579 MultiByteToWideChar( CP_ACP, 0, lprbbi->lpText, -1, lpBand->lpText, len );
2583 REBAR_ValidateBand (hwnd, infoPtr, lpBand);
2585 REBAR_DumpBand (hwnd);
2587 if (lprbbi->fMask & (RBBIM_CHILDSIZE | RBBIM_SIZE)) {
2588 REBAR_Layout (hwnd, NULL, TRUE, FALSE);
2589 REBAR_ForceResize (hwnd);
2590 REBAR_MoveChildWindows (hwnd);
2598 REBAR_SetBandInfoW (HWND hwnd, WPARAM wParam, LPARAM lParam)
2600 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2601 LPREBARBANDINFOW lprbbi = (LPREBARBANDINFOW)lParam;
2606 if (lprbbi->cbSize < REBARBANDINFO_V3_SIZEW)
2608 if ((UINT)wParam >= infoPtr->uNumBands)
2611 TRACE("index %u\n", (UINT)wParam);
2612 REBAR_DumpBandInfo ((LPREBARBANDINFOA)lprbbi);
2614 /* set band information */
2615 lpBand = &infoPtr->bands[(UINT)wParam];
2617 REBAR_CommonSetupBand (hwnd, (LPREBARBANDINFOA)lprbbi, lpBand);
2618 if (lprbbi->fMask & RBBIM_TEXT) {
2619 if (lpBand->lpText) {
2620 COMCTL32_Free (lpBand->lpText);
2621 lpBand->lpText = NULL;
2623 if (lprbbi->lpText) {
2624 INT len = lstrlenW (lprbbi->lpText);
2625 lpBand->lpText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
2626 strcpyW (lpBand->lpText, lprbbi->lpText);
2630 REBAR_ValidateBand (hwnd, infoPtr, lpBand);
2632 REBAR_DumpBand (hwnd);
2634 if (lprbbi->fMask & (RBBIM_CHILDSIZE | RBBIM_SIZE)) {
2635 REBAR_Layout (hwnd, NULL, TRUE, FALSE);
2636 REBAR_ForceResize (hwnd);
2637 REBAR_MoveChildWindows (hwnd);
2645 REBAR_SetBarInfo (HWND hwnd, WPARAM wParam, LPARAM lParam)
2647 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2648 LPREBARINFO lpInfo = (LPREBARINFO)lParam;
2655 if (lpInfo->cbSize < sizeof (REBARINFO))
2658 TRACE("setting bar info!\n");
2660 if (lpInfo->fMask & RBIM_IMAGELIST) {
2661 infoPtr->himl = lpInfo->himl;
2662 if (infoPtr->himl) {
2664 ImageList_GetIconSize (infoPtr->himl, &cx, &cy);
2665 infoPtr->imageSize.cx = cx;
2666 infoPtr->imageSize.cy = cy;
2669 infoPtr->imageSize.cx = 0;
2670 infoPtr->imageSize.cy = 0;
2672 TRACE("new image cx=%ld, cy=%ld\n", infoPtr->imageSize.cx,
2673 infoPtr->imageSize.cy);
2676 /* revalidate all bands to reset flags for images in headers of bands */
2677 for (i=0; i<infoPtr->uNumBands; i++) {
2678 lpBand = &infoPtr->bands[i];
2679 REBAR_ValidateBand (hwnd, infoPtr, lpBand);
2687 REBAR_SetBkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
2689 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2692 clrTemp = infoPtr->clrBk;
2693 infoPtr->clrBk = (COLORREF)lParam;
2695 TRACE("background color 0x%06lx!\n", infoPtr->clrBk);
2701 /* << REBAR_SetColorScheme >> */
2702 /* << REBAR_SetPalette >> */
2706 REBAR_SetParent (HWND hwnd, WPARAM wParam, LPARAM lParam)
2708 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2709 HWND hwndTemp = infoPtr->hwndNotify;
2711 infoPtr->hwndNotify = (HWND)wParam;
2713 return (LRESULT)hwndTemp;
2718 REBAR_SetTextColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
2720 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2723 clrTemp = infoPtr->clrText;
2724 infoPtr->clrText = (COLORREF)lParam;
2726 TRACE("text color 0x%06lx!\n", infoPtr->clrText);
2732 /* << REBAR_SetTooltips >> */
2735 inline static LRESULT
2736 REBAR_SetUnicodeFormat (HWND hwnd, WPARAM wParam)
2738 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2739 BOOL bTemp = infoPtr->bUnicode;
2740 infoPtr->bUnicode = (BOOL)wParam;
2746 REBAR_SetVersion (HWND hwnd, INT iVersion)
2748 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2749 INT iOldVersion = infoPtr->iVersion;
2751 if (iVersion > COMCTL32_VERSION)
2754 infoPtr->iVersion = iVersion;
2756 TRACE("new version %d\n", iVersion);
2763 REBAR_ShowBand (HWND hwnd, WPARAM wParam, LPARAM lParam)
2765 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2768 if (((INT)wParam < 0) || ((INT)wParam > infoPtr->uNumBands))
2771 lpBand = &infoPtr->bands[(INT)wParam];
2774 TRACE("show band %d\n", (INT)wParam);
2775 lpBand->fStyle = lpBand->fStyle & ~RBBS_HIDDEN;
2776 if (IsWindow (lpBand->hwndChild))
2777 ShowWindow (lpBand->hwndChild, SW_SHOW);
2780 TRACE("hide band %d\n", (INT)wParam);
2781 lpBand->fStyle = lpBand->fStyle | RBBS_HIDDEN;
2782 if (IsWindow (lpBand->hwndChild))
2783 ShowWindow (lpBand->hwndChild, SW_HIDE);
2786 REBAR_Layout (hwnd, NULL, TRUE, FALSE);
2787 REBAR_ForceResize (hwnd);
2788 REBAR_MoveChildWindows (hwnd);
2795 REBAR_SizeToRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
2797 LPRECT lpRect = (LPRECT)lParam;
2803 TRACE("[%d %d %d %d]\n",
2804 lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
2806 /* what is going on???? */
2807 GetWindowRect(hwnd, &t1);
2808 TRACE("window rect [%d %d %d %d]\n",
2809 t1.left, t1.top, t1.right, t1.bottom);
2810 GetClientRect(hwnd, &t1);
2811 TRACE("client rect [%d %d %d %d]\n",
2812 t1.left, t1.top, t1.right, t1.bottom);
2814 REBAR_Layout (hwnd, lpRect, TRUE, FALSE);
2815 REBAR_ForceResize (hwnd);
2816 REBAR_MoveChildWindows (hwnd);
2823 REBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
2825 REBAR_INFO *infoPtr;
2827 /* allocate memory for info structure */
2828 infoPtr = (REBAR_INFO *)COMCTL32_Alloc (sizeof(REBAR_INFO));
2829 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
2831 /* initialize info structure - initial values are 0 */
2832 infoPtr->clrBk = CLR_NONE;
2833 infoPtr->clrText = GetSysColor (COLOR_BTNTEXT);
2834 infoPtr->ihitBand = -1;
2836 infoPtr->hcurArrow = LoadCursorA (0, IDC_ARROWA);
2837 infoPtr->hcurHorz = LoadCursorA (0, IDC_SIZEWEA);
2838 infoPtr->hcurVert = LoadCursorA (0, IDC_SIZENSA);
2839 infoPtr->hcurDrag = LoadCursorA (0, IDC_SIZEA);
2841 infoPtr->bUnicode = IsWindowUnicode (hwnd);
2843 if (GetWindowLongA (hwnd, GWL_STYLE) & RBS_AUTOSIZE)
2844 FIXME("style RBS_AUTOSIZE set!\n");
2847 SendMessageA (hwnd, WM_NOTIFYFORMAT, (WPARAM)hwnd, NF_QUERY);
2850 TRACE("created!\n");
2856 REBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
2858 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2863 /* free rebar bands */
2864 if ((infoPtr->uNumBands > 0) && infoPtr->bands) {
2865 /* clean up each band */
2866 for (i = 0; i < infoPtr->uNumBands; i++) {
2867 lpBand = &infoPtr->bands[i];
2869 /* delete text strings */
2870 if (lpBand->lpText) {
2871 COMCTL32_Free (lpBand->lpText);
2872 lpBand->lpText = NULL;
2874 /* destroy child window */
2875 DestroyWindow (lpBand->hwndChild);
2878 /* free band array */
2879 COMCTL32_Free (infoPtr->bands);
2880 infoPtr->bands = NULL;
2883 DeleteObject (infoPtr->hcurArrow);
2884 DeleteObject (infoPtr->hcurHorz);
2885 DeleteObject (infoPtr->hcurVert);
2886 DeleteObject (infoPtr->hcurDrag);
2888 /* free rebar info data */
2889 COMCTL32_Free (infoPtr);
2890 SetWindowLongA (hwnd, 0, 0);
2891 TRACE("destroyed!\n");
2897 REBAR_EraseBkGnd (HWND hwnd, WPARAM wParam, LPARAM lParam)
2901 if (GetClipBox ( (HDC)wParam, &cliprect))
2902 return REBAR_InternalEraseBkGnd (hwnd, wParam, lParam, &cliprect);
2908 REBAR_GetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
2910 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2912 return (LRESULT)infoPtr->hFont;
2917 REBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
2919 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2921 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
2923 /* If InternalHitTest did not find a hit on the Gripper, */
2924 /* then ignore the button click. */
2925 if (infoPtr->ihitBand == -1) return 0;
2929 /* save off the LOWORD and HIWORD of lParam as initial x,y */
2930 lpBand = &infoPtr->bands[infoPtr->ihitBand];
2931 infoPtr->dragStart = MAKEPOINTS(lParam);
2932 infoPtr->dragNow = infoPtr->dragStart;
2933 if (dwStyle & CCS_VERT)
2934 infoPtr->ihitoffset = infoPtr->dragStart.y - (lpBand->rcBand.top+REBAR_PRE_GRIPPER);
2936 infoPtr->ihitoffset = infoPtr->dragStart.x - (lpBand->rcBand.left+REBAR_PRE_GRIPPER);
2943 REBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
2945 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2949 /* If InternalHitTest did not find a hit on the Gripper, */
2950 /* then ignore the button click. */
2951 if (infoPtr->ihitBand == -1) return 0;
2953 infoPtr->dragStart.x = 0;
2954 infoPtr->dragStart.y = 0;
2955 infoPtr->dragNow = infoPtr->dragStart;
2956 infoPtr->ihitBand = -1;
2960 if (infoPtr->fStatus & BEGIN_DRAG_ISSUED) {
2961 REBAR_Notify(hwnd, (NMHDR *) &layout, infoPtr, RBN_LAYOUTCHANGED);
2962 REBAR_Notify_NMREBAR (hwnd, infoPtr, -1, RBN_ENDDRAG);
2963 infoPtr->fStatus &= ~BEGIN_DRAG_ISSUED;
2966 GetClientRect(hwnd, &rect);
2967 InvalidateRect(hwnd, NULL, TRUE);
2974 REBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
2976 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
2977 REBAR_BAND *band1, *band2;
2979 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
2981 /* Validate entry as hit on Gripper has occured */
2982 if (GetCapture() != hwnd) return 0;
2983 if (infoPtr->ihitBand == -1) return 0;
2985 ptsmove = MAKEPOINTS(lParam);
2987 /* if mouse did not move much, exit */
2988 if ((abs(ptsmove.x - infoPtr->dragNow.x) <= mindragx) &&
2989 (abs(ptsmove.y - infoPtr->dragNow.y) <= mindragy)) return 0;
2991 band1 = &infoPtr->bands[infoPtr->ihitBand-1];
2992 band2 = &infoPtr->bands[infoPtr->ihitBand];
2994 /* Test for valid drag case - must not be first band in row */
2995 if (dwStyle & CCS_VERT) {
2996 if ((ptsmove.x < band2->rcBand.left) ||
2997 (ptsmove.x > band2->rcBand.right) ||
2998 ((infoPtr->ihitBand > 0) && (band1->iRow != band2->iRow))) {
2999 FIXME("Cannot drag to other rows yet!!\n");
3002 REBAR_HandleLRDrag (hwnd, infoPtr, &ptsmove, dwStyle);
3006 if ((ptsmove.y < band2->rcBand.top) ||
3007 (ptsmove.y > band2->rcBand.bottom) ||
3008 ((infoPtr->ihitBand > 0) && (band1->iRow != band2->iRow))) {
3009 FIXME("Cannot drag to other rows yet!!\n");
3012 REBAR_HandleLRDrag (hwnd, infoPtr, &ptsmove, dwStyle);
3019 inline static LRESULT
3020 REBAR_NCCalcSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
3022 if (GetWindowLongA (hwnd, GWL_STYLE) & WS_BORDER) {
3023 ((LPRECT)lParam)->left += GetSystemMetrics(SM_CXEDGE);
3024 ((LPRECT)lParam)->top += GetSystemMetrics(SM_CYEDGE);
3025 ((LPRECT)lParam)->right -= GetSystemMetrics(SM_CXEDGE);
3026 ((LPRECT)lParam)->bottom -= GetSystemMetrics(SM_CYEDGE);
3034 REBAR_NCPaint (HWND hwnd, WPARAM wParam, LPARAM lParam)
3036 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3040 if (dwStyle & WS_MINIMIZE)
3041 return 0; /* Nothing to do */
3043 DefWindowProcA (hwnd, WM_NCPAINT, wParam, lParam);
3045 if (!(hdc = GetDCEx( hwnd, 0, DCX_USESTYLE | DCX_WINDOW )))
3048 if (dwStyle & WS_BORDER) {
3049 GetWindowRect (hwnd, &rcWindow);
3050 OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
3051 DrawEdge (hdc, &rcWindow, EDGE_ETCHED, BF_RECT);
3054 ReleaseDC( hwnd, hdc );
3061 REBAR_Paint (HWND hwnd, WPARAM wParam, LPARAM lParam)
3066 hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
3068 TRACE("painting (%d,%d)-(%d,%d)\n",
3069 ps.rcPaint.left, ps.rcPaint.top,
3070 ps.rcPaint.right, ps.rcPaint.bottom);
3073 /* Erase area of paint if requested */
3074 REBAR_InternalEraseBkGnd (hwnd, wParam, lParam, &ps.rcPaint);
3077 REBAR_Refresh (hwnd, hdc);
3079 EndPaint (hwnd, &ps);
3085 REBAR_SetCursor (HWND hwnd, WPARAM wParam, LPARAM lParam)
3087 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
3088 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
3092 TRACE("code=0x%X id=0x%X\n", LOWORD(lParam), HIWORD(lParam));
3095 ScreenToClient (hwnd, &pt);
3097 REBAR_InternalHitTest (hwnd, &pt, &flags, NULL);
3099 if (flags == RBHT_GRABBER) {
3100 if ((dwStyle & CCS_VERT) &&
3101 !(dwStyle & RBS_VERTICALGRIPPER))
3102 SetCursor (infoPtr->hcurVert);
3104 SetCursor (infoPtr->hcurHorz);
3106 else if (flags != RBHT_CLIENT)
3107 SetCursor (infoPtr->hcurArrow);
3114 REBAR_SetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
3116 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
3121 infoPtr->hFont = (HFONT)wParam;
3123 /* revalidate all bands to change sizes of text in headers of bands */
3124 for (i=0; i<infoPtr->uNumBands; i++) {
3125 lpBand = &infoPtr->bands[i];
3126 REBAR_ValidateBand (hwnd, infoPtr, lpBand);
3131 GetClientRect (hwnd, &rcClient);
3132 REBAR_Layout (hwnd, &rcClient, FALSE, TRUE);
3133 REBAR_ForceResize (hwnd);
3134 REBAR_MoveChildWindows (hwnd);
3142 REBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
3144 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd);
3147 /* auto resize deadlock check */
3148 if (infoPtr->fStatus & AUTO_RESIZE) {
3149 infoPtr->fStatus &= ~AUTO_RESIZE;
3150 TRACE("AUTO_RESIZE was set, reset, fStatus=%08x\n",
3155 GetClientRect (hwnd, &rcClient);
3156 if ((lParam == 0) && (rcClient.right == 0) && (rcClient.bottom == 0)) {
3157 /* native control seems to do this */
3158 GetClientRect (GetParent(hwnd), &rcClient);
3159 TRACE("sizing rebar, message and client zero, parent client (%d,%d)\n",
3160 rcClient.right, rcClient.bottom);
3163 TRACE("sizing rebar from (%ld,%ld) to (%d,%d), client (%d,%d)\n",
3164 infoPtr->calcSize.cx, infoPtr->calcSize.cy,
3165 LOWORD(lParam), HIWORD(lParam),
3166 rcClient.right, rcClient.bottom);
3169 REBAR_Layout (hwnd, &rcClient, TRUE, TRUE);
3170 REBAR_ForceResize (hwnd);
3171 infoPtr->fStatus &= ~AUTO_RESIZE;
3172 REBAR_MoveChildWindows (hwnd);
3178 static LRESULT WINAPI
3179 REBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
3181 TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n", hwnd, uMsg, wParam, lParam);
3182 if (!REBAR_GetInfoPtr (hwnd) && (uMsg != WM_CREATE))
3183 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
3186 /* case RB_BEGINDRAG: */
3189 return REBAR_DeleteBand (hwnd, wParam, lParam);
3191 /* case RB_DRAGMOVE: */
3192 /* case RB_ENDDRAG: */
3194 case RB_GETBANDBORDERS:
3195 return REBAR_GetBandBorders (hwnd, wParam, lParam);
3197 case RB_GETBANDCOUNT:
3198 return REBAR_GetBandCount (hwnd);
3200 case RB_GETBANDINFO: /* obsoleted after IE3, but we have to
3201 support it anyway. */
3202 case RB_GETBANDINFOA:
3203 return REBAR_GetBandInfoA (hwnd, wParam, lParam);
3205 case RB_GETBANDINFOW:
3206 return REBAR_GetBandInfoW (hwnd, wParam, lParam);
3208 case RB_GETBARHEIGHT:
3209 return REBAR_GetBarHeight (hwnd, wParam, lParam);
3212 return REBAR_GetBarInfo (hwnd, wParam, lParam);
3215 return REBAR_GetBkColor (hwnd);
3217 /* case RB_GETCOLORSCHEME: */
3218 /* case RB_GETDROPTARGET: */
3221 return REBAR_GetPalette (hwnd, wParam, lParam);
3224 return REBAR_GetRect (hwnd, wParam, lParam);
3226 case RB_GETROWCOUNT:
3227 return REBAR_GetRowCount (hwnd);
3229 case RB_GETROWHEIGHT:
3230 return REBAR_GetRowHeight (hwnd, wParam, lParam);
3232 case RB_GETTEXTCOLOR:
3233 return REBAR_GetTextColor (hwnd);
3235 case RB_GETTOOLTIPS:
3236 return REBAR_GetToolTips (hwnd);
3238 case RB_GETUNICODEFORMAT:
3239 return REBAR_GetUnicodeFormat (hwnd);
3241 case CCM_GETVERSION:
3242 return REBAR_GetVersion (hwnd);
3245 return REBAR_HitTest (hwnd, wParam, lParam);
3248 return REBAR_IdToIndex (hwnd, wParam, lParam);
3250 case RB_INSERTBANDA:
3251 return REBAR_InsertBandA (hwnd, wParam, lParam);
3253 case RB_INSERTBANDW:
3254 return REBAR_InsertBandW (hwnd, wParam, lParam);
3256 case RB_MAXIMIZEBAND:
3257 return REBAR_MaximizeBand (hwnd, wParam, lParam);
3259 case RB_MINIMIZEBAND:
3260 return REBAR_MinimizeBand (hwnd, wParam, lParam);
3263 return REBAR_MoveBand (hwnd, wParam, lParam);
3265 case RB_SETBANDINFOA:
3266 return REBAR_SetBandInfoA (hwnd, wParam, lParam);
3268 case RB_SETBANDINFOW:
3269 return REBAR_SetBandInfoW (hwnd, wParam, lParam);
3272 return REBAR_SetBarInfo (hwnd, wParam, lParam);
3275 return REBAR_SetBkColor (hwnd, wParam, lParam);
3277 /* case RB_SETCOLORSCHEME: */
3278 /* case RB_SETPALETTE: */
3279 /* return REBAR_GetPalette (hwnd, wParam, lParam); */
3282 return REBAR_SetParent (hwnd, wParam, lParam);
3284 case RB_SETTEXTCOLOR:
3285 return REBAR_SetTextColor (hwnd, wParam, lParam);
3287 /* case RB_SETTOOLTIPS: */
3289 case RB_SETUNICODEFORMAT:
3290 return REBAR_SetUnicodeFormat (hwnd, wParam);
3292 case CCM_SETVERSION:
3293 return REBAR_SetVersion (hwnd, (INT)wParam);
3296 return REBAR_ShowBand (hwnd, wParam, lParam);
3299 return REBAR_SizeToRect (hwnd, wParam, lParam);
3302 /* Messages passed to parent */
3306 return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
3309 /* case WM_CHARTOITEM: supported according to ControlSpy */
3312 return REBAR_Create (hwnd, wParam, lParam);
3315 return REBAR_Destroy (hwnd, wParam, lParam);
3318 return REBAR_EraseBkGnd (hwnd, wParam, lParam);
3321 return REBAR_GetFont (hwnd, wParam, lParam);
3323 /* case WM_LBUTTONDBLCLK: supported according to ControlSpy */
3325 case WM_LBUTTONDOWN:
3326 return REBAR_LButtonDown (hwnd, wParam, lParam);
3329 return REBAR_LButtonUp (hwnd, wParam, lParam);
3331 /* case WM_MEASUREITEM: supported according to ControlSpy */
3334 return REBAR_MouseMove (hwnd, wParam, lParam);
3337 return REBAR_NCCalcSize (hwnd, wParam, lParam);
3339 /* case WM_NCCREATE: supported according to ControlSpy */
3340 /* case WM_NCHITTEST: supported according to ControlSpy */
3343 return REBAR_NCPaint (hwnd, wParam, lParam);
3345 /* case WM_NOTIFYFORMAT: supported according to ControlSpy */
3348 return REBAR_Paint (hwnd, wParam, lParam);
3350 /* case WM_PALETTECHANGED: supported according to ControlSpy */
3351 /* case WM_PRINTCLIENT: supported according to ControlSpy */
3352 /* case WM_QUERYNEWPALETTE:supported according to ControlSpy */
3353 /* case WM_RBUTTONDOWN: supported according to ControlSpy */
3354 /* case WM_RBUTTONUP: supported according to ControlSpy */
3357 return REBAR_SetCursor (hwnd, wParam, lParam);
3360 return REBAR_SetFont (hwnd, wParam, lParam);
3362 /* case WM_SETREDRAW: supported according to ControlSpy */
3365 return REBAR_Size (hwnd, wParam, lParam);
3367 /* case WM_STYLECHANGED: supported according to ControlSpy */
3368 /* case WM_SYSCOLORCHANGE: supported according to ControlSpy */
3369 /* case WM_VKEYTOITEM: supported according to ControlSpy */
3370 /* case WM_WININICHANGE: */
3373 if (uMsg >= WM_USER)
3374 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
3375 uMsg, wParam, lParam);
3376 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
3383 REBAR_Register (void)
3387 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
3388 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
3389 wndClass.lpfnWndProc = (WNDPROC)REBAR_WindowProc;
3390 wndClass.cbClsExtra = 0;
3391 wndClass.cbWndExtra = sizeof(REBAR_INFO *);
3392 wndClass.hCursor = 0;
3393 wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
3394 wndClass.lpszClassName = REBARCLASSNAMEA;
3396 RegisterClassA (&wndClass);
3398 mindragx = GetSystemMetrics (SM_CXDRAG);
3399 mindragy = GetSystemMetrics (SM_CYDRAG);
3405 REBAR_Unregister (void)
3407 UnregisterClassA (REBARCLASSNAMEA, (HINSTANCE)NULL);