Made more cross-platform by changing ->_fileno to fileno().
[wine/multimedia.git] / dlls / comctl32 / rebar.c
blob94bf588ae4e1f006dc2a3d12de1deac3ce8e6388
1 /*
2 * Rebar control
4 * Copyright 1998 Eric Kohl
6 * NOTES
7 * An author is needed! Any volunteers?
8 * I will only improve this control once in a while.
9 * Eric <ekohl@abo.rhein-zeitung.de>
11 * TODO:
12 * - vertical placement
13 * - ComboBox and ComboBoxEx placement
14 * - center image
15 * - Layout code.
16 * - Display code.
17 * - Some messages.
18 * - All notifications.
21 #include "windows.h"
22 #include "commctrl.h"
23 #include "rebar.h"
24 #include "win.h"
25 #include "sysmetrics.h"
26 #include "debug.h"
29 /* fDraw flags */
30 #define DRAW_GRIPPER 1
31 #define DRAW_IMAGE 2
32 #define DRAW_TEXT 4
33 #define DRAW_CHILD 8
35 #define GRIPPER_WIDTH 13
38 #define REBAR_GetInfoPtr(wndPtr) ((REBAR_INFO *)wndPtr->wExtra[0])
41 static VOID
42 REBAR_DrawBand (HDC32 hdc, REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
45 DrawEdge32 (hdc, &lpBand->rcBand, BDR_RAISEDINNER, BF_MIDDLE);
47 /* draw background */
49 /* draw gripper */
50 if (lpBand->fDraw & DRAW_GRIPPER)
51 DrawEdge32 (hdc, &lpBand->rcGripper, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE);
53 /* draw caption image */
54 if (lpBand->fDraw & DRAW_IMAGE) {
55 /* FIXME: center image */
56 POINT32 pt;
58 pt.y = (lpBand->rcCapImage.bottom + lpBand->rcCapImage.top - infoPtr->imageSize.cy)/2;
59 pt.x = (lpBand->rcCapImage.right + lpBand->rcCapImage.left - infoPtr->imageSize.cx)/2;
61 ImageList_Draw (infoPtr->himl, lpBand->iImage, hdc,
62 // lpBand->rcCapImage.left, lpBand->rcCapImage.top,
63 pt.x, pt.y,
64 ILD_TRANSPARENT);
67 /* draw caption text */
68 if (lpBand->fDraw & DRAW_TEXT) {
69 HFONT32 hOldFont = SelectObject32 (hdc, infoPtr->hFont);
70 INT32 oldBkMode = SetBkMode32 (hdc, TRANSPARENT);
71 DrawText32W (hdc, lpBand->lpText, -1, &lpBand->rcCapText,
72 DT_CENTER | DT_VCENTER | DT_SINGLELINE);
73 if (oldBkMode != TRANSPARENT)
74 SetBkMode32 (hdc, oldBkMode);
75 SelectObject32 (hdc, hOldFont);
80 static VOID
81 REBAR_Refresh (WND *wndPtr, HDC32 hdc)
83 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
84 REBAR_BAND *lpBand;
85 UINT32 i;
87 for (i = 0; i < infoPtr->uNumBands; i++) {
88 lpBand = &infoPtr->bands[i];
90 if ((lpBand->fStyle & RBBS_HIDDEN) ||
91 ((wndPtr->dwStyle & CCS_VERT) && (lpBand->fStyle & RBBS_NOVERT)))
92 continue;
94 REBAR_DrawBand (hdc, infoPtr, lpBand);
100 static VOID
101 REBAR_CalcHorzBand (REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
103 lpBand->fDraw = 0;
105 /* set initial caption image rectangle */
106 SetRect32 (&lpBand->rcCapImage, 0, 0, 0, 0);
108 /* image is visible */
109 if ((lpBand->iImage > -1) && (infoPtr->himl)) {
110 lpBand->fDraw |= DRAW_IMAGE;
112 lpBand->rcCapImage.right = lpBand->rcCapImage.left + infoPtr->imageSize.cx;
113 lpBand->rcCapImage.bottom = lpBand->rcCapImage.top + infoPtr->imageSize.cy;
115 /* update band height */
116 if (lpBand->uMinHeight < infoPtr->imageSize.cy + 2) {
117 lpBand->uMinHeight = infoPtr->imageSize.cy + 2;
118 lpBand->rcBand.bottom = lpBand->rcBand.top + lpBand->uMinHeight;
122 /* set initial caption text rectangle */
123 lpBand->rcCapText.left = lpBand->rcCapImage.right;
124 lpBand->rcCapText.top = lpBand->rcBand.top + 1;
125 lpBand->rcCapText.right = lpBand->rcCapText.left;
126 lpBand->rcCapText.bottom = lpBand->rcBand.bottom - 1;
128 /* text is visible */
129 if (lpBand->lpText) {
130 HDC32 hdc = GetDC32 (0);
131 HFONT32 hOldFont = SelectObject32 (hdc, infoPtr->hFont);
132 SIZE32 size;
134 lpBand->fDraw |= DRAW_TEXT;
135 GetTextExtentPoint32W (hdc, lpBand->lpText,
136 lstrlen32W (lpBand->lpText), &size);
137 lpBand->rcCapText.right += size.cx;
139 SelectObject32 (hdc, hOldFont);
140 ReleaseDC32 (0, hdc);
143 /* set initial child window rectangle */
144 if (lpBand->fStyle & RBBS_FIXEDSIZE) {
145 lpBand->rcChild.left = lpBand->rcCapText.right;
146 lpBand->rcChild.top = lpBand->rcBand.top;
147 lpBand->rcChild.right = lpBand->rcBand.right;
148 lpBand->rcChild.bottom = lpBand->rcBand.bottom;
150 else {
151 lpBand->rcChild.left = lpBand->rcCapText.right + 4;
152 lpBand->rcChild.top = lpBand->rcBand.top + 2;
153 lpBand->rcChild.right = lpBand->rcBand.right - 4;
154 lpBand->rcChild.bottom = lpBand->rcBand.bottom - 2;
157 /* calculate gripper rectangle */
158 if ((!(lpBand->fStyle & RBBS_NOGRIPPER)) &&
159 (!(lpBand->fStyle & RBBS_FIXEDSIZE)) &&
160 ((lpBand->fStyle & RBBS_GRIPPERALWAYS) ||
161 (infoPtr->uNumBands > 1))) {
162 lpBand->fDraw |= DRAW_GRIPPER;
163 lpBand->rcGripper.left = lpBand->rcBand.left + 3;
164 lpBand->rcGripper.right = lpBand->rcGripper.left + 3;
165 lpBand->rcGripper.top = lpBand->rcBand.top + 3;
166 lpBand->rcGripper.bottom = lpBand->rcBand.bottom - 3;
168 /* move caption rectangles */
169 OffsetRect32 (&lpBand->rcCapImage, GRIPPER_WIDTH, 0);
170 OffsetRect32 (&lpBand->rcCapText, GRIPPER_WIDTH, 0);
172 /* adjust child rectangle */
173 lpBand->rcChild.left += GRIPPER_WIDTH;
180 static VOID
181 REBAR_CalcVertBand (WND *wndPtr, REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
183 lpBand->fDraw = 0;
185 /* set initial caption image rectangle */
186 SetRect32 (&lpBand->rcCapImage, 0, 0, 0, 0);
188 /* image is visible */
189 if ((lpBand->iImage > -1) && (infoPtr->himl)) {
190 lpBand->fDraw |= DRAW_IMAGE;
192 lpBand->rcCapImage.right = lpBand->rcCapImage.left + infoPtr->imageSize.cx;
193 lpBand->rcCapImage.bottom = lpBand->rcCapImage.top + infoPtr->imageSize.cy;
195 /* update band width */
196 if (lpBand->uMinHeight < infoPtr->imageSize.cx + 2) {
197 lpBand->uMinHeight = infoPtr->imageSize.cx + 2;
198 lpBand->rcBand.right = lpBand->rcBand.left + lpBand->uMinHeight;
202 /* set initial caption text rectangle */
203 lpBand->rcCapText.left = lpBand->rcBand.left + 1;
204 lpBand->rcCapText.top = lpBand->rcCapImage.bottom;
205 lpBand->rcCapText.right = lpBand->rcBand.right - 1;
206 lpBand->rcCapText.bottom = lpBand->rcCapText.top;
208 /* text is visible */
209 if (lpBand->lpText) {
210 HDC32 hdc = GetDC32 (0);
211 HFONT32 hOldFont = SelectObject32 (hdc, infoPtr->hFont);
212 SIZE32 size;
214 lpBand->fDraw |= DRAW_TEXT;
215 GetTextExtentPoint32W (hdc, lpBand->lpText,
216 lstrlen32W (lpBand->lpText), &size);
217 // lpBand->rcCapText.right += size.cx;
218 lpBand->rcCapText.bottom += size.cy;
220 SelectObject32 (hdc, hOldFont);
221 ReleaseDC32 (0, hdc);
224 /* set initial child window rectangle */
225 if (lpBand->fStyle & RBBS_FIXEDSIZE) {
226 lpBand->rcChild.left = lpBand->rcBand.left;
227 lpBand->rcChild.top = lpBand->rcCapText.bottom;
228 lpBand->rcChild.right = lpBand->rcBand.right;
229 lpBand->rcChild.bottom = lpBand->rcBand.bottom;
231 else {
232 lpBand->rcChild.left = lpBand->rcBand.left + 2;
233 lpBand->rcChild.top = lpBand->rcCapText.bottom + 4;
234 lpBand->rcChild.right = lpBand->rcBand.right - 2;
235 lpBand->rcChild.bottom = lpBand->rcBand.bottom - 4;
238 /* calculate gripper rectangle */
239 if ((!(lpBand->fStyle & RBBS_NOGRIPPER)) &&
240 (!(lpBand->fStyle & RBBS_FIXEDSIZE)) &&
241 ((lpBand->fStyle & RBBS_GRIPPERALWAYS) ||
242 (infoPtr->uNumBands > 1))) {
243 lpBand->fDraw |= DRAW_GRIPPER;
245 if (wndPtr->dwStyle & RBS_VERTICALGRIPPER) {
246 /* adjust band width */
247 lpBand->rcBand.right += GRIPPER_WIDTH;
248 lpBand->uMinHeight += GRIPPER_WIDTH;
250 lpBand->rcGripper.left = lpBand->rcBand.left + 3;
251 lpBand->rcGripper.right = lpBand->rcGripper.left + 3;
252 lpBand->rcGripper.top = lpBand->rcBand.top + 3;
253 lpBand->rcGripper.bottom = lpBand->rcBand.bottom - 3;
255 /* move caption rectangles */
256 OffsetRect32 (&lpBand->rcCapImage, GRIPPER_WIDTH, 0);
257 OffsetRect32 (&lpBand->rcCapText, GRIPPER_WIDTH, 0);
259 /* adjust child rectangle */
260 lpBand->rcChild.left += GRIPPER_WIDTH;
262 else {
263 lpBand->rcGripper.left = lpBand->rcBand.left + 3;
264 lpBand->rcGripper.right = lpBand->rcBand.right - 3;
265 lpBand->rcGripper.top = lpBand->rcBand.top + 3;
266 lpBand->rcGripper.bottom = lpBand->rcGripper.top + 3;
268 /* move caption rectangles */
269 OffsetRect32 (&lpBand->rcCapImage, 0, GRIPPER_WIDTH);
270 OffsetRect32 (&lpBand->rcCapText, 0, GRIPPER_WIDTH);
272 /* adjust child rectangle */
273 lpBand->rcChild.top += GRIPPER_WIDTH;
279 static VOID
280 REBAR_Layout (WND *wndPtr, LPRECT32 lpRect)
282 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
283 REBAR_BAND *lpBand;
284 RECT32 rcClient;
285 INT32 x, y, cx, cy;
286 UINT32 i;
288 if (lpRect)
289 rcClient = *lpRect;
290 else
291 GetClientRect32 (wndPtr->hwndSelf, &rcClient);
293 x = 0;
294 y = 0;
296 if (wndPtr->dwStyle & CCS_VERT) {
297 cx = 20; /* FIXME: fixed height */
298 cy = rcClient.bottom - rcClient.top;
300 else {
301 cx = rcClient.right - rcClient.left;
302 cy = 20; /* FIXME: fixed height */
305 for (i = 0; i < infoPtr->uNumBands; i++) {
306 lpBand = &infoPtr->bands[i];
308 if ((lpBand->fStyle & RBBS_HIDDEN) ||
309 ((wndPtr->dwStyle & CCS_VERT) && (lpBand->fStyle & RBBS_NOVERT)))
310 continue;
313 if (wndPtr->dwStyle & CCS_VERT) {
314 if (lpBand->fStyle & RBBS_VARIABLEHEIGHT)
315 cx = lpBand->cyMaxChild;
316 else if (lpBand->fStyle & RBBIM_CHILDSIZE)
317 cx = lpBand->cyMinChild;
318 else
319 cx = 20; /* FIXME */
321 lpBand->rcBand.left = x;
322 lpBand->rcBand.right = x + cx;
323 lpBand->rcBand.top = y;
324 lpBand->rcBand.bottom = y + cy;
325 lpBand->uMinHeight = cx;
327 else {
328 if (lpBand->fStyle & RBBS_VARIABLEHEIGHT)
329 cy = lpBand->cyMaxChild;
330 else if (lpBand->fStyle & RBBIM_CHILDSIZE)
331 cy = lpBand->cyMinChild;
332 else
333 cy = 20; /* FIXME */
335 lpBand->rcBand.left = x;
336 lpBand->rcBand.right = x + cx;
337 lpBand->rcBand.top = y;
338 lpBand->rcBand.bottom = y + cy;
339 lpBand->uMinHeight = cy;
342 if (wndPtr->dwStyle & CCS_VERT) {
343 REBAR_CalcVertBand (wndPtr, infoPtr, lpBand);
344 x += lpBand->uMinHeight;
346 else {
347 REBAR_CalcHorzBand (infoPtr, lpBand);
348 y += lpBand->uMinHeight;
352 if (wndPtr->dwStyle & CCS_VERT) {
353 infoPtr->calcSize.cx = x;
354 infoPtr->calcSize.cy = rcClient.bottom - rcClient.top;
356 else {
357 infoPtr->calcSize.cx = rcClient.right - rcClient.left;
358 infoPtr->calcSize.cy = y;
363 static VOID
364 REBAR_ForceResize (WND *wndPtr)
366 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
367 RECT32 rc;
369 TRACE (rebar, " to [%d x %d]!\n",
370 infoPtr->calcSize.cx, infoPtr->calcSize.cy);
372 infoPtr->bAutoResize = TRUE;
374 rc.left = 0;
375 rc.top = 0;
376 rc.right = infoPtr->calcSize.cx;
377 rc.bottom = infoPtr->calcSize.cy;
379 if (wndPtr->dwStyle & WS_BORDER) {
380 InflateRect32 (&rc, sysMetrics[SM_CXEDGE], sysMetrics[SM_CYEDGE]);
383 SetWindowPos32 (wndPtr->hwndSelf, 0, 0, 0,
384 rc.right - rc.left, rc.bottom - rc.top,
385 SWP_NOMOVE | SWP_NOZORDER | SWP_SHOWWINDOW);
389 static VOID
390 REBAR_MoveChildWindows (WND *wndPtr)
392 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
393 REBAR_BAND *lpBand;
394 UINT32 i;
396 for (i = 0; i < infoPtr->uNumBands; i++) {
397 lpBand = &infoPtr->bands[i];
399 if (lpBand->fStyle & RBBS_HIDDEN)
400 continue;
401 if (lpBand->hwndChild) {
402 TRACE (rebar, "hwndChild = %x\n", lpBand->hwndChild);
404 if (WIDGETS_IsControl32 (WIN_FindWndPtr(lpBand->hwndChild), BIC32_COMBO)) {
405 INT32 nEditHeight, yPos;
406 RECT32 rc;
408 /* special placement code for combo box */
411 /* get size of edit line */
412 GetWindowRect32 (lpBand->hwndChild, &rc);
413 nEditHeight = rc.bottom - rc.top;
414 yPos = (lpBand->rcChild.bottom + lpBand->rcChild.top - nEditHeight)/2;
416 /* center combo box inside child area */
417 SetWindowPos32 (lpBand->hwndChild, HWND_TOP,
418 lpBand->rcChild.left, /*lpBand->rcChild.top*/ yPos,
419 lpBand->rcChild.right - lpBand->rcChild.left,
420 nEditHeight,
421 SWP_SHOWWINDOW);
423 #if 0
424 else if () {
425 /* special placement code for extended combo box */
429 #endif
430 else {
431 SetWindowPos32 (lpBand->hwndChild, HWND_TOP,
432 lpBand->rcChild.left, lpBand->rcChild.top,
433 lpBand->rcChild.right - lpBand->rcChild.left,
434 lpBand->rcChild.bottom - lpBand->rcChild.top,
435 SWP_SHOWWINDOW);
442 static void
443 REBAR_InternalHitTest (WND *wndPtr, LPPOINT32 lpPt, UINT32 *pFlags, INT32 *pBand)
445 REBAR_INFO *infoPtr = REBAR_GetInfoPtr(wndPtr);
446 REBAR_BAND *lpBand;
447 RECT32 rect;
448 INT32 iCount;
450 GetClientRect32 (wndPtr->hwndSelf, &rect);
452 *pFlags = RBHT_NOWHERE;
453 if (PtInRect32 (&rect, *lpPt))
455 if (infoPtr->uNumBands == 0) {
456 *pFlags = RBHT_NOWHERE;
457 if (pBand)
458 *pBand = -1;
459 TRACE (rebar, "NOWHERE\n");
460 return;
462 else {
463 /* somewhere inside */
464 for (iCount = 0; iCount < infoPtr->uNumBands; iCount++) {
465 lpBand = &infoPtr->bands[iCount];
466 if (PtInRect32 (&lpBand->rcBand, *lpPt)) {
467 if (pBand)
468 *pBand = iCount;
469 if (PtInRect32 (&lpBand->rcGripper, *lpPt)) {
470 *pFlags = RBHT_GRABBER;
471 TRACE (rebar, "ON GRABBER %d\n", iCount);
472 return;
474 else if (PtInRect32 (&lpBand->rcCapImage, *lpPt)) {
475 *pFlags = RBHT_CAPTION;
476 TRACE (rebar, "ON CAPTION %d\n", iCount);
477 return;
479 else if (PtInRect32 (&lpBand->rcCapText, *lpPt)) {
480 *pFlags = RBHT_CAPTION;
481 TRACE (rebar, "ON CAPTION %d\n", iCount);
482 return;
484 else if (PtInRect32 (&lpBand->rcChild, *lpPt)) {
485 *pFlags = RBHT_CLIENT;
486 TRACE (rebar, "ON CLIENT %d\n", iCount);
487 return;
489 else {
490 *pFlags = RBHT_NOWHERE;
491 TRACE (rebar, "NOWHERE %d\n", iCount);
492 return;
497 *pFlags = RBHT_NOWHERE;
498 if (pBand)
499 *pBand = -1;
501 TRACE (rebar, "NOWHERE\n");
502 return;
505 else {
506 *pFlags = RBHT_NOWHERE;
507 if (pBand)
508 *pBand = -1;
509 TRACE (rebar, "NOWHERE\n");
510 return;
513 TRACE (rebar, "flags=0x%X\n", *pFlags);
514 return;
519 // << REBAR_BeginDrag >>
522 static LRESULT
523 REBAR_DeleteBand (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
525 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
526 UINT32 uBand = (UINT32)wParam;
528 if (uBand >= infoPtr->uNumBands)
529 return FALSE;
531 FIXME (rebar, "deleting band %u!\n", uBand);
533 if (infoPtr->uNumBands == 1) {
534 TRACE (rebar, " simple delete!\n");
535 COMCTL32_Free (infoPtr->bands);
536 infoPtr->bands = NULL;
537 infoPtr->uNumBands = 0;
539 else {
540 REBAR_BAND *oldBands = infoPtr->bands;
541 TRACE(rebar, "complex delete! [uBand=%u]\n", uBand);
543 infoPtr->uNumBands--;
544 infoPtr->bands = COMCTL32_Alloc (sizeof (REBAR_BAND) * infoPtr->uNumBands);
545 if (uBand > 0) {
546 memcpy (&infoPtr->bands[0], &oldBands[0],
547 uBand * sizeof(REBAR_BAND));
550 if (uBand < infoPtr->uNumBands) {
551 memcpy (&infoPtr->bands[uBand], &oldBands[uBand+1],
552 (infoPtr->uNumBands - uBand) * sizeof(REBAR_BAND));
555 COMCTL32_Free (oldBands);
558 REBAR_Layout (wndPtr, NULL);
559 REBAR_ForceResize (wndPtr);
560 REBAR_MoveChildWindows (wndPtr);
562 return TRUE;
566 // << REBAR_DragMove >>
567 // << REBAR_EndDrag >>
570 static LRESULT
571 REBAR_GetBandBorders (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
573 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
575 return 0;
579 __inline__ static LRESULT
580 REBAR_GetBandCount (WND *wndPtr)
582 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
584 TRACE (rebar, "band count %u!\n", infoPtr->uNumBands);
586 return infoPtr->uNumBands;
590 static LRESULT
591 REBAR_GetBandInfo32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
593 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
594 LPREBARBANDINFO32A lprbbi = (LPREBARBANDINFO32A)lParam;
595 REBAR_BAND *lpBand;
597 if (lprbbi == NULL)
598 return FALSE;
599 if (lprbbi->cbSize < REBARBANDINFO_V3_SIZE32A)
600 return FALSE;
601 if ((UINT32)wParam >= infoPtr->uNumBands)
602 return FALSE;
604 TRACE (rebar, "index %u\n", (UINT32)wParam);
606 /* copy band information */
607 lpBand = &infoPtr->bands[(UINT32)wParam];
609 if (lprbbi->fMask & RBBIM_STYLE)
610 lprbbi->fStyle = lpBand->fStyle;
612 if (lprbbi->fMask & RBBIM_COLORS) {
613 lprbbi->clrFore = lpBand->clrFore;
614 lprbbi->clrBack = lpBand->clrBack;
617 if ((lprbbi->fMask & RBBIM_TEXT) &&
618 (lprbbi->lpText) && (lpBand->lpText)) {
619 lstrcpynWtoA (lprbbi->lpText, lpBand->lpText, lprbbi->cch);
622 if (lprbbi->fMask & RBBIM_IMAGE)
623 lprbbi->iImage = lpBand->iImage;
625 if (lprbbi->fMask & RBBIM_CHILD)
626 lprbbi->hwndChild = lpBand->hwndChild;
628 if (lprbbi->fMask & RBBIM_CHILDSIZE) {
629 lprbbi->cxMinChild = lpBand->cxMinChild;
630 lprbbi->cyMinChild = lpBand->cyMinChild;
631 lprbbi->cyMaxChild = lpBand->cyMaxChild;
632 lprbbi->cyChild = lpBand->cyChild;
633 lprbbi->cyIntegral = lpBand->cyIntegral;
636 if (lprbbi->fMask & RBBIM_SIZE)
637 lprbbi->cx = lpBand->cx;
639 if (lprbbi->fMask & RBBIM_BACKGROUND)
640 lprbbi->hbmBack = lpBand->hbmBack;
642 if (lprbbi->fMask & RBBIM_ID)
643 lprbbi->wID = lpBand->wID;
645 /* check for additional data */
646 if (lprbbi->cbSize >= sizeof (REBARBANDINFO32A)) {
647 if (lprbbi->fMask & RBBIM_IDEALSIZE)
648 lprbbi->cxIdeal = lpBand->cxIdeal;
650 if (lprbbi->fMask & RBBIM_LPARAM)
651 lprbbi->lParam = lpBand->lParam;
653 if (lprbbi->fMask & RBBIM_HEADERSIZE)
654 lprbbi->cxHeader = lpBand->cxHeader;
657 return TRUE;
661 static LRESULT
662 REBAR_GetBandInfo32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
664 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
665 LPREBARBANDINFO32W lprbbi = (LPREBARBANDINFO32W)lParam;
666 REBAR_BAND *lpBand;
668 if (lprbbi == NULL)
669 return FALSE;
670 if (lprbbi->cbSize < REBARBANDINFO_V3_SIZE32W)
671 return FALSE;
672 if ((UINT32)wParam >= infoPtr->uNumBands)
673 return FALSE;
675 TRACE (rebar, "index %u\n", (UINT32)wParam);
677 /* copy band information */
678 lpBand = &infoPtr->bands[(UINT32)wParam];
680 if (lprbbi->fMask & RBBIM_STYLE)
681 lprbbi->fStyle = lpBand->fStyle;
683 if (lprbbi->fMask & RBBIM_COLORS) {
684 lprbbi->clrFore = lpBand->clrFore;
685 lprbbi->clrBack = lpBand->clrBack;
688 if ((lprbbi->fMask & RBBIM_TEXT) &&
689 (lprbbi->lpText) && (lpBand->lpText)) {
690 lstrcpyn32W (lprbbi->lpText, lpBand->lpText, lprbbi->cch);
693 if (lprbbi->fMask & RBBIM_IMAGE)
694 lprbbi->iImage = lpBand->iImage;
696 if (lprbbi->fMask & RBBIM_CHILD)
697 lprbbi->hwndChild = lpBand->hwndChild;
699 if (lprbbi->fMask & RBBIM_CHILDSIZE) {
700 lprbbi->cxMinChild = lpBand->cxMinChild;
701 lprbbi->cyMinChild = lpBand->cyMinChild;
702 lprbbi->cyMaxChild = lpBand->cyMaxChild;
703 lprbbi->cyChild = lpBand->cyChild;
704 lprbbi->cyIntegral = lpBand->cyIntegral;
707 if (lprbbi->fMask & RBBIM_SIZE)
708 lprbbi->cx = lpBand->cx;
710 if (lprbbi->fMask & RBBIM_BACKGROUND)
711 lprbbi->hbmBack = lpBand->hbmBack;
713 if (lprbbi->fMask & RBBIM_ID)
714 lprbbi->wID = lpBand->wID;
716 /* check for additional data */
717 if (lprbbi->cbSize >= sizeof (REBARBANDINFO32A)) {
718 if (lprbbi->fMask & RBBIM_IDEALSIZE)
719 lprbbi->cxIdeal = lpBand->cxIdeal;
721 if (lprbbi->fMask & RBBIM_LPARAM)
722 lprbbi->lParam = lpBand->lParam;
724 if (lprbbi->fMask & RBBIM_HEADERSIZE)
725 lprbbi->cxHeader = lpBand->cxHeader;
728 return TRUE;
732 static LRESULT
733 REBAR_GetBarHeight (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
735 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
736 INT32 nHeight;
738 REBAR_Layout (wndPtr, NULL);
739 nHeight = infoPtr->calcSize.cy;
741 if (wndPtr->dwStyle & WS_BORDER)
742 nHeight += (2 * sysMetrics[SM_CYEDGE]);
744 FIXME (rebar, "height = %d\n", nHeight);
746 return nHeight;
750 static LRESULT
751 REBAR_GetBarInfo (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
753 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
754 LPREBARINFO lpInfo = (LPREBARINFO)lParam;
756 if (lpInfo == NULL)
757 return FALSE;
759 if (lpInfo->cbSize < sizeof (REBARINFO))
760 return FALSE;
762 TRACE (rebar, "getting bar info!\n");
764 if (infoPtr->himl) {
765 lpInfo->himl = infoPtr->himl;
766 lpInfo->fMask |= RBIM_IMAGELIST;
769 return TRUE;
773 __inline__ static LRESULT
774 REBAR_GetBkColor (WND *wndPtr)
776 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
778 TRACE (rebar, "background color 0x%06lx!\n", infoPtr->clrBk);
780 return infoPtr->clrBk;
784 // << REBAR_GetColorScheme >>
785 // << REBAR_GetDropTarget >>
788 static LRESULT
789 REBAR_GetPalette (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
791 FIXME (rebar, "empty stub!\n");
793 return 0;
797 static LRESULT
798 REBAR_GetRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
800 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
801 INT32 iBand = (INT32)wParam;
802 LPRECT32 lprc = (LPRECT32)lParam;
803 REBAR_BAND *lpBand;
805 if ((iBand < 0) && ((UINT32)iBand >= infoPtr->uNumBands))
806 return FALSE;
807 if (!lprc)
808 return FALSE;
810 TRACE (rebar, "band %d\n", iBand);
812 lpBand = &infoPtr->bands[iBand];
813 CopyRect32 (lprc, &lpBand->rcBand);
815 lprc->left = lpBand->rcBand.left;
816 lprc->top = lpBand->rcBand.top;
817 lprc->right = lpBand->rcBand.right;
818 lprc->bottom = lpBand->rcBand.bottom;
821 return TRUE;
825 __inline__ static LRESULT
826 REBAR_GetRowCount (WND *wndPtr)
828 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
830 FIXME (rebar, "%u : semi stub!\n", infoPtr->uNumBands);
832 return infoPtr->uNumBands;
836 static LRESULT
837 REBAR_GetRowHeight (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
839 // REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
841 FIXME (rebar, "-- height = 20: semi stub!\n");
843 return 20;
847 __inline__ static LRESULT
848 REBAR_GetTextColor (WND *wndPtr)
850 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
852 TRACE (rebar, "text color 0x%06lx!\n", infoPtr->clrText);
854 return infoPtr->clrText;
858 __inline__ static LRESULT
859 REBAR_GetToolTips (WND *wndPtr)
861 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
862 return infoPtr->hwndToolTip;
866 __inline__ static LRESULT
867 REBAR_GetUnicodeFormat (WND *wndPtr)
869 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
870 return infoPtr->bUnicode;
874 static LRESULT
875 REBAR_HitTest (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
877 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
878 LPRBHITTESTINFO lprbht = (LPRBHITTESTINFO)lParam;
880 if (!lprbht)
881 return -1;
883 REBAR_InternalHitTest (wndPtr, &lprbht->pt,
884 &lprbht->flags, &lprbht->iBand);
886 return lprbht->iBand;
890 static LRESULT
891 REBAR_IdToIndex (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
893 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
894 UINT32 i;
896 if (infoPtr == NULL)
897 return -1;
899 if (infoPtr->uNumBands < 1)
900 return -1;
902 TRACE (rebar, "id %u\n", (UINT32)wParam);
904 for (i = 0; i < infoPtr->uNumBands; i++) {
905 if (infoPtr->bands[i].wID == (UINT32)wParam) {
906 TRACE (rebar, "band %u found!\n", i);
907 return i;
911 TRACE (rebar, "no band found!\n");
912 return -1;
916 static LRESULT
917 REBAR_InsertBand32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
919 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
920 LPREBARBANDINFO32A lprbbi = (LPREBARBANDINFO32A)lParam;
921 UINT32 uIndex = (UINT32)wParam;
922 REBAR_BAND *lpBand;
924 if (infoPtr == NULL)
925 return FALSE;
926 if (lprbbi == NULL)
927 return FALSE;
928 if (lprbbi->cbSize < REBARBANDINFO_V3_SIZE32A)
929 return FALSE;
931 TRACE (rebar, "insert band at %u!\n", uIndex);
933 if (infoPtr->uNumBands == 0) {
934 infoPtr->bands = (REBAR_BAND *)COMCTL32_Alloc (sizeof (REBAR_BAND));
935 uIndex = 0;
937 else {
938 REBAR_BAND *oldBands = infoPtr->bands;
939 infoPtr->bands =
940 (REBAR_BAND *)COMCTL32_Alloc ((infoPtr->uNumBands+1)*sizeof(REBAR_BAND));
941 if (((INT32)uIndex == -1) || (uIndex > infoPtr->uNumBands))
942 uIndex = infoPtr->uNumBands;
944 /* pre insert copy */
945 if (uIndex > 0) {
946 memcpy (&infoPtr->bands[0], &oldBands[0],
947 uIndex * sizeof(REBAR_BAND));
950 /* post copy */
951 if (uIndex < infoPtr->uNumBands - 1) {
952 memcpy (&infoPtr->bands[uIndex+1], &oldBands[uIndex],
953 (infoPtr->uNumBands - uIndex - 1) * sizeof(REBAR_BAND));
956 COMCTL32_Free (oldBands);
959 infoPtr->uNumBands++;
961 TRACE (rebar, "index %u!\n", uIndex);
963 /* initialize band (infoPtr->bands[uIndex])*/
964 lpBand = &infoPtr->bands[uIndex];
966 if (lprbbi->fMask & RBBIM_STYLE)
967 lpBand->fStyle = lprbbi->fStyle;
969 if (lprbbi->fMask & RBBIM_COLORS) {
970 lpBand->clrFore = lprbbi->clrFore;
971 lpBand->clrBack = lprbbi->clrBack;
973 else {
974 lpBand->clrFore = CLR_NONE;
975 lpBand->clrBack = CLR_NONE;
978 if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) {
979 INT32 len = lstrlen32A (lprbbi->lpText);
980 if (len > 0) {
981 lpBand->lpText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
982 lstrcpyAtoW (lpBand->lpText, lprbbi->lpText);
986 if (lprbbi->fMask & RBBIM_IMAGE)
987 lpBand->iImage = lprbbi->iImage;
988 else
989 lpBand->iImage = -1;
991 if (lprbbi->fMask & RBBIM_CHILD) {
992 TRACE (rebar, "hwndChild = %x\n", lprbbi->hwndChild);
993 lpBand->hwndChild = lprbbi->hwndChild;
994 lpBand->hwndPrevParent =
995 SetParent32 (lpBand->hwndChild, wndPtr->hwndSelf);
998 if (lprbbi->fMask & RBBIM_CHILDSIZE) {
999 lpBand->cxMinChild = lprbbi->cxMinChild;
1000 lpBand->cyMinChild = lprbbi->cyMinChild;
1001 lpBand->cyMaxChild = lprbbi->cyMaxChild;
1002 lpBand->cyChild = lprbbi->cyChild;
1003 lpBand->cyIntegral = lprbbi->cyIntegral;
1005 else {
1006 lpBand->cxMinChild = -1;
1007 lpBand->cyMinChild = -1;
1008 lpBand->cyMaxChild = -1;
1009 lpBand->cyChild = -1;
1010 lpBand->cyIntegral = -1;
1013 if (lprbbi->fMask & RBBIM_SIZE)
1014 lpBand->cx = lprbbi->cx;
1015 else
1016 lpBand->cx = -1;
1018 if (lprbbi->fMask & RBBIM_BACKGROUND)
1019 lpBand->hbmBack = lprbbi->hbmBack;
1021 if (lprbbi->fMask & RBBIM_ID)
1022 lpBand->wID = lprbbi->wID;
1024 /* check for additional data */
1025 if (lprbbi->cbSize >= sizeof (REBARBANDINFO32A)) {
1026 if (lprbbi->fMask & RBBIM_IDEALSIZE)
1027 lpBand->cxIdeal = lprbbi->cxIdeal;
1029 if (lprbbi->fMask & RBBIM_LPARAM)
1030 lpBand->lParam = lprbbi->lParam;
1032 if (lprbbi->fMask & RBBIM_HEADERSIZE)
1033 lpBand->cxHeader = lprbbi->cxHeader;
1037 REBAR_Layout (wndPtr, NULL);
1038 REBAR_ForceResize (wndPtr);
1039 REBAR_MoveChildWindows (wndPtr);
1041 return TRUE;
1045 static LRESULT
1046 REBAR_InsertBand32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1048 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
1049 LPREBARBANDINFO32W lprbbi = (LPREBARBANDINFO32W)lParam;
1050 UINT32 uIndex = (UINT32)wParam;
1051 REBAR_BAND *lpBand;
1053 if (infoPtr == NULL)
1054 return FALSE;
1055 if (lprbbi == NULL)
1056 return FALSE;
1057 if (lprbbi->cbSize < REBARBANDINFO_V3_SIZE32W)
1058 return FALSE;
1060 TRACE (rebar, "insert band at %u!\n", uIndex);
1062 if (infoPtr->uNumBands == 0) {
1063 infoPtr->bands = (REBAR_BAND *)COMCTL32_Alloc (sizeof (REBAR_BAND));
1064 uIndex = 0;
1066 else {
1067 REBAR_BAND *oldBands = infoPtr->bands;
1068 infoPtr->bands =
1069 (REBAR_BAND *)COMCTL32_Alloc ((infoPtr->uNumBands+1)*sizeof(REBAR_BAND));
1070 if (((INT32)uIndex == -1) || (uIndex > infoPtr->uNumBands))
1071 uIndex = infoPtr->uNumBands;
1073 /* pre insert copy */
1074 if (uIndex > 0) {
1075 memcpy (&infoPtr->bands[0], &oldBands[0],
1076 uIndex * sizeof(REBAR_BAND));
1079 /* post copy */
1080 if (uIndex < infoPtr->uNumBands - 1) {
1081 memcpy (&infoPtr->bands[uIndex+1], &oldBands[uIndex],
1082 (infoPtr->uNumBands - uIndex - 1) * sizeof(REBAR_BAND));
1085 COMCTL32_Free (oldBands);
1088 infoPtr->uNumBands++;
1090 TRACE (rebar, "index %u!\n", uIndex);
1092 /* initialize band (infoPtr->bands[uIndex])*/
1093 lpBand = &infoPtr->bands[uIndex];
1095 if (lprbbi->fMask & RBBIM_STYLE)
1096 lpBand->fStyle = lprbbi->fStyle;
1098 if (lprbbi->fMask & RBBIM_COLORS) {
1099 lpBand->clrFore = lprbbi->clrFore;
1100 lpBand->clrBack = lprbbi->clrBack;
1102 else {
1103 lpBand->clrFore = CLR_NONE;
1104 lpBand->clrBack = CLR_NONE;
1107 if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) {
1108 INT32 len = lstrlen32W (lprbbi->lpText);
1109 if (len > 0) {
1110 lpBand->lpText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
1111 lstrcpy32W (lpBand->lpText, lprbbi->lpText);
1115 if (lprbbi->fMask & RBBIM_IMAGE)
1116 lpBand->iImage = lprbbi->iImage;
1117 else
1118 lpBand->iImage = -1;
1120 if (lprbbi->fMask & RBBIM_CHILD) {
1121 TRACE (rebar, "hwndChild = %x\n", lprbbi->hwndChild);
1122 lpBand->hwndChild = lprbbi->hwndChild;
1123 lpBand->hwndPrevParent =
1124 SetParent32 (lpBand->hwndChild, wndPtr->hwndSelf);
1127 if (lprbbi->fMask & RBBIM_CHILDSIZE) {
1128 lpBand->cxMinChild = lprbbi->cxMinChild;
1129 lpBand->cyMinChild = lprbbi->cyMinChild;
1130 lpBand->cyMaxChild = lprbbi->cyMaxChild;
1131 lpBand->cyChild = lprbbi->cyChild;
1132 lpBand->cyIntegral = lprbbi->cyIntegral;
1134 else {
1135 lpBand->cxMinChild = -1;
1136 lpBand->cyMinChild = -1;
1137 lpBand->cyMaxChild = -1;
1138 lpBand->cyChild = -1;
1139 lpBand->cyIntegral = -1;
1142 if (lprbbi->fMask & RBBIM_SIZE)
1143 lpBand->cx = lprbbi->cx;
1144 else
1145 lpBand->cx = -1;
1147 if (lprbbi->fMask & RBBIM_BACKGROUND)
1148 lpBand->hbmBack = lprbbi->hbmBack;
1150 if (lprbbi->fMask & RBBIM_ID)
1151 lpBand->wID = lprbbi->wID;
1153 /* check for additional data */
1154 if (lprbbi->cbSize >= sizeof (REBARBANDINFO32W)) {
1155 if (lprbbi->fMask & RBBIM_IDEALSIZE)
1156 lpBand->cxIdeal = lprbbi->cxIdeal;
1158 if (lprbbi->fMask & RBBIM_LPARAM)
1159 lpBand->lParam = lprbbi->lParam;
1161 if (lprbbi->fMask & RBBIM_HEADERSIZE)
1162 lpBand->cxHeader = lprbbi->cxHeader;
1166 REBAR_Layout (wndPtr, NULL);
1167 REBAR_ForceResize (wndPtr);
1168 REBAR_MoveChildWindows (wndPtr);
1170 return TRUE;
1174 // << REBAR_MaximizeBand >>
1175 // << REBAR_MinimizeBand >>
1176 // << REBAR_MoveBand >>
1179 static LRESULT
1180 REBAR_SetBandInfo32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1182 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
1183 LPREBARBANDINFO32A lprbbi = (LPREBARBANDINFO32A)lParam;
1184 REBAR_BAND *lpBand;
1186 if (lprbbi == NULL)
1187 return FALSE;
1188 if (lprbbi->cbSize < REBARBANDINFO_V3_SIZE32A)
1189 return FALSE;
1190 if ((UINT32)wParam >= infoPtr->uNumBands)
1191 return FALSE;
1193 TRACE (rebar, "index %u\n", (UINT32)wParam);
1195 /* set band information */
1196 lpBand = &infoPtr->bands[(UINT32)wParam];
1198 if (lprbbi->fMask & RBBIM_STYLE)
1199 lpBand->fStyle = lprbbi->fStyle;
1201 if (lprbbi->fMask & RBBIM_COLORS) {
1202 lpBand->clrFore = lprbbi->clrFore;
1203 lpBand->clrBack = lprbbi->clrBack;
1206 if (lprbbi->fMask & RBBIM_TEXT) {
1207 if (lpBand->lpText) {
1208 COMCTL32_Free (lpBand->lpText);
1209 lpBand->lpText = NULL;
1211 if (lprbbi->lpText) {
1212 INT32 len = lstrlen32A (lprbbi->lpText);
1213 lpBand->lpText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
1214 lstrcpyAtoW (lpBand->lpText, lprbbi->lpText);
1218 if (lprbbi->fMask & RBBIM_IMAGE)
1219 lpBand->iImage = lprbbi->iImage;
1221 if (lprbbi->fMask & RBBIM_CHILD) {
1222 if (lprbbi->hwndChild) {
1223 lpBand->hwndChild = lprbbi->hwndChild;
1224 lpBand->hwndPrevParent =
1225 SetParent32 (lpBand->hwndChild, wndPtr->hwndSelf);
1227 else {
1228 FIXME (rebar, "child: 0x%x prev parent: 0x%x\n",
1229 lpBand->hwndChild, lpBand->hwndPrevParent);
1230 // SetParent32 (lpBand->hwndChild, lpBand->hwndPrevParent);
1231 lpBand->hwndChild = 0;
1232 lpBand->hwndPrevParent = 0;
1236 if (lprbbi->fMask & RBBIM_CHILDSIZE) {
1237 lpBand->cxMinChild = lprbbi->cxMinChild;
1238 lpBand->cyMinChild = lprbbi->cyMinChild;
1239 lpBand->cyMaxChild = lprbbi->cyMaxChild;
1240 lpBand->cyChild = lprbbi->cyChild;
1241 lpBand->cyIntegral = lprbbi->cyIntegral;
1244 if (lprbbi->fMask & RBBIM_SIZE)
1245 lpBand->cx = lprbbi->cx;
1247 if (lprbbi->fMask & RBBIM_BACKGROUND)
1248 lpBand->hbmBack = lprbbi->hbmBack;
1250 if (lprbbi->fMask & RBBIM_ID)
1251 lpBand->wID = lprbbi->wID;
1253 /* check for additional data */
1254 if (lprbbi->cbSize >= sizeof (REBARBANDINFO32A)) {
1255 if (lprbbi->fMask & RBBIM_IDEALSIZE)
1256 lpBand->cxIdeal = lprbbi->cxIdeal;
1258 if (lprbbi->fMask & RBBIM_LPARAM)
1259 lpBand->lParam = lprbbi->lParam;
1261 if (lprbbi->fMask & RBBIM_HEADERSIZE)
1262 lpBand->cxHeader = lprbbi->cxHeader;
1266 REBAR_Layout (wndPtr, NULL);
1267 REBAR_ForceResize (wndPtr);
1268 REBAR_MoveChildWindows (wndPtr);
1270 return TRUE;
1274 static LRESULT
1275 REBAR_SetBandInfo32W (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1277 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
1278 LPREBARBANDINFO32W lprbbi = (LPREBARBANDINFO32W)lParam;
1279 REBAR_BAND *lpBand;
1281 if (lprbbi == NULL)
1282 return FALSE;
1283 if (lprbbi->cbSize < REBARBANDINFO_V3_SIZE32W)
1284 return FALSE;
1285 if ((UINT32)wParam >= infoPtr->uNumBands)
1286 return FALSE;
1288 TRACE (rebar, "index %u\n", (UINT32)wParam);
1290 /* set band information */
1291 lpBand = &infoPtr->bands[(UINT32)wParam];
1293 if (lprbbi->fMask & RBBIM_STYLE)
1294 lpBand->fStyle = lprbbi->fStyle;
1296 if (lprbbi->fMask & RBBIM_COLORS) {
1297 lpBand->clrFore = lprbbi->clrFore;
1298 lpBand->clrBack = lprbbi->clrBack;
1301 if (lprbbi->fMask & RBBIM_TEXT) {
1302 if (lpBand->lpText) {
1303 COMCTL32_Free (lpBand->lpText);
1304 lpBand->lpText = NULL;
1306 if (lprbbi->lpText) {
1307 INT32 len = lstrlen32W (lprbbi->lpText);
1308 lpBand->lpText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
1309 lstrcpy32W (lpBand->lpText, lprbbi->lpText);
1313 if (lprbbi->fMask & RBBIM_IMAGE)
1314 lpBand->iImage = lprbbi->iImage;
1316 if (lprbbi->fMask & RBBIM_CHILD) {
1317 if (lprbbi->hwndChild) {
1318 lpBand->hwndChild = lprbbi->hwndChild;
1319 lpBand->hwndPrevParent =
1320 SetParent32 (lpBand->hwndChild, wndPtr->hwndSelf);
1322 else {
1323 FIXME (rebar, "child: 0x%x prev parent: 0x%x\n",
1324 lpBand->hwndChild, lpBand->hwndPrevParent);
1325 // SetParent32 (lpBand->hwndChild, lpBand->hwndPrevParent);
1326 lpBand->hwndChild = 0;
1327 lpBand->hwndPrevParent = 0;
1331 if (lprbbi->fMask & RBBIM_CHILDSIZE) {
1332 lpBand->cxMinChild = lprbbi->cxMinChild;
1333 lpBand->cyMinChild = lprbbi->cyMinChild;
1334 lpBand->cyMaxChild = lprbbi->cyMaxChild;
1335 lpBand->cyChild = lprbbi->cyChild;
1336 lpBand->cyIntegral = lprbbi->cyIntegral;
1339 if (lprbbi->fMask & RBBIM_SIZE)
1340 lpBand->cx = lprbbi->cx;
1342 if (lprbbi->fMask & RBBIM_BACKGROUND)
1343 lpBand->hbmBack = lprbbi->hbmBack;
1345 if (lprbbi->fMask & RBBIM_ID)
1346 lpBand->wID = lprbbi->wID;
1348 /* check for additional data */
1349 if (lprbbi->cbSize >= sizeof (REBARBANDINFO32W)) {
1350 if (lprbbi->fMask & RBBIM_IDEALSIZE)
1351 lpBand->cxIdeal = lprbbi->cxIdeal;
1353 if (lprbbi->fMask & RBBIM_LPARAM)
1354 lpBand->lParam = lprbbi->lParam;
1356 if (lprbbi->fMask & RBBIM_HEADERSIZE)
1357 lpBand->cxHeader = lprbbi->cxHeader;
1361 REBAR_Layout (wndPtr, NULL);
1362 REBAR_ForceResize (wndPtr);
1363 REBAR_MoveChildWindows (wndPtr);
1365 return TRUE;
1369 static LRESULT
1370 REBAR_SetBarInfo (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1372 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
1373 LPREBARINFO lpInfo = (LPREBARINFO)lParam;
1375 if (lpInfo == NULL)
1376 return FALSE;
1378 if (lpInfo->cbSize < sizeof (REBARINFO))
1379 return FALSE;
1381 TRACE (rebar, "setting bar info!\n");
1383 if (lpInfo->fMask & RBIM_IMAGELIST) {
1384 infoPtr->himl = lpInfo->himl;
1385 if (infoPtr->himl) {
1386 ImageList_GetIconSize (infoPtr->himl, &infoPtr->imageSize.cx,
1387 &infoPtr->imageSize.cy);
1389 else {
1390 infoPtr->imageSize.cx = 0;
1391 infoPtr->imageSize.cy = 0;
1395 return TRUE;
1399 static LRESULT
1400 REBAR_SetBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1402 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
1403 COLORREF clrTemp;
1405 clrTemp = infoPtr->clrBk;
1406 infoPtr->clrBk = (COLORREF)lParam;
1408 TRACE (rebar, "background color 0x%06lx!\n", infoPtr->clrBk);
1410 return clrTemp;
1414 // << REBAR_SetColorScheme >>
1415 // << REBAR_SetPalette >>
1418 static LRESULT
1419 REBAR_SetParent (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1421 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
1422 HWND32 hwndTemp = infoPtr->hwndNotify;
1424 infoPtr->hwndNotify = (HWND32)wParam;
1426 return (LRESULT)hwndTemp;
1430 static LRESULT
1431 REBAR_SetTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1433 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
1434 COLORREF clrTemp;
1436 clrTemp = infoPtr->clrText;
1437 infoPtr->clrText = (COLORREF)lParam;
1439 TRACE (rebar, "text color 0x%06lx!\n", infoPtr->clrText);
1441 return clrTemp;
1445 // << REBAR_SetTooltips >>
1448 __inline__ static LRESULT
1449 REBAR_SetUnicodeFormat (WND *wndPtr, WPARAM32 wParam)
1451 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
1452 BOOL32 bTemp = infoPtr->bUnicode;
1453 infoPtr->bUnicode = (BOOL32)wParam;
1454 return bTemp;
1458 static LRESULT
1459 REBAR_ShowBand (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1461 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
1462 REBAR_BAND *lpBand;
1464 if (((INT32)wParam < 0) || ((INT32)wParam > infoPtr->uNumBands))
1465 return FALSE;
1467 lpBand = &infoPtr->bands[(INT32)wParam];
1469 if ((BOOL32)lParam) {
1470 TRACE (rebar, "show band %d\n", (INT32)wParam);
1471 lpBand->fStyle = lpBand->fStyle & ~RBBS_HIDDEN;
1472 if (IsWindow32 (lpBand->hwndChild))
1473 ShowWindow32 (lpBand->hwndChild, SW_SHOW);
1475 else {
1476 TRACE (rebar, "hide band %d\n", (INT32)wParam);
1477 lpBand->fStyle = lpBand->fStyle | RBBS_HIDDEN;
1478 if (IsWindow32 (lpBand->hwndChild))
1479 ShowWindow32 (lpBand->hwndChild, SW_SHOW);
1482 REBAR_Layout (wndPtr, NULL);
1483 REBAR_ForceResize (wndPtr);
1484 REBAR_MoveChildWindows (wndPtr);
1486 return TRUE;
1490 static LRESULT
1491 REBAR_SizeToRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1493 REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr);
1494 LPRECT32 lpRect = (LPRECT32)lParam;
1496 if (lpRect == NULL)
1497 return FALSE;
1499 FIXME (rebar, "layout change not implemented!\n");
1500 FIXME (rebar, "[%d %d %d %d]\n",
1501 lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
1503 #if 0
1504 SetWindowPos32 (wndPtr->hwndSelf, 0, lpRect->left, lpRect->top,
1505 lpRect->right - lpRect->left, lpRect->bottom - lpRect->top,
1506 SWP_NOZORDER);
1507 #endif
1509 infoPtr->calcSize.cx = lpRect->right - lpRect->left;
1510 infoPtr->calcSize.cy = lpRect->bottom - lpRect->top;
1512 REBAR_ForceResize (wndPtr);
1513 return TRUE;
1518 static LRESULT
1519 REBAR_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1521 REBAR_INFO *infoPtr;
1523 /* allocate memory for info structure */
1524 infoPtr = (REBAR_INFO *)COMCTL32_Alloc (sizeof(REBAR_INFO));
1525 wndPtr->wExtra[0] = (DWORD)infoPtr;
1527 if (infoPtr == NULL) {
1528 ERR (rebar, "could not allocate info memory!\n");
1529 return 0;
1532 if ((REBAR_INFO*)wndPtr->wExtra[0] != infoPtr) {
1533 ERR (rebar, "pointer assignment error!\n");
1534 return 0;
1537 /* initialize info structure */
1538 infoPtr->clrBk = CLR_NONE;
1539 infoPtr->clrText = RGB(0, 0, 0);
1541 infoPtr->bAutoResize = FALSE;
1542 infoPtr->hcurArrow = LoadCursor32A (0, IDC_ARROW32A);
1543 infoPtr->hcurHorz = LoadCursor32A (0, IDC_SIZEWE32A);
1544 infoPtr->hcurVert = LoadCursor32A (0, IDC_SIZENS32A);
1545 infoPtr->hcurDrag = LoadCursor32A (0, IDC_SIZE32A);
1547 infoPtr->bUnicode = IsWindowUnicode (wndPtr->hwndSelf);
1549 if (wndPtr->dwStyle & RBS_AUTOSIZE)
1550 FIXME (rebar, "style RBS_AUTOSIZE set!\n");
1552 #if 0
1553 SendMessage32A (wndPtr->parent->hwndSelf, WM_NOTIFYFORMAT,
1554 (WPARAM32)wndPtr->hwndSelf, NF_QUERY);
1555 #endif
1557 TRACE (rebar, "created!\n");
1558 return 0;
1562 static LRESULT
1563 REBAR_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1565 REBAR_INFO *infoPtr = REBAR_GetInfoPtr(wndPtr);
1566 REBAR_BAND *lpBand;
1567 INT32 i;
1570 /* free rebar bands */
1571 if ((infoPtr->uNumBands > 0) && infoPtr->bands) {
1572 /* clean up each band */
1573 for (i = 0; i < infoPtr->uNumBands; i++) {
1574 lpBand = &infoPtr->bands[i];
1576 /* delete text strings */
1577 if (lpBand->lpText) {
1578 COMCTL32_Free (lpBand->lpText);
1579 lpBand->lpText = NULL;
1581 /* destroy child window */
1582 DestroyWindow32 (lpBand->hwndChild);
1585 /* free band array */
1586 COMCTL32_Free (infoPtr->bands);
1587 infoPtr->bands = NULL;
1593 DeleteObject32 (infoPtr->hcurArrow);
1594 DeleteObject32 (infoPtr->hcurHorz);
1595 DeleteObject32 (infoPtr->hcurVert);
1596 DeleteObject32 (infoPtr->hcurDrag);
1601 /* free rebar info data */
1602 COMCTL32_Free (infoPtr);
1604 TRACE (rebar, "destroyed!\n");
1605 return 0;
1609 static LRESULT
1610 REBAR_GetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1612 REBAR_INFO *infoPtr = REBAR_GetInfoPtr(wndPtr);
1614 return (LRESULT)infoPtr->hFont;
1618 #if 0
1619 static LRESULT
1620 REBAR_MouseMove (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1622 REBAR_INFO *infoPtr = REBAR_GetInfoPtr(wndPtr);
1624 return 0;
1626 #endif
1629 __inline__ static LRESULT
1630 REBAR_NCCalcSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1632 if (wndPtr->dwStyle & WS_BORDER) {
1633 ((LPRECT32)lParam)->left += sysMetrics[SM_CXEDGE];
1634 ((LPRECT32)lParam)->top += sysMetrics[SM_CYEDGE];
1635 ((LPRECT32)lParam)->right -= sysMetrics[SM_CXEDGE];
1636 ((LPRECT32)lParam)->bottom -= sysMetrics[SM_CYEDGE];
1639 return 0;
1643 static LRESULT
1644 REBAR_NCPaint (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1646 HWND32 hwnd = wndPtr->hwndSelf;
1647 HDC32 hdc;
1649 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1650 !WIN_IsWindowDrawable( wndPtr, 0 )) return 0; /* Nothing to do */
1652 DefWindowProc32A (hwnd, WM_NCPAINT, wParam, lParam);
1654 if (!(hdc = GetDCEx32( hwnd, 0, DCX_USESTYLE | DCX_WINDOW ))) return 0;
1656 if (ExcludeVisRect( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1657 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1658 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1659 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1660 == NULLREGION){
1661 ReleaseDC32( hwnd, hdc );
1662 return 0;
1665 if (!(wndPtr->flags & WIN_MANAGED) && (wndPtr->dwStyle & WS_BORDER))
1666 DrawEdge32 (hdc, &wndPtr->rectWindow, EDGE_ETCHED, BF_RECT);
1668 ReleaseDC32( hwnd, hdc );
1670 return 0;
1674 static LRESULT
1675 REBAR_Paint (WND *wndPtr, WPARAM32 wParam)
1677 HDC32 hdc;
1678 PAINTSTRUCT32 ps;
1680 hdc = wParam==0 ? BeginPaint32 (wndPtr->hwndSelf, &ps) : (HDC32)wParam;
1681 REBAR_Refresh (wndPtr, hdc);
1682 if (!wParam)
1683 EndPaint32 (wndPtr->hwndSelf, &ps);
1684 return 0;
1688 static LRESULT
1689 REBAR_SetCursor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1691 REBAR_INFO *infoPtr = REBAR_GetInfoPtr(wndPtr);
1692 POINT32 pt;
1693 UINT32 flags;
1695 TRACE (rebar, "code=0x%X id=0x%X\n", LOWORD(lParam), HIWORD(lParam));
1697 GetCursorPos32 (&pt);
1698 ScreenToClient32 (wndPtr->hwndSelf, &pt);
1700 REBAR_InternalHitTest (wndPtr, &pt, &flags, NULL);
1702 if (flags == RBHT_GRABBER) {
1703 if ((wndPtr->dwStyle & CCS_VERT) &&
1704 !(wndPtr->dwStyle & RBS_VERTICALGRIPPER))
1705 SetCursor32 (infoPtr->hcurVert);
1706 else
1707 SetCursor32 (infoPtr->hcurHorz);
1709 else if (flags != RBHT_CLIENT)
1710 SetCursor32 (infoPtr->hcurArrow);
1712 return 0;
1716 static LRESULT
1717 REBAR_SetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1719 REBAR_INFO *infoPtr = REBAR_GetInfoPtr(wndPtr);
1720 TEXTMETRIC32A tm;
1721 HFONT32 hFont, hOldFont;
1722 HDC32 hdc;
1724 infoPtr->hFont = (HFONT32)wParam;
1726 hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject32 (SYSTEM_FONT);
1728 hdc = GetDC32 (0);
1729 hOldFont = SelectObject32 (hdc, hFont);
1730 GetTextMetrics32A (hdc, &tm);
1731 infoPtr->nHeight = tm.tmHeight + VERT_BORDER;
1732 SelectObject32 (hdc, hOldFont);
1733 ReleaseDC32 (0, hdc);
1735 if (lParam) {
1737 REBAR_Layout (wndPtr);
1738 hdc = GetDC32 (wndPtr->hwndSelf);
1739 REBAR_Refresh (wndPtr, hdc);
1740 ReleaseDC32 (wndPtr->hwndSelf, hdc);
1744 return 0;
1747 static LRESULT
1748 REBAR_Size (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1750 REBAR_INFO *infoPtr = REBAR_GetInfoPtr(wndPtr);
1751 RECT32 rcParent;
1752 INT32 x, y, cx, cy;
1754 /* auto resize deadlock check */
1755 if (infoPtr->bAutoResize) {
1756 infoPtr->bAutoResize = FALSE;
1757 return 0;
1760 TRACE (rebar, "sizing rebar!\n");
1762 /* get parent rectangle */
1763 GetClientRect32 (GetParent32 (wndPtr->hwndSelf), &rcParent);
1765 REBAR_Layout (wndPtr, &rcParent);
1767 if (wndPtr->dwStyle & CCS_VERT) {
1768 if (wndPtr->dwStyle & CCS_LEFT == CCS_LEFT) {
1769 x = rcParent.left;
1770 y = rcParent.top;
1771 cx = infoPtr->calcSize.cx;
1772 cy = infoPtr->calcSize.cy;
1774 else {
1775 x = rcParent.right - infoPtr->calcSize.cx;
1776 y = rcParent.top;
1777 cx = infoPtr->calcSize.cx;
1778 cy = infoPtr->calcSize.cy;
1781 else {
1782 if (wndPtr->dwStyle & CCS_TOP) {
1783 x = rcParent.left;
1784 y = rcParent.top;
1785 cx = infoPtr->calcSize.cx;
1786 cy = infoPtr->calcSize.cy;
1788 else {
1789 x = rcParent.left;
1790 y = rcParent.bottom - infoPtr->calcSize.cy;
1791 cx = infoPtr->calcSize.cx;
1792 cy = infoPtr->calcSize.cy;
1796 SetWindowPos32 (wndPtr->hwndSelf, 0, x, y, cx, cy,
1797 SWP_NOZORDER | SWP_SHOWWINDOW);
1799 REBAR_Layout (wndPtr, NULL);
1800 REBAR_ForceResize (wndPtr);
1801 REBAR_MoveChildWindows (wndPtr);
1803 return 0;
1807 LRESULT WINAPI
1808 REBAR_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
1810 WND *wndPtr = WIN_FindWndPtr(hwnd);
1812 switch (uMsg)
1814 // case RB_BEGINDRAG:
1816 case RB_DELETEBAND:
1817 return REBAR_DeleteBand (wndPtr, wParam, lParam);
1819 // case RB_DRAGMOVE:
1820 // case RB_ENDDRAG:
1821 // case RB_GETBANDBORDERS:
1823 case RB_GETBANDCOUNT:
1824 return REBAR_GetBandCount (wndPtr);
1826 // case RB_GETBANDINFO32: /* outdated, just for compatibility */
1828 case RB_GETBANDINFO32A:
1829 return REBAR_GetBandInfo32A (wndPtr, wParam, lParam);
1831 case RB_GETBANDINFO32W:
1832 return REBAR_GetBandInfo32W (wndPtr, wParam, lParam);
1834 case RB_GETBARHEIGHT:
1835 return REBAR_GetBarHeight (wndPtr, wParam, lParam);
1837 case RB_GETBARINFO:
1838 return REBAR_GetBarInfo (wndPtr, wParam, lParam);
1840 case RB_GETBKCOLOR:
1841 return REBAR_GetBkColor (wndPtr);
1843 // case RB_GETCOLORSCHEME:
1844 // case RB_GETDROPTARGET:
1846 case RB_GETPALETTE:
1847 return REBAR_GetPalette (wndPtr, wParam, lParam);
1849 case RB_GETRECT:
1850 return REBAR_GetRect (wndPtr, wParam, lParam);
1852 case RB_GETROWCOUNT:
1853 return REBAR_GetRowCount (wndPtr);
1855 case RB_GETROWHEIGHT:
1856 return REBAR_GetRowHeight (wndPtr, wParam, lParam);
1858 case RB_GETTEXTCOLOR:
1859 return REBAR_GetTextColor (wndPtr);
1861 case RB_GETTOOLTIPS:
1862 return REBAR_GetToolTips (wndPtr);
1864 case RB_GETUNICODEFORMAT:
1865 return REBAR_GetUnicodeFormat (wndPtr);
1867 case RB_HITTEST:
1868 return REBAR_HitTest (wndPtr, wParam, lParam);
1870 case RB_IDTOINDEX:
1871 return REBAR_IdToIndex (wndPtr, wParam, lParam);
1873 case RB_INSERTBAND32A:
1874 return REBAR_InsertBand32A (wndPtr, wParam, lParam);
1876 case RB_INSERTBAND32W:
1877 return REBAR_InsertBand32W (wndPtr, wParam, lParam);
1879 // case RB_MAXIMIZEBAND:
1880 // case RB_MINIMIZEBAND:
1881 // case RB_MOVEBAND:
1883 case RB_SETBANDINFO32A:
1884 return REBAR_SetBandInfo32A (wndPtr, wParam, lParam);
1886 case RB_SETBANDINFO32W:
1887 return REBAR_SetBandInfo32W (wndPtr, wParam, lParam);
1889 case RB_SETBARINFO:
1890 return REBAR_SetBarInfo (wndPtr, wParam, lParam);
1892 case RB_SETBKCOLOR:
1893 return REBAR_SetBkColor (wndPtr, wParam, lParam);
1895 // case RB_SETCOLORSCHEME:
1896 // case RB_SETPALETTE:
1898 case RB_SETPARENT:
1899 return REBAR_SetParent (wndPtr, wParam, lParam);
1901 case RB_SETTEXTCOLOR:
1902 return REBAR_SetTextColor (wndPtr, wParam, lParam);
1904 // case RB_SETTOOLTIPS:
1906 case RB_SETUNICODEFORMAT:
1907 return REBAR_SetUnicodeFormat (wndPtr, wParam);
1909 case RB_SHOWBAND:
1910 return REBAR_ShowBand (wndPtr, wParam, lParam);
1912 case RB_SIZETORECT:
1913 return REBAR_SizeToRect (wndPtr, wParam, lParam);
1916 case WM_CREATE:
1917 return REBAR_Create (wndPtr, wParam, lParam);
1919 case WM_DESTROY:
1920 return REBAR_Destroy (wndPtr, wParam, lParam);
1922 case WM_GETFONT:
1923 return REBAR_GetFont (wndPtr, wParam, lParam);
1925 // case WM_MOUSEMOVE:
1926 // return REBAR_MouseMove (wndPtr, wParam, lParam);
1928 case WM_NCCALCSIZE:
1929 return REBAR_NCCalcSize (wndPtr, wParam, lParam);
1931 case WM_NCPAINT:
1932 return REBAR_NCPaint (wndPtr, wParam, lParam);
1934 case WM_NOTIFY:
1935 return SendMessage32A (wndPtr->parent->hwndSelf, WM_NOTIFY,
1936 wParam, lParam);
1938 case WM_PAINT:
1939 return REBAR_Paint (wndPtr, wParam);
1941 case WM_SETCURSOR:
1942 return REBAR_SetCursor (wndPtr, wParam, lParam);
1944 case WM_SETFONT:
1945 return REBAR_SetFont (wndPtr, wParam, lParam);
1947 case WM_SIZE:
1948 return REBAR_Size (wndPtr, wParam, lParam);
1950 // case WM_TIMER:
1952 // case WM_WININICHANGE:
1954 default:
1955 if (uMsg >= WM_USER)
1956 ERR (rebar, "unknown msg %04x wp=%08x lp=%08lx\n",
1957 uMsg, wParam, lParam);
1958 return DefWindowProc32A (hwnd, uMsg, wParam, lParam);
1960 return 0;
1964 VOID
1965 REBAR_Register (VOID)
1967 WNDCLASS32A wndClass;
1969 if (GlobalFindAtom32A (REBARCLASSNAME32A)) return;
1971 ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
1972 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
1973 wndClass.lpfnWndProc = (WNDPROC32)REBAR_WindowProc;
1974 wndClass.cbClsExtra = 0;
1975 wndClass.cbWndExtra = sizeof(REBAR_INFO *);
1976 wndClass.hCursor = 0;
1977 wndClass.hbrBackground = (HBRUSH32)(COLOR_BTNFACE + 1);
1978 wndClass.lpszClassName = REBARCLASSNAME32A;
1980 RegisterClass32A (&wndClass);
1984 VOID
1985 REBAR_Unregister (VOID)
1987 if (GlobalFindAtom32A (REBARCLASSNAME32A))
1988 UnregisterClass32A (REBARCLASSNAME32A, (HINSTANCE32)NULL);