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 * 1. Support dragging by the Gripper for only left and right drags
28 * 2. Implement WM_LBUTTONDOWN, WM_LBUTTONUP, and WM_MOUSEMOVE.
29 * 3. Support RBS_BANDBORDERS.
30 * 4. Total rewrite of MouseMove code to handle multiple bands in row. (5b)
31 * 5. Fix drawing bugs.
34 * 1. default row height should be the max height of all visible bands
35 * 2. Following still not handled: RBBS_FIXEDBMP, RBBS_CHILDEDGE,
36 * RBBS_VARIABLEHEIGHT, RBBS_USECHEVRON
37 * 3. GETBANDINFO seems to return correct colors in native but not here.
46 #include "wine/unicode.h"
48 #include "debugtools.h"
50 DEFAULT_DEBUG_CHANNEL(rebar
);
72 UINT lcx
; /* minimum cx for band */
73 UINT hcx
; /* maximum cx for band */
74 UINT lcy
; /* minimum cy for band */
75 UINT hcy
; /* maximum cy for band */
77 SIZE offChild
; /* x,y offset if child is not FIXEDSIZE */
79 INT iRow
; /* row this band assigned to */
80 UINT fDraw
; /* drawing flags */
81 RECT rcBand
; /* calculated band rectangle */
82 RECT rcGripper
; /* calculated gripper rectangle */
83 RECT rcCapImage
; /* calculated caption image rectangle */
84 RECT rcCapText
; /* calculated caption text rectangle */
85 RECT rcChild
; /* calculated child rectangle */
92 #define DRAW_GRIPPER 1
101 COLORREF clrBk
; /* background color */
102 COLORREF clrText
; /* text color */
103 HIMAGELIST himl
; /* handle to imagelist */
104 UINT uNumBands
; /* number of bands in the rebar */
105 UINT uNumRows
; /* number of rows of bands */
106 HWND hwndToolTip
; /* handle to the tool tip control */
107 HWND hwndNotify
; /* notification window (parent) */
108 HFONT hFont
; /* handle to the rebar's font */
109 SIZE imageSize
; /* image size (image list) */
111 SIZE calcSize
; /* calculated rebar size */
112 BOOL bUnicode
; /* Unicode flag */
113 UINT fStatus
; /* Status flags (see below) */
114 HCURSOR hcurArrow
; /* handle to the arrow cursor */
115 HCURSOR hcurHorz
; /* handle to the EW cursor */
116 HCURSOR hcurVert
; /* handle to the NS cursor */
117 HCURSOR hcurDrag
; /* handle to the drag cursor */
118 INT iVersion
; /* version number */
119 POINTS dragStart
; /* x,y of button down */
120 POINTS dragNow
; /* x,y of this MouseMove */
121 INT ihitBand
; /* band number of band whose gripper was grabbed */
122 INT ihitoffset
; /* offset of hotspot from gripper.left */
124 REBAR_BAND
*bands
; /* pointer to the array of rebar bands */
128 #define BEGIN_DRAG_ISSUED 1
129 #define AUTO_RESIZE 2
132 #define GRIPPER_WIDTH 8
133 #define GRIPPER_HEIGHT 16
136 /* This is the increment that is used over the band height */
137 /* Determined by experiment. */
140 #define REBAR_GetInfoPtr(wndPtr) ((REBAR_INFO *)GetWindowLongA (hwnd, 0))
143 /* "constant values" retrieved when DLL was initialized */
144 /* FIXME we do this when the classes are registered. */
145 static UINT mindragx
= 0;
146 static UINT mindragy
= 0;
150 REBAR_DumpBandInfo( LPREBARBANDINFOA pB
)
152 TRACE("band info: ID=%u, size=%u, style=0x%08x, mask=0x%08x, child=%04x\n",
153 pB
->wID
, pB
->cbSize
, pB
->fStyle
, pB
->fMask
, pB
->hwndChild
);
154 TRACE("band info: cx=%u, xMin=%u, yMin=%u, yChild=%u, yMax=%u, yIntgl=%u\n",
155 pB
->cx
, pB
->cxMinChild
,
156 pB
->cyMinChild
, pB
->cyChild
, pB
->cyMaxChild
, pB
->cyIntegral
);
157 TRACE("band info: xIdeal=%u, xHeader=%u, lParam=0x%08lx, clrF=0x%06lx, clrB=0x%06lx\n",
158 pB
->cxIdeal
, pB
->cxHeader
, pB
->lParam
, pB
->clrFore
, pB
->clrBack
);
162 REBAR_DumpBand (HWND hwnd
)
164 REBAR_INFO
*iP
= REBAR_GetInfoPtr (hwnd
);
168 if( TRACE_ON(rebar
) ) {
170 TRACE("hwnd=%04x: color=%08lx/%08lx, bands=%u, rows=%u, cSize=%ld,%ld\n",
171 hwnd
, iP
->clrText
, iP
->clrBk
, iP
->uNumBands
, iP
->uNumRows
,
172 iP
->calcSize
.cx
, iP
->calcSize
.cy
);
173 TRACE("hwnd=%04x: flags=%08x, dragStart=%d,%d, dragNow=%d,%d, ihitBand=%d\n",
174 hwnd
, iP
->fStatus
, iP
->dragStart
.x
, iP
->dragStart
.y
,
175 iP
->dragNow
.x
, iP
->dragNow
.y
,
177 for (i
= 0; i
< iP
->uNumBands
; i
++) {
179 TRACE("band # %u: ID=%u, mask=0x%08x, style=0x%08x, child=%04x, row=%u\n",
180 i
, pB
->wID
, pB
->fMask
, pB
->fStyle
, pB
->hwndChild
, pB
->iRow
);
181 TRACE("band # %u: xMin=%u, yMin=%u, cx=%u, yChild=%u, yMax=%u, yIntgl=%u, uMinH=%u,\n",
182 i
, pB
->cxMinChild
, pB
->cyMinChild
, pB
->cx
,
183 pB
->cyChild
, pB
->cyMaxChild
, pB
->cyIntegral
, pB
->uMinHeight
);
184 TRACE("band # %u: header=%u, lcx=%u, hcx=%u, lcy=%u, hcy=%u, offChild=%ld,%ld\n",
185 i
, pB
->cxHeader
, pB
->lcx
, pB
->hcx
, pB
->lcy
, pB
->hcy
, pB
->offChild
.cx
, pB
->offChild
.cy
);
186 TRACE("band # %u: fDraw=%08x, Band=(%d,%d)-(%d,%d), Grip=(%d,%d)-(%d,%d)\n",
188 pB
->rcBand
.left
, pB
->rcBand
.top
, pB
->rcBand
.right
, pB
->rcBand
.bottom
,
189 pB
->rcGripper
.left
, pB
->rcGripper
.top
, pB
->rcGripper
.right
, pB
->rcGripper
.bottom
);
190 TRACE("band # %u: Img=(%d,%d)-(%d,%d), Txt=(%d,%d)-(%d,%d), Child=(%d,%d)-(%d,%d)\n",
192 pB
->rcCapImage
.left
, pB
->rcCapImage
.top
, pB
->rcCapImage
.right
, pB
->rcCapImage
.bottom
,
193 pB
->rcCapText
.left
, pB
->rcCapText
.top
, pB
->rcCapText
.right
, pB
->rcCapText
.bottom
,
194 pB
->rcChild
.left
, pB
->rcChild
.top
, pB
->rcChild
.right
, pB
->rcChild
.bottom
);
201 REBAR_Notify (HWND hwnd
, NMHDR
*nmhdr
, UINT code
)
205 parent
= GetParent (hwnd
);
206 owner
= GetWindow (hwnd
, GW_OWNER
);
207 if (owner
) parent
= owner
;
208 nmhdr
->idFrom
= GetDlgCtrlID (hwnd
);
209 nmhdr
->hwndFrom
= hwnd
;
212 SendMessageA (parent
, WM_NOTIFY
, (WPARAM
) nmhdr
->idFrom
,
217 REBAR_DrawBand (HDC hdc
, REBAR_INFO
*infoPtr
, REBAR_BAND
*lpBand
, DWORD dwStyle
)
221 if (lpBand
->fDraw
& DRAW_SEP
) {
223 if (dwStyle
& CCS_VERT
)
224 SetRect (&rcSep
, lpBand
->rcBand
.left
-2, lpBand
->rcBand
.top
-SEP_WIDTH
,
225 lpBand
->rcBand
.right
+2, lpBand
->rcBand
.top
-1);
227 SetRect (&rcSep
, lpBand
->rcBand
.left
-SEP_WIDTH
, lpBand
->rcBand
.top
-2,
228 lpBand
->rcBand
.left
-1, lpBand
->rcBand
.bottom
+2);
229 TRACE("drawing band separator (%d,%d)-(%d,%d)\n",
230 rcSep
.left
, rcSep
.top
, rcSep
.right
, rcSep
.bottom
);
231 DrawEdge (hdc
, &rcSep
, EDGE_ETCHED
, BF_LEFT
| BF_TOP
| BF_MIDDLE
);
235 if (lpBand
->fDraw
& DRAW_GRIPPER
)
236 DrawEdge (hdc
, &lpBand
->rcGripper
, BDR_RAISEDINNER
, BF_RECT
| BF_MIDDLE
);
238 /* draw caption image */
239 if (lpBand
->fDraw
& DRAW_IMAGE
) {
243 pt
.y
= (lpBand
->rcCapImage
.bottom
+ lpBand
->rcCapImage
.top
- infoPtr
->imageSize
.cy
)/2;
244 pt
.x
= (lpBand
->rcCapImage
.right
+ lpBand
->rcCapImage
.left
- infoPtr
->imageSize
.cx
)/2;
246 ImageList_Draw (infoPtr
->himl
, lpBand
->iImage
, hdc
,
251 /* draw caption text */
252 if (lpBand
->fDraw
& DRAW_TEXT
) {
253 HFONT hOldFont
= SelectObject (hdc
, infoPtr
->hFont
);
254 INT oldBkMode
= SetBkMode (hdc
, TRANSPARENT
);
255 COLORREF oldcolor
= CLR_NONE
;
256 if (lpBand
->clrFore
!= CLR_NONE
)
257 oldcolor
= SetTextColor (hdc
, lpBand
->clrFore
);
258 DrawTextW (hdc
, lpBand
->lpText
, -1, &lpBand
->rcCapText
,
259 DT_CENTER
| DT_VCENTER
| DT_SINGLELINE
);
260 if (oldBkMode
!= TRANSPARENT
)
261 SetBkMode (hdc
, oldBkMode
);
262 if (lpBand
->clrFore
!= CLR_NONE
)
263 SetTextColor (hdc
, oldcolor
);
264 SelectObject (hdc
, hOldFont
);
270 REBAR_Refresh (HWND hwnd
, HDC hdc
)
272 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
276 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
278 oldrow
= infoPtr
->bands
[0].iRow
;
279 for (i
= 0; i
< infoPtr
->uNumBands
; i
++) {
280 lpBand
= &infoPtr
->bands
[i
];
282 if ((lpBand
->fStyle
& RBBS_HIDDEN
) ||
283 ((dwStyle
& CCS_VERT
) &&
284 (lpBand
->fStyle
& RBBS_NOVERT
)))
287 /* if a new row then draw a separator */
288 if (oldrow
!= lpBand
->iRow
) {
289 if (dwStyle
& RBS_BANDBORDERS
) {
290 if (dwStyle
& CCS_VERT
) {
291 SetRect (&rcRowSep
, lpBand
->rcBand
.left
-2, 0,
292 lpBand
->rcBand
.left
-1, infoPtr
->calcSize
.cy
);
295 SetRect (&rcRowSep
, 0, lpBand
->rcBand
.top
-2,
296 infoPtr
->calcSize
.cx
, lpBand
->rcBand
.top
-1);
298 TRACE ("drawing row sep (%d,%d)-(%d,%d)\n",
299 rcRowSep
.left
, rcRowSep
.top
,
300 rcRowSep
.right
, rcRowSep
.bottom
);
301 DrawEdge (hdc
, &rcRowSep
, EDGE_ETCHED
, BF_TOP
|BF_LEFT
);
302 oldrow
= lpBand
->iRow
;
306 /* now draw the band */
307 REBAR_DrawBand (hdc
, infoPtr
, lpBand
, dwStyle
);
313 REBAR_AdjustBands (REBAR_INFO
*infoPtr
, UINT rowstart
, UINT rowend
,
314 INT maxx
, INT usedx
, INT mcy
, DWORD dwStyle
)
315 /* Function: This routine distributes the extra space in a row */
316 /* evenly over the adjustable bands in the row. It also makes */
317 /* sure that all bands in the row are the same height. */
323 TRACE("start=%u, end=%u, max x=%d, used x=%d, max y=%d\n",
324 rowstart
, rowend
-1, maxx
, usedx
, mcy
);
327 for (i
= rowstart
; i
<rowend
; i
++) {
328 lpBand
= &infoPtr
->bands
[i
];
329 if ((lpBand
->fMask
& RBBIM_CHILD
) && lpBand
->hwndChild
&&
330 !(lpBand
->fStyle
& RBBS_FIXEDSIZE
))
334 incr
= (maxx
-usedx
) / j
;
338 TRACE("adjusting %u of %u bands in row, incr=%d\n",
339 j
, rowend
-rowstart
, incr
);
341 for (i
= rowstart
; i
<rowend
; i
++) {
342 lpBand
= &infoPtr
->bands
[i
];
343 if (dwStyle
& CCS_VERT
) {
344 lpBand
->rcBand
.bottom
= lastx
+
345 lpBand
->rcBand
.bottom
- lpBand
->rcBand
.top
;
346 if ((lpBand
->fMask
& RBBIM_CHILD
) && lpBand
->hwndChild
&&
347 !(lpBand
->fStyle
& RBBS_FIXEDSIZE
)) {
348 /* if a child window exists and not fixed then widen it */
349 lpBand
->rcBand
.bottom
+= incr
;
351 lpBand
->rcBand
.top
= lastx
;
352 lastx
= lpBand
->rcBand
.bottom
+ 1;
353 lpBand
->rcBand
.right
= lpBand
->rcBand
.left
+ mcy
;
356 lpBand
->rcBand
.right
= lastx
+
357 lpBand
->rcBand
.right
- lpBand
->rcBand
.left
;
358 if ((lpBand
->fMask
& RBBIM_CHILD
) && lpBand
->hwndChild
&&
359 !(lpBand
->fStyle
& RBBS_FIXEDSIZE
)) {
360 /* if a child window exists and not fixed then widen it */
361 lpBand
->rcBand
.right
+= incr
;
363 lpBand
->rcBand
.left
= lastx
;
364 lastx
= lpBand
->rcBand
.right
+ 1;
365 lpBand
->rcBand
.bottom
= lpBand
->rcBand
.top
+ mcy
;
372 REBAR_CalcHorzBand (HWND hwnd
, REBAR_INFO
*infoPtr
, UINT rstart
, UINT rend
, BOOL notify
, DWORD dwStyle
)
373 /* Function: this routine initializes all the rectangles in */
374 /* each band in a row to fit in the adjusted rcBand rect. */
375 /* *** Supports only Horizontal bars. *** */
379 NMREBARCHILDSIZE rbcz
;
383 rbcz
.hdr
.hwndFrom
= hwnd
;
384 rbcz
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
385 /* MS seems to use GetDlgCtrlID() for above GetWindowLong call */
386 parenthwnd
= GetParent (hwnd
);
388 for(i
=rstart
; i
<rend
; i
++){
389 lpBand
= &infoPtr
->bands
[i
];
390 oldChild
= lpBand
->rcChild
;
392 /* set initial gripper rectangle */
393 SetRect (&lpBand
->rcGripper
, lpBand
->rcBand
.left
, lpBand
->rcBand
.top
,
394 lpBand
->rcBand
.left
, lpBand
->rcBand
.bottom
);
396 /* calculate gripper rectangle */
397 if ((!(lpBand
->fStyle
& RBBS_NOGRIPPER
)) &&
398 (!(lpBand
->fStyle
& RBBS_FIXEDSIZE
)) &&
399 ((lpBand
->fStyle
& RBBS_GRIPPERALWAYS
) ||
400 (infoPtr
->uNumBands
> 1))) {
401 lpBand
->fDraw
|= DRAW_GRIPPER
;
402 lpBand
->rcGripper
.left
+= 1;
403 lpBand
->rcGripper
.right
= lpBand
->rcGripper
.left
+ 3;
404 lpBand
->rcGripper
.top
+= 3;
405 lpBand
->rcGripper
.bottom
-= 3;
407 SetRect (&lpBand
->rcCapImage
, lpBand
->rcGripper
.left
+ GRIPPER_WIDTH
,
408 lpBand
->rcBand
.top
, lpBand
->rcGripper
.left
+ GRIPPER_WIDTH
,
409 lpBand
->rcBand
.bottom
);
412 SetRect (&lpBand
->rcCapImage
, lpBand
->rcBand
.left
, lpBand
->rcBand
.top
,
413 lpBand
->rcBand
.left
, lpBand
->rcBand
.bottom
);
416 /* image is visible */
417 if ((lpBand
->fMask
& RBBIM_IMAGE
) && (infoPtr
->himl
)) {
418 lpBand
->fDraw
|= DRAW_IMAGE
;
420 lpBand
->rcCapImage
.right
+= infoPtr
->imageSize
.cx
;
421 lpBand
->rcCapImage
.bottom
= lpBand
->rcCapImage
.top
+ infoPtr
->imageSize
.cy
;
423 /* update band height */
424 if (lpBand
->uMinHeight
< infoPtr
->imageSize
.cy
+ 2) {
425 lpBand
->uMinHeight
= infoPtr
->imageSize
.cy
+ 2;
426 lpBand
->rcBand
.bottom
= lpBand
->rcBand
.top
+ lpBand
->uMinHeight
;
430 /* set initial caption text rectangle */
431 SetRect (&lpBand
->rcCapText
, lpBand
->rcCapImage
.right
, lpBand
->rcBand
.top
+1,
432 lpBand
->rcCapImage
.right
, lpBand
->rcBand
.bottom
-1);
434 /* text is visible */
435 if ((lpBand
->fMask
& RBBIM_TEXT
) && (lpBand
->lpText
)) {
437 HFONT hOldFont
= SelectObject (hdc
, infoPtr
->hFont
);
440 lpBand
->fDraw
|= DRAW_TEXT
;
441 GetTextExtentPoint32W (hdc
, lpBand
->lpText
,
442 lstrlenW (lpBand
->lpText
), &size
);
443 lpBand
->rcCapText
.right
+= (size
.cx
+ 2);
445 SelectObject (hdc
, hOldFont
);
449 /* set initial child window rectangle if there is a child */
450 if (lpBand
->fMask
& RBBIM_CHILD
) {
451 xoff
= lpBand
->offChild
.cx
;
452 yoff
= lpBand
->offChild
.cy
;
453 SetRect (&lpBand
->rcChild
,
454 lpBand
->rcBand
.left
+lpBand
->cxHeader
+xoff
, lpBand
->rcBand
.top
+yoff
,
455 lpBand
->rcBand
.right
-xoff
, lpBand
->rcBand
.bottom
-yoff
);
458 SetRect (&lpBand
->rcChild
,
459 lpBand
->rcCapText
.right
, lpBand
->rcBand
.top
,
460 lpBand
->rcBand
.right
, lpBand
->rcBand
.bottom
);
464 /* do notify is child rectangle changed */
465 if (notify
&& !EqualRect (&oldChild
, &lpBand
->rcChild
)) {
466 TRACE("Child rectangle changed for band %u\n", i
);
467 TRACE(" from (%d,%d)-(%d,%d) to (%d,%d)-(%d,%d)\n",
468 oldChild
.left
, oldChild
.top
,
469 oldChild
.right
, oldChild
.bottom
,
470 lpBand
->rcChild
.left
, lpBand
->rcChild
.top
,
471 lpBand
->rcChild
.right
, lpBand
->rcChild
.bottom
);
472 rbcz
.hdr
.code
= RBN_CHILDSIZE
;
474 rbcz
.wID
= lpBand
->wID
;
475 rbcz
.rcChild
= lpBand
->rcChild
;
476 rbcz
.rcBand
= lpBand
->rcBand
;
477 SendMessageA (parenthwnd
, WM_NOTIFY
, (WPARAM
) rbcz
.hdr
.idFrom
,
479 if (!EqualRect (&lpBand
->rcChild
, &rbcz
.rcChild
)) {
480 TRACE("Child rect changed by NOTIFY for band %u\n", i
);
481 TRACE(" from (%d,%d)-(%d,%d) to (%d,%d)-(%d,%d)\n",
482 lpBand
->rcChild
.left
, lpBand
->rcChild
.top
,
483 lpBand
->rcChild
.right
, lpBand
->rcChild
.bottom
,
484 rbcz
.rcChild
.left
, rbcz
.rcChild
.top
,
485 rbcz
.rcChild
.right
, rbcz
.rcChild
.bottom
);
496 REBAR_CalcVertBand (HWND hwnd
, REBAR_INFO
*infoPtr
, UINT rstart
, UINT rend
, BOOL notify
, DWORD dwStyle
)
497 /* Function: this routine initializes all the rectangles in */
498 /* each band in a row to fit in the adjusted rcBand rect. */
499 /* *** Supports only Vertical bars. *** */
503 NMREBARCHILDSIZE rbcz
;
507 rbcz
.hdr
.hwndFrom
= hwnd
;
508 rbcz
.hdr
.idFrom
= GetWindowLongA (hwnd
, GWL_ID
);
509 /* MS seems to use GetDlgCtrlID() for above GetWindowLong call */
510 parenthwnd
= GetParent (hwnd
);
512 for(i
=rstart
; i
<rend
; i
++){
513 lpBand
= &infoPtr
->bands
[i
];
514 oldChild
= lpBand
->rcChild
;
516 /* set initial gripper rectangle */
517 SetRect (&lpBand
->rcGripper
, lpBand
->rcBand
.left
, lpBand
->rcBand
.top
,
518 lpBand
->rcBand
.right
, lpBand
->rcBand
.top
);
520 /* calculate gripper rectangle */
521 if ((!(lpBand
->fStyle
& RBBS_NOGRIPPER
)) &&
522 (!(lpBand
->fStyle
& RBBS_FIXEDSIZE
)) &&
523 ((lpBand
->fStyle
& RBBS_GRIPPERALWAYS
) ||
524 (infoPtr
->uNumBands
> 1))) {
525 lpBand
->fDraw
|= DRAW_GRIPPER
;
527 if (dwStyle
& RBS_VERTICALGRIPPER
) {
528 /* vertical gripper */
529 lpBand
->rcGripper
.left
+= 3;
530 lpBand
->rcGripper
.right
= lpBand
->rcGripper
.left
+ 3;
531 lpBand
->rcGripper
.top
+= 3;
532 lpBand
->rcGripper
.bottom
= lpBand
->rcGripper
.top
+ GRIPPER_HEIGHT
;
534 /* initialize Caption image rectangle */
535 SetRect (&lpBand
->rcCapImage
, lpBand
->rcBand
.left
,
536 lpBand
->rcGripper
.top
+ GRIPPER_HEIGHT
,
537 lpBand
->rcBand
.right
,
538 lpBand
->rcGripper
.top
+ GRIPPER_HEIGHT
);
541 /* horizontal gripper */
542 lpBand
->rcGripper
.left
+= 3;
543 lpBand
->rcGripper
.right
-= 3;
544 lpBand
->rcGripper
.top
+= 3;
545 lpBand
->rcGripper
.bottom
= lpBand
->rcGripper
.top
+ 3;
547 /* initialize Caption image rectangle */
548 SetRect (&lpBand
->rcCapImage
, lpBand
->rcBand
.left
,
549 lpBand
->rcGripper
.top
+ GRIPPER_WIDTH
,
550 lpBand
->rcBand
.right
,
551 lpBand
->rcGripper
.top
+ GRIPPER_WIDTH
);
555 /* initialize Caption image rectangle */
556 SetRect (&lpBand
->rcCapImage
, lpBand
->rcBand
.left
, lpBand
->rcBand
.top
,
557 lpBand
->rcBand
.right
, lpBand
->rcBand
.top
);
560 /* image is visible */
561 if ((lpBand
->fMask
& RBBIM_IMAGE
) && (infoPtr
->himl
)) {
562 lpBand
->fDraw
|= DRAW_IMAGE
;
564 lpBand
->rcCapImage
.right
+= infoPtr
->imageSize
.cx
;
565 lpBand
->rcCapImage
.bottom
+= infoPtr
->imageSize
.cy
;
567 /* update band height */
568 if (lpBand
->uMinHeight
< infoPtr
->imageSize
.cx
+ 2) {
569 lpBand
->uMinHeight
= infoPtr
->imageSize
.cx
+ 2;
570 lpBand
->rcBand
.right
= lpBand
->rcBand
.left
+ lpBand
->uMinHeight
;
574 /* set initial caption text rectangle */
575 lpBand
->rcCapText
.left
= lpBand
->rcBand
.left
+ 1;
576 lpBand
->rcCapText
.top
= lpBand
->rcCapImage
.bottom
;
577 lpBand
->rcCapText
.right
= lpBand
->rcBand
.right
- 1;
578 lpBand
->rcCapText
.bottom
= lpBand
->rcCapText
.top
;
580 /* text is visible */
581 if (lpBand
->lpText
) {
583 HFONT hOldFont
= SelectObject (hdc
, infoPtr
->hFont
);
586 lpBand
->fDraw
|= DRAW_TEXT
;
587 GetTextExtentPoint32W (hdc
, lpBand
->lpText
,
588 lstrlenW (lpBand
->lpText
), &size
);
589 lpBand
->rcCapText
.bottom
+= (size
.cy
+ 2);
591 SelectObject (hdc
, hOldFont
);
595 /* set initial child window rectangle if there is a child */
596 if (lpBand
->fMask
& RBBIM_CHILD
) {
597 yoff
= lpBand
->offChild
.cx
;
598 xoff
= lpBand
->offChild
.cy
;
599 SetRect (&lpBand
->rcChild
,
600 lpBand
->rcBand
.left
+xoff
,
601 lpBand
->rcBand
.top
+lpBand
->cxHeader
+yoff
,
602 lpBand
->rcBand
.right
-xoff
, lpBand
->rcBand
.bottom
-yoff
);
605 SetRect (&lpBand
->rcChild
,
606 lpBand
->rcBand
.left
, lpBand
->rcCapText
.bottom
,
607 lpBand
->rcBand
.right
, lpBand
->rcBand
.top
);
611 /* do notify is child rectangle changed */
612 if (notify
&& !EqualRect (&oldChild
, &lpBand
->rcChild
)) {
613 TRACE("Child rectangle changed for band %u\n", i
);
614 TRACE(" from (%d,%d)-(%d,%d) to (%d,%d)-(%d,%d)\n",
615 oldChild
.left
, oldChild
.top
,
616 oldChild
.right
, oldChild
.bottom
,
617 lpBand
->rcChild
.left
, lpBand
->rcChild
.top
,
618 lpBand
->rcChild
.right
, lpBand
->rcChild
.bottom
);
619 rbcz
.hdr
.code
= RBN_CHILDSIZE
;
621 rbcz
.wID
= lpBand
->wID
;
622 rbcz
.rcChild
= lpBand
->rcChild
;
623 rbcz
.rcBand
= lpBand
->rcBand
;
624 SendMessageA (parenthwnd
, WM_NOTIFY
, (WPARAM
) rbcz
.hdr
.idFrom
,
626 if (!EqualRect (&lpBand
->rcChild
, &rbcz
.rcChild
)) {
627 TRACE("Child rect changed by NOTIFY for band %u\n", i
);
628 TRACE(" from (%d,%d)-(%d,%d) to (%d,%d)-(%d,%d)\n",
629 lpBand
->rcChild
.left
, lpBand
->rcChild
.top
,
630 lpBand
->rcChild
.right
, lpBand
->rcChild
.bottom
,
631 rbcz
.rcChild
.left
, rbcz
.rcChild
.top
,
632 rbcz
.rcChild
.right
, rbcz
.rcChild
.bottom
);
642 REBAR_Layout (HWND hwnd
, LPRECT lpRect
, BOOL notify
, BOOL resetclient
)
643 /* Function: This routine is resposible for laying out all */
644 /* the bands in a rebar. It assigns each band to a row and*/
645 /* determines when to start a new row. */
647 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
648 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
650 RECT rcClient
, rcAdj
;
651 INT x
, y
, cx
, cxsep
, mcy
, clientcx
, clientcy
, adjcx
, adjcy
, row
, rightx
, bottomy
;
652 UINT i
, rowstartband
;
655 GetClientRect (hwnd
, &rcClient
);
656 TRACE("Client is (%d,%d)-(%d,%d)\n",
657 rcClient
.left
, rcClient
.top
, rcClient
.right
, rcClient
.bottom
);
661 TRACE("adjustment rect is (%d,%d)-(%d,%d)\n",
662 rcAdj
.left
, rcAdj
.top
, rcAdj
.right
, rcAdj
.bottom
);
665 CopyRect (&rcAdj
, &rcClient
);
668 clientcx
= rcClient
.right
- rcClient
.left
;
669 clientcy
= rcClient
.bottom
- rcClient
.top
;
670 adjcx
= rcAdj
.right
- rcAdj
.left
;
671 adjcy
= rcAdj
.bottom
- rcAdj
.top
;
673 TRACE("window client rect will be set to adj rect\n");
684 for (i
= 0; i
< infoPtr
->uNumBands
; i
++) {
685 lpBand
= &infoPtr
->bands
[i
];
689 if ((lpBand
->fStyle
& RBBS_HIDDEN
) ||
690 ((dwStyle
& CCS_VERT
) && (lpBand
->fStyle
& RBBS_NOVERT
)))
693 cxsep
= (x
==0) ? 0 : SEP_WIDTH
; /* separator from previous band */
694 cx
= lpBand
->cxHeader
+ /* Header: includes gripper, text, image */
695 lpBand
->hcx
; /* coumpted size of child */
696 if (dwStyle
& CCS_VERT
)
697 dobreak
= (y
+ cx
+ cxsep
> adjcy
);
699 dobreak
= (x
+ cx
+ cxsep
> adjcx
);
700 /* This is the check for whether we need to start a new row */
701 if ( ( (lpBand
->fStyle
& RBBS_BREAK
) && (i
!= 0) ) ||
702 ( ((dwStyle
& CCS_VERT
) ? (y
!= 0) : (x
!= 0)) && dobreak
)) {
705 TRACE("Spliting to new row %d on band %u\n", row
+1, i
);
706 borders
= (dwStyle
& RBS_BANDBORDERS
) ? 2 : 0;
707 if (dwStyle
& CCS_VERT
) {
708 /* first adjust all bands in previous current row to */
709 /* redistribute extra x pixels */
710 REBAR_AdjustBands (infoPtr
, rowstartband
, i
,
711 clientcy
, y
, mcy
, dwStyle
);
712 /* calculate band subrectangles and break to new row */
713 REBAR_CalcVertBand (hwnd
, infoPtr
, rowstartband
, i
,
716 x
+= (mcy
+ borders
);
719 /* first adjust all bands in previous current row to */
720 /* redistribute extra x pixels */
721 REBAR_AdjustBands (infoPtr
, rowstartband
, i
,
722 clientcx
, x
, mcy
, dwStyle
);
723 /* calculate band subrectangles and break to new row */
724 REBAR_CalcHorzBand (hwnd
, infoPtr
, rowstartband
, i
,
727 y
+= (mcy
+ borders
);
730 /* FIXME: if not RBS_VARHEIGHT then find max */
738 if (mcy
< lpBand
->lcy
+ REBARSPACE
) mcy
= lpBand
->lcy
+ REBARSPACE
;
740 /* if boundary rect specified then limit mcy */
742 if (dwStyle
& CCS_VERT
) {
745 TRACE("row %u limiting mcy=%d, adjcx=%d, x=%d\n",
752 TRACE("row %u limiting mcy=%d, adjcy=%d, y=%d\n",
758 if (dwStyle
& CCS_VERT
) {
759 /* bound the bottom side if we have a bounding rectangle */
760 lpBand
->fDraw
|= (y
==0) ? 0 : DRAW_SEP
;
762 bottomy
= (lpRect
) ? min(clientcy
, y
+cxsep
+cx
) : y
+cxsep
+cx
;
763 lpBand
->rcBand
.left
= x
;
764 lpBand
->rcBand
.right
= y
+ min(mcy
, lpBand
->lcy
+REBARSPACE
);
765 lpBand
->rcBand
.top
= min(bottomy
, y
+ cxsep
);
766 lpBand
->rcBand
.bottom
= bottomy
;
767 lpBand
->uMinHeight
= lpBand
->lcy
;
771 /* bound the right side if we have a bounding rectangle */
772 lpBand
->fDraw
|= (x
==0) ? 0 : DRAW_SEP
;
773 rightx
= (lpRect
) ? min(clientcx
, x
+cxsep
+cx
) : x
+cxsep
+cx
;
775 lpBand
->rcBand
.left
= min(rightx
, x
+ cxsep
);
776 lpBand
->rcBand
.right
= rightx
;
777 lpBand
->rcBand
.top
= y
;
778 lpBand
->rcBand
.bottom
= y
+ min(mcy
, lpBand
->lcy
+REBARSPACE
);
779 lpBand
->uMinHeight
= lpBand
->lcy
;
782 TRACE("band %u, row %d, (%d,%d)-(%d,%d)\n",
784 lpBand
->rcBand
.left
, lpBand
->rcBand
.top
,
785 lpBand
->rcBand
.right
, lpBand
->rcBand
.bottom
);
788 if (infoPtr
->uNumBands
) {
789 infoPtr
->uNumRows
= row
;
791 if (dwStyle
& CCS_VERT
) {
792 REBAR_AdjustBands (infoPtr
, rowstartband
, infoPtr
->uNumBands
,
793 clientcy
, y
, mcy
, dwStyle
);
794 REBAR_CalcVertBand (hwnd
, infoPtr
, rowstartband
, infoPtr
->uNumBands
,
799 REBAR_AdjustBands (infoPtr
, rowstartband
, infoPtr
->uNumBands
,
800 clientcx
, x
, mcy
, dwStyle
);
801 REBAR_CalcHorzBand (hwnd
, infoPtr
, rowstartband
, infoPtr
->uNumBands
,
807 /* FIXME: if not RBS_VARHEIGHT then find max mcy and adj rect*/
809 if (dwStyle
& CCS_VERT
) {
810 infoPtr
->calcSize
.cx
= x
;
811 infoPtr
->calcSize
.cy
= clientcy
;
814 infoPtr
->calcSize
.cx
= clientcx
;
815 infoPtr
->calcSize
.cy
= y
;
817 REBAR_DumpBand (hwnd
);
822 REBAR_ForceResize (HWND hwnd
)
823 /* Function: This changes the size of the REBAR window to that */
824 /* calculated by REBAR_Layout. */
826 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
829 TRACE( " to [%ld x %ld]!\n",
830 infoPtr
->calcSize
.cx
, infoPtr
->calcSize
.cy
);
832 infoPtr
->fStatus
|= AUTO_RESIZE
;
836 rc
.right
= infoPtr
->calcSize
.cx
;
837 rc
.bottom
= infoPtr
->calcSize
.cy
;
839 if (GetWindowLongA (hwnd
, GWL_STYLE
) & WS_BORDER
) {
840 InflateRect (&rc
, GetSystemMetrics(SM_CXEDGE
), GetSystemMetrics(SM_CYEDGE
));
843 SetWindowPos (hwnd
, 0, 0, 0,
844 rc
.right
- rc
.left
, rc
.bottom
- rc
.top
,
845 SWP_NOMOVE
| SWP_NOZORDER
| SWP_SHOWWINDOW
);
850 REBAR_MoveChildWindows (HWND hwnd
)
852 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
854 CHAR szClassName
[40];
857 for (i
= 0; i
< infoPtr
->uNumBands
; i
++) {
858 lpBand
= &infoPtr
->bands
[i
];
860 if (lpBand
->fStyle
& RBBS_HIDDEN
)
862 if (lpBand
->hwndChild
) {
863 TRACE("hwndChild = %x\n", lpBand
->hwndChild
);
865 GetClassNameA (lpBand
->hwndChild
, szClassName
, 40);
866 if (!lstrcmpA (szClassName
, "ComboBox")) {
867 INT nEditHeight
, yPos
;
870 /* special placement code for combo box */
873 /* get size of edit line */
874 GetWindowRect (lpBand
->hwndChild
, &rc
);
875 nEditHeight
= rc
.bottom
- rc
.top
;
876 yPos
= (lpBand
->rcChild
.bottom
+ lpBand
->rcChild
.top
- nEditHeight
)/2;
878 /* center combo box inside child area */
879 TRACE("moving child %04x to (%d,%d)-(%d,%d)\n",
881 lpBand
->rcChild
.left
, yPos
,
882 lpBand
->rcChild
.right
- lpBand
->rcChild
.left
,
884 SetWindowPos (lpBand
->hwndChild
, HWND_TOP
,
885 lpBand
->rcChild
.left
, /*lpBand->rcChild.top*/ yPos
,
886 lpBand
->rcChild
.right
- lpBand
->rcChild
.left
,
891 else if (!lstrcmpA (szClassName
, WC_COMBOBOXEXA
)) {
892 INT nEditHeight
, yPos
;
896 /* special placement code for extended combo box */
898 /* get size of edit line */
899 hwndEdit
= SendMessageA (lpBand
->hwndChild
, CBEM_GETEDITCONTROL
, 0, 0);
900 GetWindowRect (hwndEdit
, &rc
);
901 nEditHeight
= rc
.bottom
- rc
.top
;
902 yPos
= (lpBand
->rcChild
.bottom
+ lpBand
->rcChild
.top
- nEditHeight
)/2;
904 /* center combo box inside child area */
905 TRACE("moving child %04x to (%d,%d)-(%d,%d)\n",
907 lpBand
->rcChild
.left
, yPos
,
908 lpBand
->rcChild
.right
- lpBand
->rcChild
.left
,
910 SetWindowPos (lpBand
->hwndChild
, HWND_TOP
,
911 lpBand
->rcChild
.left
, /*lpBand->rcChild.top*/ yPos
,
912 lpBand
->rcChild
.right
- lpBand
->rcChild
.left
,
919 TRACE("moving child %04x to (%d,%d)-(%d,%d)\n",
921 lpBand
->rcChild
.left
, lpBand
->rcChild
.top
,
922 lpBand
->rcChild
.right
- lpBand
->rcChild
.left
,
923 lpBand
->rcChild
.bottom
- lpBand
->rcChild
.top
);
924 SetWindowPos (lpBand
->hwndChild
, HWND_TOP
,
925 lpBand
->rcChild
.left
, lpBand
->rcChild
.top
,
926 lpBand
->rcChild
.right
- lpBand
->rcChild
.left
,
927 lpBand
->rcChild
.bottom
- lpBand
->rcChild
.top
,
936 REBAR_ValidateBand (HWND hwnd
, REBAR_INFO
*infoPtr
, REBAR_BAND
*lpBand
)
937 /* Function: This routine evaluates the band specs supplied */
938 /* by the user and updates the following 5 fields in */
939 /* the internal band structure: cxHeader, lcx, lcy, hcx, hcy*/
942 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
949 /* Header is where the image, text and gripper exist */
950 /* in the band and preceed the child window. */
952 /* calculate gripper rectangle */
953 if ((!(lpBand
->fStyle
& RBBS_NOGRIPPER
)) &&
954 (!(lpBand
->fStyle
& RBBS_FIXEDSIZE
)) &&
955 ((lpBand
->fStyle
& RBBS_GRIPPERALWAYS
) ||
956 (infoPtr
->uNumBands
> 1))) {
957 if (dwStyle
& CCS_VERT
)
958 if (dwStyle
& RBS_VERTICALGRIPPER
)
959 header
+= (GRIPPER_HEIGHT
+ 3);
961 header
+= (GRIPPER_WIDTH
+ 3);
963 header
+= (GRIPPER_WIDTH
+ 1);
966 /* image is visible */
967 if ((lpBand
->fMask
& RBBIM_IMAGE
) && (infoPtr
->himl
)) {
968 if (dwStyle
& CCS_VERT
) {
969 header
+= infoPtr
->imageSize
.cy
;
970 lpBand
->lcy
= infoPtr
->imageSize
.cx
+ 2;
973 header
+= infoPtr
->imageSize
.cx
;
974 lpBand
->lcy
= infoPtr
->imageSize
.cy
+ 2;
978 /* text is visible */
979 if ((lpBand
->fMask
& RBBIM_TEXT
) && (lpBand
->lpText
)) {
981 HFONT hOldFont
= SelectObject (hdc
, infoPtr
->hFont
);
984 GetTextExtentPoint32W (hdc
, lpBand
->lpText
,
985 lstrlenW (lpBand
->lpText
), &size
);
986 header
+= ((dwStyle
& CCS_VERT
) ? (size
.cy
+ 2) : (size
.cx
+ 2));
988 SelectObject (hdc
, hOldFont
);
992 /* check if user overrode the header value */
993 if (!(lpBand
->fMask
& RBBIM_HEADERSIZE
))
994 lpBand
->cxHeader
= header
;
997 /* Now compute minimum size of child window */
998 lpBand
->offChild
.cx
= 0;
999 lpBand
->offChild
.cy
= 0;
1000 if (lpBand
->fMask
& RBBIM_CHILDSIZE
) {
1001 if (!(lpBand
->fStyle
& RBBS_FIXEDSIZE
)) {
1002 lpBand
->offChild
.cx
= 4;
1003 lpBand
->offChild
.cy
= 2;
1005 lpBand
->lcx
= lpBand
->cxMinChild
;
1006 lpBand
->lcy
= lpBand
->cyMinChild
;
1007 lpBand
->hcy
= lpBand
->lcy
;
1008 if (lpBand
->fStyle
& RBBS_VARIABLEHEIGHT
) {
1009 if (lpBand
->cyChild
!= 0xffffffff)
1010 lpBand
->lcy
= max (lpBand
->cyChild
, lpBand
->lcy
);
1011 lpBand
->hcy
= lpBand
->cyMaxChild
;
1013 TRACE("_CHILDSIZE\n");
1015 if (lpBand
->fMask
& RBBIM_SIZE
) {
1016 lpBand
->hcx
= max (lpBand
->cx
, lpBand
->lcx
);
1020 lpBand
->hcx
= lpBand
->lcx
;
1025 REBAR_CommonSetupBand (HWND hwnd
, LPREBARBANDINFOA lprbbi
, REBAR_BAND
*lpBand
)
1026 /* Function: This routine copies the supplied values from */
1027 /* user input (lprbbi) to the internal band structure. */
1029 lpBand
->fMask
|= lprbbi
->fMask
;
1031 if (lprbbi
->fMask
& RBBIM_STYLE
)
1032 lpBand
->fStyle
= lprbbi
->fStyle
;
1034 if (lprbbi
->fMask
& RBBIM_COLORS
) {
1035 lpBand
->clrFore
= lprbbi
->clrFore
;
1036 lpBand
->clrBack
= lprbbi
->clrBack
;
1039 if (lprbbi
->fMask
& RBBIM_IMAGE
)
1040 lpBand
->iImage
= lprbbi
->iImage
;
1042 if (lprbbi
->fMask
& RBBIM_CHILD
) {
1043 if (lprbbi
->hwndChild
) {
1044 lpBand
->hwndChild
= lprbbi
->hwndChild
;
1045 lpBand
->hwndPrevParent
=
1046 SetParent (lpBand
->hwndChild
, hwnd
);
1049 TRACE("child: 0x%x prev parent: 0x%x\n",
1050 lpBand
->hwndChild
, lpBand
->hwndPrevParent
);
1051 lpBand
->hwndChild
= 0;
1052 lpBand
->hwndPrevParent
= 0;
1056 if (lprbbi
->fMask
& RBBIM_CHILDSIZE
) {
1057 lpBand
->cxMinChild
= lprbbi
->cxMinChild
;
1058 lpBand
->cyMinChild
= lprbbi
->cyMinChild
;
1059 lpBand
->cyMaxChild
= lprbbi
->cyMaxChild
;
1060 lpBand
->cyChild
= lprbbi
->cyChild
;
1061 lpBand
->cyIntegral
= lprbbi
->cyIntegral
;
1064 if (lprbbi
->fMask
& RBBIM_SIZE
)
1065 lpBand
->cx
= lprbbi
->cx
;
1067 if (lprbbi
->fMask
& RBBIM_BACKGROUND
)
1068 lpBand
->hbmBack
= lprbbi
->hbmBack
;
1070 if (lprbbi
->fMask
& RBBIM_ID
)
1071 lpBand
->wID
= lprbbi
->wID
;
1073 /* check for additional data */
1074 if (lprbbi
->cbSize
>= sizeof (REBARBANDINFOA
)) {
1075 if (lprbbi
->fMask
& RBBIM_IDEALSIZE
)
1076 lpBand
->cxIdeal
= lprbbi
->cxIdeal
;
1078 if (lprbbi
->fMask
& RBBIM_LPARAM
)
1079 lpBand
->lParam
= lprbbi
->lParam
;
1081 if (lprbbi
->fMask
& RBBIM_HEADERSIZE
)
1082 lpBand
->cxHeader
= lprbbi
->cxHeader
;
1087 REBAR_InternalEraseBkGnd (HWND hwnd
, WPARAM wParam
, LPARAM lParam
, RECT
*clip
)
1088 /* Function: This erases the background rectangle with the */
1089 /* default brush, then with any band that has a different */
1090 /* background color. */
1092 HBRUSH hbrBackground
= GetClassWord(hwnd
, GCW_HBRBACKGROUND
);
1093 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
1099 FillRect( (HDC
) wParam
, clip
, hbrBackground
);
1101 for(i
=0; i
<infoPtr
->uNumBands
; i
++) {
1102 lpBand
= &infoPtr
->bands
[i
];
1103 if (lpBand
->clrBack
!= CLR_NONE
) {
1104 if (IntersectRect (&eraserect
, clip
, &lpBand
->rcBand
)) {
1105 /* draw background */
1106 HBRUSH brh
= CreateSolidBrush (lpBand
->clrBack
);
1107 TRACE("backround color=0x%06lx, rect (%d,%d)-(%d,%d)\n",
1109 lpBand
->rcBand
.left
,lpBand
->rcBand
.top
,
1110 lpBand
->rcBand
.right
,lpBand
->rcBand
.bottom
);
1111 FillRect ( (HDC
)wParam
, &eraserect
, brh
);
1120 REBAR_InternalHitTest (HWND hwnd
, LPPOINT lpPt
, UINT
*pFlags
, INT
*pBand
)
1122 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
1127 GetClientRect (hwnd
, &rect
);
1129 *pFlags
= RBHT_NOWHERE
;
1130 if (PtInRect (&rect
, *lpPt
))
1132 if (infoPtr
->uNumBands
== 0) {
1133 *pFlags
= RBHT_NOWHERE
;
1140 /* somewhere inside */
1141 infoPtr
->ihitBand
= -1;
1142 for (iCount
= 0; iCount
< infoPtr
->uNumBands
; iCount
++) {
1143 lpBand
= &infoPtr
->bands
[iCount
];
1144 if (PtInRect (&lpBand
->rcBand
, *lpPt
)) {
1147 if (PtInRect (&lpBand
->rcGripper
, *lpPt
)) {
1148 *pFlags
= RBHT_GRABBER
;
1149 infoPtr
->ihitBand
= iCount
;
1150 TRACE("ON GRABBER %d\n", iCount
);
1153 else if (PtInRect (&lpBand
->rcCapImage
, *lpPt
)) {
1154 *pFlags
= RBHT_CAPTION
;
1155 TRACE("ON CAPTION %d\n", iCount
);
1158 else if (PtInRect (&lpBand
->rcCapText
, *lpPt
)) {
1159 *pFlags
= RBHT_CAPTION
;
1160 TRACE("ON CAPTION %d\n", iCount
);
1163 else if (PtInRect (&lpBand
->rcChild
, *lpPt
)) {
1164 *pFlags
= RBHT_CLIENT
;
1165 TRACE("ON CLIENT %d\n", iCount
);
1169 *pFlags
= RBHT_NOWHERE
;
1170 TRACE("NOWHERE %d\n", iCount
);
1176 *pFlags
= RBHT_NOWHERE
;
1185 *pFlags
= RBHT_NOWHERE
;
1192 TRACE("flags=0x%X\n", *pFlags
);
1196 #define READJ(b,i) {b->rcChild.right += (i);b->rcBand.right += (i);}
1197 #define LEADJ(b,i) {b->rcBand.left += (i); \
1198 b->rcGripper.left += (i); \
1199 b->rcGripper.right += (i); \
1200 b->rcCapImage.left += (i); \
1201 b->rcCapImage.right += (i); \
1202 b->rcCapText.left += (i); \
1203 b->rcCapText.right += (i); \
1204 b->rcChild.left += (i);}
1208 REBAR_Shrink (REBAR_BAND
*band
, INT movement
, INT i
)
1209 /* Function: This attempts to shrink the given band by the */
1210 /* the amount in "movement". A shrink to the left is indi- */
1211 /* cated by "movement" being negative. "i" is merely the */
1212 /* band index for trace messages. */
1214 INT Leadjust
, Readjust
, avail
, ret
;
1216 /* Note: a left drag is indicated by "movement" being negative. */
1217 /* Similarly, a right drag is indicated by "movement" */
1218 /* being positive. "movement" should never be 0, but if */
1219 /* it is then the band does not move. */
1221 avail
= band
->rcBand
.right
- band
->rcBand
.left
-
1222 band
->cxHeader
- band
->offChild
.cx
;
1224 /* now compute the Left End adjustment factor and Right End */
1225 /* adjustment factor. They may be different if shrinking. */
1227 /* if this band is not shrinkable, then just move it */
1228 Leadjust
= Readjust
= movement
;
1234 if (avail
<= abs(movement
)) {
1235 Readjust
= movement
;
1236 Leadjust
= movement
+ avail
;
1240 Readjust
= movement
;
1247 if (avail
<= abs(movement
)) {
1248 Leadjust
= movement
;
1249 Readjust
= movement
- avail
;
1253 Leadjust
= movement
;
1260 /* Reasonability Check */
1261 if (band
->rcBand
.left
+Leadjust
< 0) {
1262 ERR("adjustment will fail, band %d: left=%d, right=%d, move=%d, rtn=%d\n",
1263 i
, Leadjust
, Readjust
, movement
, ret
);
1266 LEADJ(band
, Leadjust
);
1267 READJ(band
, Readjust
);
1269 TRACE("band %d: left=%d, right=%d, move=%d, rtn=%d, rcBand=(%d,%d)-(%d,%d)\n",
1270 i
, Leadjust
, Readjust
, movement
, ret
,
1271 band
->rcBand
.left
, band
->rcBand
.top
,
1272 band
->rcBand
.right
, band
->rcBand
.bottom
);
1278 REBAR_HandleLRDrag (HWND hwnd
, REBAR_INFO
*infoPtr
, POINTS
*ptsmove
)
1279 /* Function: This will implement the functionality of a */
1280 /* Gripper drag within a row. It will not implement "out- */
1281 /* of-row" drags. (They are detected and handled in */
1282 /* REBAR_MouseMove.) */
1283 /* **** FIXME Vertical rebars not implemented. **** */
1284 /* **** FIXME Switching order of bands in a row not **** */
1285 /* **** yet implemented. **** */
1287 REBAR_BAND
*hitBand
, *band
, *prevband
, *mindBand
, *maxdBand
;
1288 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
1290 NMREBARCHILDSIZE cs
;
1293 INT imindBand
= -1, imaxdBand
, ihitBand
, i
, movement
, tempx
;
1294 INT RHeaderSum
= 0, LHeaderSum
= 0;
1297 /* *** FIXME drag does not work for vertical *** */
1298 if (dwStyle
& CCS_VERT
) {
1299 FIXME("Drag not yet implemented for vertical rebars\n");
1303 /* on first significant mouse movement, issue notify */
1305 if (!(infoPtr
->fStatus
& BEGIN_DRAG_ISSUED
)) {
1306 startdrag
.dwMask
= 0;
1307 startdrag
.uBand
= -1;
1308 REBAR_Notify(hwnd
, (NMHDR
*) &startdrag
, RBN_BEGINDRAG
);
1309 infoPtr
->fStatus
|= BEGIN_DRAG_ISSUED
;
1312 ihitBand
= infoPtr
->ihitBand
;
1313 hitBand
= &infoPtr
->bands
[ihitBand
];
1314 imaxdBand
= ihitBand
; /* to suppress warning message */
1316 /* find all the bands in the row of the one whose Gripper was seized */
1317 for (i
=0; i
<infoPtr
->uNumBands
; i
++) {
1318 band
= &infoPtr
->bands
[i
];
1319 if (band
->iRow
== hitBand
->iRow
) {
1321 if (imindBand
== -1) imindBand
= i
;
1322 /* minimum size of each band is size of header plus */
1323 /* size of minimum child plus offset of child from header plus */
1324 /* a one to separate each band. */
1326 LHeaderSum
+= (band
->cxHeader
+ band
->offChild
.cx
+
1329 RHeaderSum
+= (band
->cxHeader
+ band
->offChild
.cx
+
1334 if (RHeaderSum
) RHeaderSum
--; /* no separator afterlast band */
1336 mindBand
= &infoPtr
->bands
[imindBand
];
1337 maxdBand
= &infoPtr
->bands
[imaxdBand
];
1339 if (imindBand
== imaxdBand
) return; /* nothing to drag agains */
1340 if (imindBand
== ihitBand
) return; /* first band in row, cant drag */
1342 /* limit movement to inside adjustable bands - Left */
1343 if (ptsmove
->x
< mindBand
->rcBand
.left
)
1344 return; /* should swap bands */
1345 /* limit movement to inside adjustable bands - Right */
1346 if (ptsmove
->x
> maxdBand
->rcBand
.right
)
1347 return; /* should swap bands */
1349 movement
= ptsmove
->x
- (hitBand
->rcGripper
.left
- infoPtr
->ihitoffset
);
1350 infoPtr
->dragNow
= *ptsmove
;
1352 TRACE("before: movement=%d (%d,%d), imindBand=%d, ihitBand=%d, imaxdBand=%d, LSum=%d, RSum=%d\n",
1353 movement
, ptsmove
->x
, ptsmove
->y
, imindBand
, ihitBand
,
1354 imaxdBand
, LHeaderSum
, RHeaderSum
);
1355 REBAR_DumpBand (hwnd
);
1359 /* *** Drag left *** */
1360 compress
= hitBand
->rcBand
.left
-1 - mindBand
->rcBand
.left
-
1362 if (compress
< abs(movement
)) {
1363 TRACE("limiting left drag, was %d changed to %d\n",
1364 movement
, -compress
);
1365 movement
= -compress
;
1367 for (i
=ihitBand
; i
>=imindBand
; i
--) {
1368 band
= &infoPtr
->bands
[i
];
1369 if (i
== ihitBand
) {
1370 prevband
= &infoPtr
->bands
[i
-1];
1371 if (band
->rcBand
.left
- movement
<= prevband
->rcBand
.right
) {
1372 tempx
= movement
- (prevband
->rcBand
.right
-band
->rcBand
.left
+1);
1373 ERR("movement bad. BUG!! was %d, left=%d, right=%d, setting to %d\n",
1374 movement
, band
->rcBand
.left
, prevband
->rcBand
.right
, tempx
);
1377 LEADJ(band
, movement
)
1380 movement
= REBAR_Shrink (band
, movement
, i
);
1385 /* *** Drag right *** */
1386 compress
= maxdBand
->rcBand
.right
- hitBand
->rcBand
.left
-
1388 if (compress
< abs(movement
)) {
1389 TRACE("limiting right drag, was %d changed to %d\n",
1390 movement
, compress
);
1391 movement
= compress
;
1393 for (i
=ihitBand
-1; i
<=imaxdBand
; i
++) {
1394 band
= &infoPtr
->bands
[i
];
1395 if (i
== ihitBand
-1) {
1396 READJ(band
, movement
)
1399 movement
= REBAR_Shrink (band
, movement
, i
);
1403 TRACE("bands after adjustment, see band # %d, %d\n",
1404 imindBand
, imaxdBand
);
1405 REBAR_DumpBand (hwnd
);
1408 mindBand
->rcBand
.left
,
1409 min(mindBand
->rcBand
.top
, maxdBand
->rcBand
.top
),
1410 maxdBand
->rcBand
.right
,
1411 max(mindBand
->rcBand
.bottom
, maxdBand
->rcBand
.bottom
));
1413 if (!(deferpos
= BeginDeferWindowPos (4))) {
1414 ERR("BeginDeferWindowPos returned NULL\n");
1417 for (i
=imindBand
; i
<=imaxdBand
; i
++) {
1418 band
= &infoPtr
->bands
[i
];
1419 if ((band
->fMask
& RBBIM_CHILD
) && band
->hwndChild
) {
1422 cs
.rcChild
= band
->rcChild
;
1423 cs
.rcBand
= band
->rcBand
;
1424 REBAR_Notify (hwnd
, (NMHDR
*) &cs
, RBN_CHILDSIZE
);
1425 deferpos
= DeferWindowPos (deferpos
, band
->hwndChild
, HWND_TOP
,
1426 cs
.rcChild
.left
, cs
.rcChild
.top
,
1427 cs
.rcChild
.right
- cs
.rcChild
.left
,
1428 cs
.rcChild
.bottom
- cs
.rcChild
.top
,
1431 ERR("DeferWindowPos returned NULL\n");
1436 if (!EndDeferWindowPos (deferpos
)) {
1437 ERR("EndDeferWindowPos failed\n");
1440 InvalidateRect (hwnd
, &newrect
, TRUE
);
1441 UpdateWindow (hwnd
);
1449 /* << REBAR_BeginDrag >> */
1453 REBAR_DeleteBand (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1455 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
1456 UINT uBand
= (UINT
)wParam
;
1458 if (uBand
>= infoPtr
->uNumBands
)
1461 TRACE("deleting band %u!\n", uBand
);
1463 if (infoPtr
->uNumBands
== 1) {
1464 TRACE(" simple delete!\n");
1465 COMCTL32_Free (infoPtr
->bands
);
1466 infoPtr
->bands
= NULL
;
1467 infoPtr
->uNumBands
= 0;
1470 REBAR_BAND
*oldBands
= infoPtr
->bands
;
1471 TRACE("complex delete! [uBand=%u]\n", uBand
);
1473 infoPtr
->uNumBands
--;
1474 infoPtr
->bands
= COMCTL32_Alloc (sizeof (REBAR_BAND
) * infoPtr
->uNumBands
);
1476 memcpy (&infoPtr
->bands
[0], &oldBands
[0],
1477 uBand
* sizeof(REBAR_BAND
));
1480 if (uBand
< infoPtr
->uNumBands
) {
1481 memcpy (&infoPtr
->bands
[uBand
], &oldBands
[uBand
+1],
1482 (infoPtr
->uNumBands
- uBand
) * sizeof(REBAR_BAND
));
1485 COMCTL32_Free (oldBands
);
1488 REBAR_Layout (hwnd
, NULL
, FALSE
, FALSE
);
1489 REBAR_ForceResize (hwnd
);
1490 REBAR_MoveChildWindows (hwnd
);
1496 /* << REBAR_DragMove >> */
1497 /* << REBAR_EndDrag >> */
1501 REBAR_GetBandBorders (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1503 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
1504 /* LPRECT32 lpRect = (LPRECT32)lParam; */
1509 if ((UINT
)wParam
>= infoPtr
->uNumBands
)
1512 lpBand
= &infoPtr
->bands
[(UINT
)wParam
];
1513 if (GetWindowLongA (hwnd
, GWL_STYLE
) & RBS_BANDBORDERS
) {
1514 /*lpRect.left = ??? */
1515 /*lpRect.top = ??? */
1516 /*lpRect.right = ??? */
1517 /*lpRect.bottom = ??? */
1520 /*lpRect.left = ??? */
1527 inline static LRESULT
1528 REBAR_GetBandCount (HWND hwnd
)
1530 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
1532 TRACE("band count %u!\n", infoPtr
->uNumBands
);
1534 return infoPtr
->uNumBands
;
1539 REBAR_GetBandInfoA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1541 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
1542 LPREBARBANDINFOA lprbbi
= (LPREBARBANDINFOA
)lParam
;
1547 if (lprbbi
->cbSize
< REBARBANDINFO_V3_SIZEA
)
1549 if ((UINT
)wParam
>= infoPtr
->uNumBands
)
1552 TRACE("index %u\n", (UINT
)wParam
);
1554 /* copy band information */
1555 lpBand
= &infoPtr
->bands
[(UINT
)wParam
];
1557 if (lprbbi
->fMask
& RBBIM_STYLE
)
1558 lprbbi
->fStyle
= lpBand
->fStyle
;
1560 if (lprbbi
->fMask
& RBBIM_COLORS
) {
1561 lprbbi
->clrFore
= lpBand
->clrFore
;
1562 lprbbi
->clrBack
= lpBand
->clrBack
;
1563 if (lprbbi
->clrBack
== CLR_NONE
)
1564 lprbbi
->clrBack
= GetSysColor (COLOR_BTNFACE
);
1567 if ((lprbbi
->fMask
& RBBIM_TEXT
) && (lprbbi
->lpText
)) {
1568 if (lpBand
->lpText
&& (lpBand
->fMask
& RBBIM_TEXT
))
1570 if (!WideCharToMultiByte( CP_ACP
, 0, lpBand
->lpText
, -1,
1571 lprbbi
->lpText
, lprbbi
->cch
, NULL
, NULL
))
1572 lprbbi
->lpText
[lprbbi
->cch
-1] = 0;
1575 *lprbbi
->lpText
= 0;
1578 if (lprbbi
->fMask
& RBBIM_IMAGE
) {
1579 if (lpBand
->fMask
& RBBIM_IMAGE
)
1580 lprbbi
->iImage
= lpBand
->iImage
;
1582 lprbbi
->iImage
= -1;
1585 if (lprbbi
->fMask
& RBBIM_CHILD
)
1586 lprbbi
->hwndChild
= lpBand
->hwndChild
;
1588 if (lprbbi
->fMask
& RBBIM_CHILDSIZE
) {
1589 lprbbi
->cxMinChild
= lpBand
->cxMinChild
;
1590 lprbbi
->cyMinChild
= lpBand
->cyMinChild
;
1591 lprbbi
->cyMaxChild
= lpBand
->cyMaxChild
;
1592 lprbbi
->cyChild
= lpBand
->cyChild
;
1593 lprbbi
->cyIntegral
= lpBand
->cyIntegral
;
1596 if (lprbbi
->fMask
& RBBIM_SIZE
)
1597 lprbbi
->cx
= lpBand
->cx
;
1599 if (lprbbi
->fMask
& RBBIM_BACKGROUND
)
1600 lprbbi
->hbmBack
= lpBand
->hbmBack
;
1602 if (lprbbi
->fMask
& RBBIM_ID
)
1603 lprbbi
->wID
= lpBand
->wID
;
1605 /* check for additional data */
1606 if (lprbbi
->cbSize
>= sizeof (REBARBANDINFOA
)) {
1607 if (lprbbi
->fMask
& RBBIM_IDEALSIZE
)
1608 lprbbi
->cxIdeal
= lpBand
->cxIdeal
;
1610 if (lprbbi
->fMask
& RBBIM_LPARAM
)
1611 lprbbi
->lParam
= lpBand
->lParam
;
1613 if (lprbbi
->fMask
& RBBIM_HEADERSIZE
)
1614 lprbbi
->cxHeader
= lpBand
->cxHeader
;
1617 REBAR_DumpBandInfo (lprbbi
);
1624 REBAR_GetBandInfoW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1626 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
1627 LPREBARBANDINFOW lprbbi
= (LPREBARBANDINFOW
)lParam
;
1632 if (lprbbi
->cbSize
< REBARBANDINFO_V3_SIZEW
)
1634 if ((UINT
)wParam
>= infoPtr
->uNumBands
)
1637 TRACE("index %u\n", (UINT
)wParam
);
1639 /* copy band information */
1640 lpBand
= &infoPtr
->bands
[(UINT
)wParam
];
1642 if (lprbbi
->fMask
& RBBIM_STYLE
)
1643 lprbbi
->fStyle
= lpBand
->fStyle
;
1645 if (lprbbi
->fMask
& RBBIM_COLORS
) {
1646 lprbbi
->clrFore
= lpBand
->clrFore
;
1647 lprbbi
->clrBack
= lpBand
->clrBack
;
1648 if (lprbbi
->clrBack
== CLR_NONE
)
1649 lprbbi
->clrBack
= GetSysColor (COLOR_BTNFACE
);
1652 if ((lprbbi
->fMask
& RBBIM_TEXT
) && (lprbbi
->lpText
)) {
1653 if (lpBand
->lpText
&& (lpBand
->fMask
& RBBIM_TEXT
))
1654 lstrcpynW (lprbbi
->lpText
, lpBand
->lpText
, lprbbi
->cch
);
1656 *lprbbi
->lpText
= 0;
1659 if (lprbbi
->fMask
& RBBIM_IMAGE
) {
1660 if (lpBand
->fMask
& RBBIM_IMAGE
)
1661 lprbbi
->iImage
= lpBand
->iImage
;
1663 lprbbi
->iImage
= -1;
1666 if (lprbbi
->fMask
& RBBIM_CHILD
)
1667 lprbbi
->hwndChild
= lpBand
->hwndChild
;
1669 if (lprbbi
->fMask
& RBBIM_CHILDSIZE
) {
1670 lprbbi
->cxMinChild
= lpBand
->cxMinChild
;
1671 lprbbi
->cyMinChild
= lpBand
->cyMinChild
;
1672 lprbbi
->cyMaxChild
= lpBand
->cyMaxChild
;
1673 lprbbi
->cyChild
= lpBand
->cyChild
;
1674 lprbbi
->cyIntegral
= lpBand
->cyIntegral
;
1677 if (lprbbi
->fMask
& RBBIM_SIZE
)
1678 lprbbi
->cx
= lpBand
->cx
;
1680 if (lprbbi
->fMask
& RBBIM_BACKGROUND
)
1681 lprbbi
->hbmBack
= lpBand
->hbmBack
;
1683 if (lprbbi
->fMask
& RBBIM_ID
)
1684 lprbbi
->wID
= lpBand
->wID
;
1686 /* check for additional data */
1687 if (lprbbi
->cbSize
>= sizeof (REBARBANDINFOA
)) {
1688 if (lprbbi
->fMask
& RBBIM_IDEALSIZE
)
1689 lprbbi
->cxIdeal
= lpBand
->cxIdeal
;
1691 if (lprbbi
->fMask
& RBBIM_LPARAM
)
1692 lprbbi
->lParam
= lpBand
->lParam
;
1694 if (lprbbi
->fMask
& RBBIM_HEADERSIZE
)
1695 lprbbi
->cxHeader
= lpBand
->cxHeader
;
1698 REBAR_DumpBandInfo ((LPREBARBANDINFOA
)lprbbi
);
1705 REBAR_GetBarHeight (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1707 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
1710 nHeight
= infoPtr
->calcSize
.cy
;
1712 TRACE("height = %d\n", nHeight
);
1719 REBAR_GetBarInfo (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1721 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
1722 LPREBARINFO lpInfo
= (LPREBARINFO
)lParam
;
1727 if (lpInfo
->cbSize
< sizeof (REBARINFO
))
1730 TRACE("getting bar info!\n");
1732 if (infoPtr
->himl
) {
1733 lpInfo
->himl
= infoPtr
->himl
;
1734 lpInfo
->fMask
|= RBIM_IMAGELIST
;
1741 inline static LRESULT
1742 REBAR_GetBkColor (HWND hwnd
)
1744 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
1745 COLORREF clr
= infoPtr
->clrBk
;
1747 if (clr
== CLR_NONE
)
1748 clr
= GetSysColor (COLOR_BTNFACE
);
1750 TRACE("background color 0x%06lx!\n", clr
);
1756 /* << REBAR_GetColorScheme >> */
1757 /* << REBAR_GetDropTarget >> */
1761 REBAR_GetPalette (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1763 FIXME("empty stub!\n");
1770 REBAR_GetRect (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1772 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
1773 INT iBand
= (INT
)wParam
;
1774 LPRECT lprc
= (LPRECT
)lParam
;
1777 if ((iBand
< 0) && ((UINT
)iBand
>= infoPtr
->uNumBands
))
1782 lpBand
= &infoPtr
->bands
[iBand
];
1783 CopyRect (lprc
, &lpBand
->rcBand
);
1785 TRACE("band %d, (%d,%d)-(%d,%d)\n", iBand
,
1786 lprc
->left
, lprc
->top
, lprc
->right
, lprc
->bottom
);
1792 inline static LRESULT
1793 REBAR_GetRowCount (HWND hwnd
)
1795 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
1797 TRACE("%u\n", infoPtr
->uNumRows
);
1799 return infoPtr
->uNumRows
;
1804 REBAR_GetRowHeight (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1806 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
1807 INT iRow
= (INT
)wParam
;
1811 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
1813 for (i
=0; i
<infoPtr
->uNumBands
; i
++) {
1814 lpBand
= &infoPtr
->bands
[i
];
1815 if (lpBand
->iRow
!= iRow
) continue;
1816 if (dwStyle
& CCS_VERT
)
1817 j
= lpBand
->rcBand
.right
- lpBand
->rcBand
.left
;
1819 j
= lpBand
->rcBand
.bottom
- lpBand
->rcBand
.top
;
1820 if (j
> ret
) ret
= j
;
1823 TRACE("row %d, height %d\n", iRow
, ret
);
1829 inline static LRESULT
1830 REBAR_GetTextColor (HWND hwnd
)
1832 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
1834 TRACE("text color 0x%06lx!\n", infoPtr
->clrText
);
1836 return infoPtr
->clrText
;
1840 inline static LRESULT
1841 REBAR_GetToolTips (HWND hwnd
)
1843 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
1844 return infoPtr
->hwndToolTip
;
1848 inline static LRESULT
1849 REBAR_GetUnicodeFormat (HWND hwnd
)
1851 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
1852 return infoPtr
->bUnicode
;
1856 inline static LRESULT
1857 REBAR_GetVersion (HWND hwnd
)
1859 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
1860 TRACE("version %d\n", infoPtr
->iVersion
);
1861 return infoPtr
->iVersion
;
1866 REBAR_HitTest (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1868 /* REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */
1869 LPRBHITTESTINFO lprbht
= (LPRBHITTESTINFO
)lParam
;
1874 REBAR_InternalHitTest (hwnd
, &lprbht
->pt
, &lprbht
->flags
, &lprbht
->iBand
);
1876 return lprbht
->iBand
;
1881 REBAR_IdToIndex (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1883 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
1886 if (infoPtr
== NULL
)
1889 if (infoPtr
->uNumBands
< 1)
1892 for (i
= 0; i
< infoPtr
->uNumBands
; i
++) {
1893 if (infoPtr
->bands
[i
].wID
== (UINT
)wParam
) {
1894 TRACE("id %u is band %u found!\n", (UINT
)wParam
, i
);
1899 TRACE("id %u is not found\n", (UINT
)wParam
);
1905 REBAR_InsertBandA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1907 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
1908 LPREBARBANDINFOA lprbbi
= (LPREBARBANDINFOA
)lParam
;
1909 UINT uIndex
= (UINT
)wParam
;
1912 if (infoPtr
== NULL
)
1916 if (lprbbi
->cbSize
< REBARBANDINFO_V3_SIZEA
)
1919 /* trace the index as signed to see the -1 */
1920 TRACE("insert band at %d!\n", (INT
)uIndex
);
1921 REBAR_DumpBandInfo (lprbbi
);
1923 if (infoPtr
->uNumBands
== 0) {
1924 infoPtr
->bands
= (REBAR_BAND
*)COMCTL32_Alloc (sizeof (REBAR_BAND
));
1928 REBAR_BAND
*oldBands
= infoPtr
->bands
;
1930 (REBAR_BAND
*)COMCTL32_Alloc ((infoPtr
->uNumBands
+1)*sizeof(REBAR_BAND
));
1931 if (((INT
)uIndex
== -1) || (uIndex
> infoPtr
->uNumBands
))
1932 uIndex
= infoPtr
->uNumBands
;
1934 /* pre insert copy */
1936 memcpy (&infoPtr
->bands
[0], &oldBands
[0],
1937 uIndex
* sizeof(REBAR_BAND
));
1941 if (uIndex
< infoPtr
->uNumBands
- 1) {
1942 memcpy (&infoPtr
->bands
[uIndex
+1], &oldBands
[uIndex
],
1943 (infoPtr
->uNumBands
- uIndex
- 1) * sizeof(REBAR_BAND
));
1946 COMCTL32_Free (oldBands
);
1949 infoPtr
->uNumBands
++;
1951 TRACE("index %u!\n", uIndex
);
1953 /* initialize band (infoPtr->bands[uIndex])*/
1954 lpBand
= &infoPtr
->bands
[uIndex
];
1956 lpBand
->clrFore
= infoPtr
->clrText
;
1957 lpBand
->clrBack
= infoPtr
->clrBk
;
1958 lpBand
->hwndChild
= 0;
1959 lpBand
->hwndPrevParent
= 0;
1961 REBAR_CommonSetupBand (hwnd
, lprbbi
, lpBand
);
1962 lpBand
->lpText
= NULL
;
1963 if ((lprbbi
->fMask
& RBBIM_TEXT
) && (lprbbi
->lpText
)) {
1964 INT len
= MultiByteToWideChar( CP_ACP
, 0, lprbbi
->lpText
, -1, NULL
, 0 );
1966 lpBand
->lpText
= (LPWSTR
)COMCTL32_Alloc (len
*sizeof(WCHAR
));
1967 MultiByteToWideChar( CP_ACP
, 0, lprbbi
->lpText
, -1, lpBand
->lpText
, len
);
1971 REBAR_ValidateBand (hwnd
, infoPtr
, lpBand
);
1973 REBAR_DumpBand (hwnd
);
1975 REBAR_Layout (hwnd
, NULL
, FALSE
, FALSE
);
1976 REBAR_ForceResize (hwnd
);
1977 REBAR_MoveChildWindows (hwnd
);
1984 REBAR_InsertBandW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1986 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
1987 LPREBARBANDINFOW lprbbi
= (LPREBARBANDINFOW
)lParam
;
1988 UINT uIndex
= (UINT
)wParam
;
1991 if (infoPtr
== NULL
)
1995 if (lprbbi
->cbSize
< REBARBANDINFO_V3_SIZEW
)
1998 /* trace the index as signed to see the -1 */
1999 TRACE("insert band at %d!\n", (INT
)uIndex
);
2000 REBAR_DumpBandInfo ((LPREBARBANDINFOA
)lprbbi
);
2002 if (infoPtr
->uNumBands
== 0) {
2003 infoPtr
->bands
= (REBAR_BAND
*)COMCTL32_Alloc (sizeof (REBAR_BAND
));
2007 REBAR_BAND
*oldBands
= infoPtr
->bands
;
2009 (REBAR_BAND
*)COMCTL32_Alloc ((infoPtr
->uNumBands
+1)*sizeof(REBAR_BAND
));
2010 if (((INT
)uIndex
== -1) || (uIndex
> infoPtr
->uNumBands
))
2011 uIndex
= infoPtr
->uNumBands
;
2013 /* pre insert copy */
2015 memcpy (&infoPtr
->bands
[0], &oldBands
[0],
2016 uIndex
* sizeof(REBAR_BAND
));
2020 if (uIndex
< infoPtr
->uNumBands
- 1) {
2021 memcpy (&infoPtr
->bands
[uIndex
+1], &oldBands
[uIndex
],
2022 (infoPtr
->uNumBands
- uIndex
- 1) * sizeof(REBAR_BAND
));
2025 COMCTL32_Free (oldBands
);
2028 infoPtr
->uNumBands
++;
2030 TRACE("index %u!\n", uIndex
);
2032 /* initialize band (infoPtr->bands[uIndex])*/
2033 lpBand
= &infoPtr
->bands
[uIndex
];
2035 lpBand
->clrFore
= infoPtr
->clrText
;
2036 lpBand
->clrBack
= infoPtr
->clrBk
;
2037 lpBand
->hwndChild
= 0;
2038 lpBand
->hwndPrevParent
= 0;
2040 REBAR_CommonSetupBand (hwnd
, (LPREBARBANDINFOA
)lprbbi
, lpBand
);
2041 lpBand
->lpText
= NULL
;
2042 if ((lprbbi
->fMask
& RBBIM_TEXT
) && (lprbbi
->lpText
)) {
2043 INT len
= lstrlenW (lprbbi
->lpText
);
2045 lpBand
->lpText
= (LPWSTR
)COMCTL32_Alloc ((len
+ 1)*sizeof(WCHAR
));
2046 strcpyW (lpBand
->lpText
, lprbbi
->lpText
);
2050 REBAR_ValidateBand (hwnd
, infoPtr
, lpBand
);
2052 REBAR_DumpBand (hwnd
);
2054 REBAR_Layout (hwnd
, NULL
, FALSE
, FALSE
);
2055 REBAR_ForceResize (hwnd
);
2056 REBAR_MoveChildWindows (hwnd
);
2063 REBAR_MaximizeBand (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2065 /* REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */
2067 FIXME("(uBand = %u fIdeal = %s)\n",
2068 (UINT
)wParam
, lParam
? "TRUE" : "FALSE");
2076 REBAR_MinimizeBand (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2078 /* REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */
2080 FIXME("(uBand = %u)\n", (UINT
)wParam
);
2088 REBAR_MoveBand (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2090 /* REBAR_INFO *infoPtr = REBAR_GetInfoPtr (hwnd); */
2092 FIXME("(iFrom = %u iTof = %u)\n",
2093 (UINT
)wParam
, (UINT
)lParam
);
2101 REBAR_SetBandInfoA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2103 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
2104 LPREBARBANDINFOA lprbbi
= (LPREBARBANDINFOA
)lParam
;
2109 if (lprbbi
->cbSize
< REBARBANDINFO_V3_SIZEA
)
2111 if ((UINT
)wParam
>= infoPtr
->uNumBands
)
2114 TRACE("index %u\n", (UINT
)wParam
);
2115 REBAR_DumpBandInfo (lprbbi
);
2117 /* set band information */
2118 lpBand
= &infoPtr
->bands
[(UINT
)wParam
];
2120 REBAR_CommonSetupBand (hwnd
, lprbbi
, lpBand
);
2121 if (lprbbi
->fMask
& RBBIM_TEXT
) {
2122 if (lpBand
->lpText
) {
2123 COMCTL32_Free (lpBand
->lpText
);
2124 lpBand
->lpText
= NULL
;
2126 if (lprbbi
->lpText
) {
2127 INT len
= MultiByteToWideChar( CP_ACP
, 0, lprbbi
->lpText
, -1, NULL
, 0 );
2128 lpBand
->lpText
= (LPWSTR
)COMCTL32_Alloc (len
*sizeof(WCHAR
));
2129 MultiByteToWideChar( CP_ACP
, 0, lprbbi
->lpText
, -1, lpBand
->lpText
, len
);
2133 REBAR_ValidateBand (hwnd
, infoPtr
, lpBand
);
2135 REBAR_DumpBand (hwnd
);
2137 if (lprbbi
->fMask
& (RBBIM_CHILDSIZE
| RBBIM_SIZE
)) {
2138 REBAR_Layout (hwnd
, NULL
, TRUE
, FALSE
);
2139 REBAR_ForceResize (hwnd
);
2140 REBAR_MoveChildWindows (hwnd
);
2148 REBAR_SetBandInfoW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2150 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
2151 LPREBARBANDINFOW lprbbi
= (LPREBARBANDINFOW
)lParam
;
2156 if (lprbbi
->cbSize
< REBARBANDINFO_V3_SIZEW
)
2158 if ((UINT
)wParam
>= infoPtr
->uNumBands
)
2161 TRACE("index %u\n", (UINT
)wParam
);
2162 REBAR_DumpBandInfo ((LPREBARBANDINFOA
)lprbbi
);
2164 /* set band information */
2165 lpBand
= &infoPtr
->bands
[(UINT
)wParam
];
2167 REBAR_CommonSetupBand (hwnd
, (LPREBARBANDINFOA
)lprbbi
, lpBand
);
2168 if (lprbbi
->fMask
& RBBIM_TEXT
) {
2169 if (lpBand
->lpText
) {
2170 COMCTL32_Free (lpBand
->lpText
);
2171 lpBand
->lpText
= NULL
;
2173 if (lprbbi
->lpText
) {
2174 INT len
= lstrlenW (lprbbi
->lpText
);
2175 lpBand
->lpText
= (LPWSTR
)COMCTL32_Alloc ((len
+ 1)*sizeof(WCHAR
));
2176 strcpyW (lpBand
->lpText
, lprbbi
->lpText
);
2180 REBAR_ValidateBand (hwnd
, infoPtr
, lpBand
);
2182 REBAR_DumpBand (hwnd
);
2184 if (lprbbi
->fMask
& (RBBIM_CHILDSIZE
| RBBIM_SIZE
)) {
2185 REBAR_Layout (hwnd
, NULL
, TRUE
, FALSE
);
2186 REBAR_ForceResize (hwnd
);
2187 REBAR_MoveChildWindows (hwnd
);
2195 REBAR_SetBarInfo (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2197 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
2198 LPREBARINFO lpInfo
= (LPREBARINFO
)lParam
;
2203 if (lpInfo
->cbSize
< sizeof (REBARINFO
))
2206 TRACE("setting bar info!\n");
2208 if (lpInfo
->fMask
& RBIM_IMAGELIST
) {
2209 infoPtr
->himl
= lpInfo
->himl
;
2210 if (infoPtr
->himl
) {
2212 ImageList_GetIconSize (infoPtr
->himl
, &cx
, &cy
);
2213 infoPtr
->imageSize
.cx
= cx
;
2214 infoPtr
->imageSize
.cy
= cy
;
2217 infoPtr
->imageSize
.cx
= 0;
2218 infoPtr
->imageSize
.cy
= 0;
2220 TRACE("new image cx=%ld, cy=%ld\n", infoPtr
->imageSize
.cx
,
2221 infoPtr
->imageSize
.cy
);
2229 REBAR_SetBkColor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2231 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
2234 clrTemp
= infoPtr
->clrBk
;
2235 infoPtr
->clrBk
= (COLORREF
)lParam
;
2237 TRACE("background color 0x%06lx!\n", infoPtr
->clrBk
);
2243 /* << REBAR_SetColorScheme >> */
2244 /* << REBAR_SetPalette >> */
2248 REBAR_SetParent (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2250 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
2251 HWND hwndTemp
= infoPtr
->hwndNotify
;
2253 infoPtr
->hwndNotify
= (HWND
)wParam
;
2255 return (LRESULT
)hwndTemp
;
2260 REBAR_SetTextColor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2262 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
2265 clrTemp
= infoPtr
->clrText
;
2266 infoPtr
->clrText
= (COLORREF
)lParam
;
2268 TRACE("text color 0x%06lx!\n", infoPtr
->clrText
);
2274 /* << REBAR_SetTooltips >> */
2277 inline static LRESULT
2278 REBAR_SetUnicodeFormat (HWND hwnd
, WPARAM wParam
)
2280 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
2281 BOOL bTemp
= infoPtr
->bUnicode
;
2282 infoPtr
->bUnicode
= (BOOL
)wParam
;
2288 REBAR_SetVersion (HWND hwnd
, INT iVersion
)
2290 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
2291 INT iOldVersion
= infoPtr
->iVersion
;
2293 if (iVersion
> COMCTL32_VERSION
)
2296 infoPtr
->iVersion
= iVersion
;
2298 TRACE("new version %d\n", iVersion
);
2305 REBAR_ShowBand (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2307 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
2310 if (((INT
)wParam
< 0) || ((INT
)wParam
> infoPtr
->uNumBands
))
2313 lpBand
= &infoPtr
->bands
[(INT
)wParam
];
2316 TRACE("show band %d\n", (INT
)wParam
);
2317 lpBand
->fStyle
= lpBand
->fStyle
& ~RBBS_HIDDEN
;
2318 if (IsWindow (lpBand
->hwndChild
))
2319 ShowWindow (lpBand
->hwndChild
, SW_SHOW
);
2322 TRACE("hide band %d\n", (INT
)wParam
);
2323 lpBand
->fStyle
= lpBand
->fStyle
| RBBS_HIDDEN
;
2324 if (IsWindow (lpBand
->hwndChild
))
2325 ShowWindow (lpBand
->hwndChild
, SW_SHOW
);
2328 REBAR_Layout (hwnd
, NULL
, TRUE
, FALSE
);
2329 REBAR_ForceResize (hwnd
);
2330 REBAR_MoveChildWindows (hwnd
);
2337 REBAR_SizeToRect (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2339 LPRECT lpRect
= (LPRECT
)lParam
;
2345 TRACE("[%d %d %d %d]\n",
2346 lpRect
->left
, lpRect
->top
, lpRect
->right
, lpRect
->bottom
);
2348 /* what is going on???? */
2349 GetWindowRect(hwnd
, &t1
);
2350 TRACE("window rect [%d %d %d %d]\n",
2351 t1
.left
, t1
.top
, t1
.right
, t1
.bottom
);
2352 GetClientRect(hwnd
, &t1
);
2353 TRACE("client rect [%d %d %d %d]\n",
2354 t1
.left
, t1
.top
, t1
.right
, t1
.bottom
);
2356 REBAR_Layout (hwnd
, lpRect
, TRUE
, FALSE
);
2357 REBAR_ForceResize (hwnd
);
2358 REBAR_MoveChildWindows (hwnd
);
2365 REBAR_Create (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2367 REBAR_INFO
*infoPtr
;
2369 /* allocate memory for info structure */
2370 infoPtr
= (REBAR_INFO
*)COMCTL32_Alloc (sizeof(REBAR_INFO
));
2371 SetWindowLongA (hwnd
, 0, (DWORD
)infoPtr
);
2373 /* initialize info structure */
2374 infoPtr
->iVersion
= 0;
2375 infoPtr
->clrBk
= CLR_NONE
;
2376 infoPtr
->clrText
= GetSysColor (COLOR_BTNTEXT
);
2377 infoPtr
->ihitBand
= -1;
2378 infoPtr
->fStatus
= 0;
2380 infoPtr
->hcurArrow
= LoadCursorA (0, IDC_ARROWA
);
2381 infoPtr
->hcurHorz
= LoadCursorA (0, IDC_SIZEWEA
);
2382 infoPtr
->hcurVert
= LoadCursorA (0, IDC_SIZENSA
);
2383 infoPtr
->hcurDrag
= LoadCursorA (0, IDC_SIZEA
);
2385 infoPtr
->bUnicode
= IsWindowUnicode (hwnd
);
2387 if (GetWindowLongA (hwnd
, GWL_STYLE
) & RBS_AUTOSIZE
)
2388 FIXME("style RBS_AUTOSIZE set!\n");
2391 SendMessageA (hwnd
, WM_NOTIFYFORMAT
, (WPARAM
)hwnd
, NF_QUERY
);
2394 TRACE("created!\n");
2400 REBAR_Destroy (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2402 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
2407 /* free rebar bands */
2408 if ((infoPtr
->uNumBands
> 0) && infoPtr
->bands
) {
2409 /* clean up each band */
2410 for (i
= 0; i
< infoPtr
->uNumBands
; i
++) {
2411 lpBand
= &infoPtr
->bands
[i
];
2413 /* delete text strings */
2414 if (lpBand
->lpText
) {
2415 COMCTL32_Free (lpBand
->lpText
);
2416 lpBand
->lpText
= NULL
;
2418 /* destroy child window */
2419 DestroyWindow (lpBand
->hwndChild
);
2422 /* free band array */
2423 COMCTL32_Free (infoPtr
->bands
);
2424 infoPtr
->bands
= NULL
;
2427 DeleteObject (infoPtr
->hcurArrow
);
2428 DeleteObject (infoPtr
->hcurHorz
);
2429 DeleteObject (infoPtr
->hcurVert
);
2430 DeleteObject (infoPtr
->hcurDrag
);
2432 /* free rebar info data */
2433 COMCTL32_Free (infoPtr
);
2434 SetWindowLongA (hwnd
, 0, 0);
2435 TRACE("destroyed!\n");
2441 REBAR_EraseBkGnd (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2445 if (GetClipBox ( (HDC
)wParam
, &cliprect
))
2446 return REBAR_InternalEraseBkGnd (hwnd
, wParam
, lParam
, &cliprect
);
2452 REBAR_GetFont (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2454 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
2456 return (LRESULT
)infoPtr
->hFont
;
2461 REBAR_LButtonDown (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2463 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
2466 /* If InternalHitTest did not find a hit on the Gripper, */
2467 /* then ignore the button click. */
2468 if (infoPtr
->ihitBand
== -1) return 0;
2472 /* save off the LOWORD and HIWORD of lParam as initial x,y */
2473 lpBand
= &infoPtr
->bands
[infoPtr
->ihitBand
];
2474 infoPtr
->dragStart
= MAKEPOINTS(lParam
);
2475 infoPtr
->dragNow
= infoPtr
->dragStart
;
2476 infoPtr
->ihitoffset
= infoPtr
->dragStart
.x
- lpBand
->rcGripper
.left
;
2483 REBAR_LButtonUp (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2485 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
2490 /* If InternalHitTest did not find a hit on the Gripper, */
2491 /* then ignore the button click. */
2492 if (infoPtr
->ihitBand
== -1) return 0;
2494 infoPtr
->dragStart
.x
= 0;
2495 infoPtr
->dragStart
.y
= 0;
2496 infoPtr
->dragNow
= infoPtr
->dragStart
;
2497 infoPtr
->ihitBand
= -1;
2501 if (infoPtr
->fStatus
& BEGIN_DRAG_ISSUED
) {
2502 REBAR_Notify(hwnd
, (NMHDR
*) &layout
, RBN_LAYOUTCHANGED
);
2506 REBAR_Notify(hwnd
, (NMHDR
*) &enddrag
, RBN_ENDDRAG
);
2507 infoPtr
->fStatus
&= ~BEGIN_DRAG_ISSUED
;
2510 GetClientRect(hwnd
, &rect
);
2511 InvalidateRect(hwnd
, NULL
, TRUE
);
2518 REBAR_MouseMove (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2520 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
2521 REBAR_BAND
*band1
, *band2
;
2524 /* Validate entry as hit on Gripper has occured */
2525 if (GetCapture() != hwnd
) return 0;
2526 if (infoPtr
->ihitBand
== -1) return 0;
2528 ptsmove
= MAKEPOINTS(lParam
);
2530 /* if mouse did not move much, exit */
2531 if ((abs(ptsmove
.x
- infoPtr
->dragNow
.x
) <= mindragx
) &&
2532 (abs(ptsmove
.y
- infoPtr
->dragNow
.y
) <= mindragy
)) return 0;
2534 band1
= &infoPtr
->bands
[infoPtr
->ihitBand
-1];
2535 band2
= &infoPtr
->bands
[infoPtr
->ihitBand
];
2537 /* Test for valid drag case - must not be first band in row */
2538 if ((ptsmove
.y
< band2
->rcBand
.top
) ||
2539 (ptsmove
.y
> band2
->rcBand
.bottom
) ||
2540 ((infoPtr
->ihitBand
> 0) && (band1
->iRow
!= band2
->iRow
))) {
2541 FIXME("Cannot drag to other rows yet!!\n");
2544 REBAR_HandleLRDrag (hwnd
, infoPtr
, &ptsmove
);
2550 inline static LRESULT
2551 REBAR_NCCalcSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2553 if (GetWindowLongA (hwnd
, GWL_STYLE
) & WS_BORDER
) {
2554 ((LPRECT
)lParam
)->left
+= GetSystemMetrics(SM_CXEDGE
);
2555 ((LPRECT
)lParam
)->top
+= GetSystemMetrics(SM_CYEDGE
);
2556 ((LPRECT
)lParam
)->right
-= GetSystemMetrics(SM_CXEDGE
);
2557 ((LPRECT
)lParam
)->bottom
-= GetSystemMetrics(SM_CYEDGE
);
2565 REBAR_NCPaint (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2567 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
2571 if (dwStyle
& WS_MINIMIZE
)
2572 return 0; /* Nothing to do */
2574 DefWindowProcA (hwnd
, WM_NCPAINT
, wParam
, lParam
);
2576 if (!(hdc
= GetDCEx( hwnd
, 0, DCX_USESTYLE
| DCX_WINDOW
)))
2579 if (dwStyle
& WS_BORDER
) {
2580 GetWindowRect (hwnd
, &rcWindow
);
2581 OffsetRect (&rcWindow
, -rcWindow
.left
, -rcWindow
.top
);
2582 DrawEdge (hdc
, &rcWindow
, EDGE_ETCHED
, BF_RECT
);
2585 ReleaseDC( hwnd
, hdc
);
2592 REBAR_Paint (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2597 hdc
= wParam
==0 ? BeginPaint (hwnd
, &ps
) : (HDC
)wParam
;
2600 /* Erase area of paint if requested */
2601 REBAR_InternalEraseBkGnd (hwnd
, wParam
, lParam
, &ps
.rcPaint
);
2604 REBAR_Refresh (hwnd
, hdc
);
2606 EndPaint (hwnd
, &ps
);
2612 REBAR_SetCursor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2614 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
2615 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
2619 TRACE("code=0x%X id=0x%X\n", LOWORD(lParam
), HIWORD(lParam
));
2622 ScreenToClient (hwnd
, &pt
);
2624 REBAR_InternalHitTest (hwnd
, &pt
, &flags
, NULL
);
2626 if (flags
== RBHT_GRABBER
) {
2627 if ((dwStyle
& CCS_VERT
) &&
2628 !(dwStyle
& RBS_VERTICALGRIPPER
))
2629 SetCursor (infoPtr
->hcurVert
);
2631 SetCursor (infoPtr
->hcurHorz
);
2633 else if (flags
!= RBHT_CLIENT
)
2634 SetCursor (infoPtr
->hcurArrow
);
2641 REBAR_SetFont (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2643 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
2645 /* TEXTMETRIC32A tm; */
2646 HFONT hFont
/*, hOldFont */;
2649 infoPtr
->hFont
= (HFONT
)wParam
;
2651 hFont
= infoPtr
->hFont
? infoPtr
->hFont
: GetStockObject (SYSTEM_FONT
);
2654 hOldFont = SelectObject32 (hdc, hFont);
2655 GetTextMetrics32A (hdc, &tm);
2656 infoPtr->nHeight = tm.tmHeight + VERT_BORDER;
2657 SelectObject32 (hdc, hOldFont);
2658 ReleaseDC32 (0, hdc);
2662 REBAR_Layout (hwnd);
2663 hdc = GetDC32 (hwnd);
2664 REBAR_Refresh (hwnd, hdc);
2665 ReleaseDC32 (hwnd, hdc);
2673 REBAR_Size (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2675 REBAR_INFO
*infoPtr
= REBAR_GetInfoPtr (hwnd
);
2678 /* auto resize deadlock check */
2679 if (infoPtr
->fStatus
& AUTO_RESIZE
) {
2680 infoPtr
->fStatus
&= ~AUTO_RESIZE
;
2684 GetClientRect (hwnd
, &rcClient
);
2685 if ((lParam
== 0) && (rcClient
.right
== 0) && (rcClient
.bottom
== 0)) {
2686 /* native control seems to do this */
2687 GetClientRect (GetParent(hwnd
), &rcClient
);
2688 TRACE("sizing rebar, message and client zero, parent client (%d,%d)\n",
2689 rcClient
.right
, rcClient
.bottom
);
2692 TRACE("sizing rebar to (%d,%d), client (%d,%d)\n",
2693 LOWORD(lParam
), HIWORD(lParam
), rcClient
.right
, rcClient
.bottom
);
2696 REBAR_Layout (hwnd
, &rcClient
, FALSE
, TRUE
);
2697 REBAR_ForceResize (hwnd
);
2698 REBAR_MoveChildWindows (hwnd
);
2704 static LRESULT WINAPI
2705 REBAR_WindowProc (HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
2707 TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n", hwnd
, uMsg
, wParam
, lParam
);
2708 if (!REBAR_GetInfoPtr (hwnd
) && (uMsg
!= WM_CREATE
))
2709 return DefWindowProcA (hwnd
, uMsg
, wParam
, lParam
);
2712 /* case RB_BEGINDRAG: */
2715 return REBAR_DeleteBand (hwnd
, wParam
, lParam
);
2717 /* case RB_DRAGMOVE: */
2718 /* case RB_ENDDRAG: */
2720 case RB_GETBANDBORDERS
:
2721 return REBAR_GetBandBorders (hwnd
, wParam
, lParam
);
2723 case RB_GETBANDCOUNT
:
2724 return REBAR_GetBandCount (hwnd
);
2726 case RB_GETBANDINFO
: /* obsoleted after IE3, but we have to
2727 support it anyway. */
2728 case RB_GETBANDINFOA
:
2729 return REBAR_GetBandInfoA (hwnd
, wParam
, lParam
);
2731 case RB_GETBANDINFOW
:
2732 return REBAR_GetBandInfoW (hwnd
, wParam
, lParam
);
2734 case RB_GETBARHEIGHT
:
2735 return REBAR_GetBarHeight (hwnd
, wParam
, lParam
);
2738 return REBAR_GetBarInfo (hwnd
, wParam
, lParam
);
2741 return REBAR_GetBkColor (hwnd
);
2743 /* case RB_GETCOLORSCHEME: */
2744 /* case RB_GETDROPTARGET: */
2747 return REBAR_GetPalette (hwnd
, wParam
, lParam
);
2750 return REBAR_GetRect (hwnd
, wParam
, lParam
);
2752 case RB_GETROWCOUNT
:
2753 return REBAR_GetRowCount (hwnd
);
2755 case RB_GETROWHEIGHT
:
2756 return REBAR_GetRowHeight (hwnd
, wParam
, lParam
);
2758 case RB_GETTEXTCOLOR
:
2759 return REBAR_GetTextColor (hwnd
);
2761 case RB_GETTOOLTIPS
:
2762 return REBAR_GetToolTips (hwnd
);
2764 case RB_GETUNICODEFORMAT
:
2765 return REBAR_GetUnicodeFormat (hwnd
);
2767 case CCM_GETVERSION
:
2768 return REBAR_GetVersion (hwnd
);
2771 return REBAR_HitTest (hwnd
, wParam
, lParam
);
2774 return REBAR_IdToIndex (hwnd
, wParam
, lParam
);
2776 case RB_INSERTBANDA
:
2777 return REBAR_InsertBandA (hwnd
, wParam
, lParam
);
2779 case RB_INSERTBANDW
:
2780 return REBAR_InsertBandW (hwnd
, wParam
, lParam
);
2782 case RB_MAXIMIZEBAND
:
2783 return REBAR_MaximizeBand (hwnd
, wParam
, lParam
);
2785 case RB_MINIMIZEBAND
:
2786 return REBAR_MinimizeBand (hwnd
, wParam
, lParam
);
2789 return REBAR_MoveBand (hwnd
, wParam
, lParam
);
2791 case RB_SETBANDINFOA
:
2792 return REBAR_SetBandInfoA (hwnd
, wParam
, lParam
);
2794 case RB_SETBANDINFOW
:
2795 return REBAR_SetBandInfoW (hwnd
, wParam
, lParam
);
2798 return REBAR_SetBarInfo (hwnd
, wParam
, lParam
);
2801 return REBAR_SetBkColor (hwnd
, wParam
, lParam
);
2803 /* case RB_SETCOLORSCHEME: */
2804 /* case RB_SETPALETTE: */
2805 /* return REBAR_GetPalette (hwnd, wParam, lParam); */
2808 return REBAR_SetParent (hwnd
, wParam
, lParam
);
2810 case RB_SETTEXTCOLOR
:
2811 return REBAR_SetTextColor (hwnd
, wParam
, lParam
);
2813 /* case RB_SETTOOLTIPS: */
2815 case RB_SETUNICODEFORMAT
:
2816 return REBAR_SetUnicodeFormat (hwnd
, wParam
);
2818 case CCM_SETVERSION
:
2819 return REBAR_SetVersion (hwnd
, (INT
)wParam
);
2822 return REBAR_ShowBand (hwnd
, wParam
, lParam
);
2825 return REBAR_SizeToRect (hwnd
, wParam
, lParam
);
2829 return SendMessageA (GetParent (hwnd
), uMsg
, wParam
, lParam
);
2832 return REBAR_Create (hwnd
, wParam
, lParam
);
2835 return REBAR_Destroy (hwnd
, wParam
, lParam
);
2838 return REBAR_GetFont (hwnd
, wParam
, lParam
);
2840 case WM_LBUTTONDOWN
:
2841 return REBAR_LButtonDown (hwnd
, wParam
, lParam
);
2844 return REBAR_LButtonUp (hwnd
, wParam
, lParam
);
2847 return REBAR_MouseMove (hwnd
, wParam
, lParam
);
2850 return REBAR_NCCalcSize (hwnd
, wParam
, lParam
);
2853 return REBAR_NCPaint (hwnd
, wParam
, lParam
);
2856 return SendMessageA (GetParent (hwnd
), uMsg
, wParam
, lParam
);
2859 return REBAR_Paint (hwnd
, wParam
, lParam
);
2862 return REBAR_SetCursor (hwnd
, wParam
, lParam
);
2865 return REBAR_SetFont (hwnd
, wParam
, lParam
);
2868 return REBAR_Size (hwnd
, wParam
, lParam
);
2870 return SendMessageA(GetParent(hwnd
),uMsg
,wParam
,lParam
);
2872 /* case WM_TIMER: */
2874 /* case WM_WININICHANGE: */
2877 return REBAR_EraseBkGnd (hwnd
, wParam
, lParam
);
2880 if (uMsg
>= WM_USER
)
2881 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
2882 uMsg
, wParam
, lParam
);
2883 return DefWindowProcA (hwnd
, uMsg
, wParam
, lParam
);
2890 REBAR_Register (void)
2894 ZeroMemory (&wndClass
, sizeof(WNDCLASSA
));
2895 wndClass
.style
= CS_GLOBALCLASS
| CS_DBLCLKS
;
2896 wndClass
.lpfnWndProc
= (WNDPROC
)REBAR_WindowProc
;
2897 wndClass
.cbClsExtra
= 0;
2898 wndClass
.cbWndExtra
= sizeof(REBAR_INFO
*);
2899 wndClass
.hCursor
= 0;
2900 wndClass
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
2901 wndClass
.lpszClassName
= REBARCLASSNAMEA
;
2903 RegisterClassA (&wndClass
);
2905 mindragx
= GetSystemMetrics (SM_CXDRAG
);
2906 mindragy
= GetSystemMetrics (SM_CYDRAG
);
2912 REBAR_Unregister (void)
2914 UnregisterClassA (REBARCLASSNAMEA
, (HINSTANCE
)NULL
);