Improved the rebar control.
diff --git a/dlls/comctl32/rebar.c b/dlls/comctl32/rebar.c index 2936d96..78ea430 100644 --- a/dlls/comctl32/rebar.c +++ b/dlls/comctl32/rebar.c
@@ -4,40 +4,339 @@ * Copyright 1998 Eric Kohl * * NOTES - * This is just a dummy control. An author is needed! Any volunteers? + * An author is needed! Any volunteers? * I will only improve this control once in a while. * Eric <ekohl@abo.rhein-zeitung.de> * * TODO: - * - All messages. + * - Some messages. * - All notifications. + * - Layout code. + * - Display code. */ #include "windows.h" #include "commctrl.h" #include "rebar.h" #include "win.h" +#include "sysmetrics.h" #include "debug.h" +/* fDraw flags */ +#define DRAW_GRIPPER 1 +#define DRAW_IMAGE 2 +#define DRAW_TEXT 4 +#define DRAW_CHILD 8 + +#define GRIPPER_WIDTH 13 + + #define REBAR_GetInfoPtr(wndPtr) ((REBAR_INFO *)wndPtr->wExtra[0]) +static VOID +REBAR_DrawBand (HDC32 hdc, REBAR_INFO *infoPtr, REBAR_BAND *lpBand) +{ + + DrawEdge32 (hdc, &lpBand->rcBand, BDR_RAISEDINNER, BF_MIDDLE); + + /* draw background */ + + /* draw gripper */ + if (lpBand->fDraw & DRAW_GRIPPER) + DrawEdge32 (hdc, &lpBand->rcGripper, BDR_RAISEDINNER, BF_RECT | BF_MIDDLE); + + /* draw caption image */ + if (lpBand->fDraw & DRAW_IMAGE) + ImageList_Draw (infoPtr->himl, lpBand->iImage, hdc, + lpBand->rcCapImage.left, lpBand->rcCapImage.top, + ILD_TRANSPARENT); + + /* draw caption text */ + if (lpBand->fDraw & DRAW_TEXT) { + HFONT32 hOldFont = SelectObject32 (hdc, infoPtr->hFont); + INT32 oldBkMode = SetBkMode32 (hdc, TRANSPARENT); + DrawText32A (hdc, lpBand->lpText, -1, &lpBand->rcCapText, + DT_CENTER | DT_VCENTER | DT_SINGLELINE); + if (oldBkMode != TRANSPARENT) + SetBkMode32 (hdc, oldBkMode); + SelectObject32 (hdc, hOldFont); + } +} static VOID REBAR_Refresh (WND *wndPtr, HDC32 hdc) { + REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); + REBAR_BAND *lpBand; + UINT32 i; + + for (i = 0; i < infoPtr->uNumBands; i++) { + lpBand = &infoPtr->bands[i]; + + if ((lpBand->fStyle & RBBS_HIDDEN) || + ((wndPtr->dwStyle & CCS_VERT) && (lpBand->fStyle & RBBS_NOVERT))) + continue; + + REBAR_DrawBand (hdc, infoPtr, lpBand); + + } +} + + +static VOID +REBAR_CalcHorzBand (REBAR_INFO *infoPtr, REBAR_BAND *lpBand) +{ + lpBand->fDraw = 0; + + /* set initial caption image rectangle */ + SetRect32 (&lpBand->rcCapImage, 0, 0, 0, 0); + + /* image is visible */ + if ((lpBand->iImage > -1) && (infoPtr->himl)) { + lpBand->fDraw |= DRAW_IMAGE; + + lpBand->rcCapImage.right = lpBand->rcCapImage.left + infoPtr->imageSize.cx; + lpBand->rcCapImage.bottom = lpBand->rcCapImage.top + infoPtr->imageSize.cy; + + /* update band height */ + if (lpBand->uMinHeight < infoPtr->imageSize.cy + 2) { + lpBand->uMinHeight = infoPtr->imageSize.cy + 2; + lpBand->rcBand.bottom = lpBand->rcBand.top + lpBand->uMinHeight; + } + } + + /* set initial caption text rectangle */ + lpBand->rcCapText.left = lpBand->rcCapImage.right; + lpBand->rcCapText.top = lpBand->rcBand.top + 1; + lpBand->rcCapText.right = lpBand->rcCapText.left; + lpBand->rcCapText.bottom = lpBand->rcBand.bottom - 1; + + /* text is visible */ + if (lpBand->lpText) { + HDC32 hdc = GetDC32 (0); + HFONT32 hOldFont = SelectObject32 (hdc, infoPtr->hFont); + SIZE32 size; + + lpBand->fDraw |= DRAW_TEXT; + GetTextExtentPoint32A (hdc, lpBand->lpText, + lstrlen32A (lpBand->lpText), &size); + lpBand->rcCapText.right += size.cx; + + SelectObject32 (hdc, hOldFont); + ReleaseDC32 (0, hdc); + } + + /* set initial child window rectangle */ + lpBand->rcChild.left = lpBand->rcCapText.right + 4; + lpBand->rcChild.top = lpBand->rcBand.top + 2; + lpBand->rcChild.right = lpBand->rcBand.right - 4; + lpBand->rcChild.bottom = lpBand->rcBand.bottom - 2; + + /* calculate gripper rectangle */ + if ((!(lpBand->fStyle & RBBS_NOGRIPPER)) && + (!(lpBand->fStyle & RBBS_FIXEDSIZE)) && + ((lpBand->fStyle & RBBS_GRIPPERALWAYS) || + (infoPtr->uNumBands > 1))) { + lpBand->fDraw |= DRAW_GRIPPER; + lpBand->rcGripper.left = lpBand->rcBand.left + 3; + lpBand->rcGripper.right = lpBand->rcGripper.left + 3; + lpBand->rcGripper.top = lpBand->rcBand.top + 3; + lpBand->rcGripper.bottom = lpBand->rcBand.bottom - 3; + + /* move caption rectangles */ + OffsetRect32 (&lpBand->rcCapImage, GRIPPER_WIDTH, 0); + OffsetRect32 (&lpBand->rcCapText, GRIPPER_WIDTH, 0); + + /* adjust child rectangle */ + lpBand->rcChild.left += GRIPPER_WIDTH; + } + + +} + +static VOID +REBAR_Layout (WND *wndPtr, LPRECT32 lpRect) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); + REBAR_BAND *lpBand; + RECT32 rcClient; + INT32 x, y, cx, cy; + UINT32 i; + + if (lpRect) + rcClient = *lpRect; + else + GetClientRect32 (wndPtr->hwndSelf, &rcClient); + +// x = rcClient.left + 1; +// y = rcClient.top + 1; + x = 0; + y = 0; + cx = rcClient.right - rcClient.left - 2; + cy = 20; /* FIXME: fixed height */ + + for (i = 0; i < infoPtr->uNumBands; i++) { + lpBand = &infoPtr->bands[i]; + + if ((lpBand->fStyle & RBBS_HIDDEN) || + ((wndPtr->dwStyle & CCS_VERT) && (lpBand->fStyle & RBBS_NOVERT))) + continue; + + if (lpBand->fStyle & RBBS_VARIABLEHEIGHT) + cy = lpBand->cyMaxChild; + else if (lpBand->fStyle & RBBIM_CHILDSIZE) + cy = lpBand->cyMinChild; + else + cy = 20; + + lpBand->rcBand.left = x; + lpBand->rcBand.right = x + cx; + lpBand->rcBand.top = y; + lpBand->rcBand.bottom = y + cy; + + lpBand->uMinHeight = cy; + +/* + if (wndPtr->dwStyle & CCS_VERT) + REBAR_CalcVertBand (infoPtr, lpBand); + else +*/ + REBAR_CalcHorzBand (infoPtr, lpBand); + + y += lpBand->uMinHeight; + } + + infoPtr->calcSize.cx = rcClient.right - rcClient.left; + infoPtr->calcSize.cy = y; /* FIXME: fixed edge */ +} + + +static VOID +REBAR_ForceResize (WND *wndPtr) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); + RECT32 rc; + + TRACE (rebar, " to [%d x %d]!\n", + infoPtr->calcSize.cx, infoPtr->calcSize.cy); + + infoPtr->bAutoResize = TRUE; + + rc.left = 0; + rc.top = 0; + rc.right = infoPtr->calcSize.cx; + rc.bottom = infoPtr->calcSize.cy; + +// AdjustWindowRectEx32 (&rc, wndPtr->dwStyle, FALSE, 0); + + SetWindowPos32 (wndPtr->hwndSelf, 0, 0, 0, + rc.right - rc.left, rc.bottom - rc.top, + SWP_NOMOVE | SWP_NOZORDER | SWP_SHOWWINDOW); +} + + +static VOID +REBAR_MoveChildWindows (WND *wndPtr) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); + REBAR_BAND *lpBand; + UINT32 i; + + for (i = 0; i < infoPtr->uNumBands; i++) { + lpBand = &infoPtr->bands[i]; + + if (lpBand->fStyle & RBBS_HIDDEN) + continue; + if (lpBand->hwndChild) { + TRACE (rebar, "hwndChild = %x\n", lpBand->hwndChild); + + SetWindowPos32 (lpBand->hwndChild, HWND_TOP, + lpBand->rcChild.left, lpBand->rcChild.top, + lpBand->rcChild.right - lpBand->rcChild.left, + lpBand->rcChild.bottom - lpBand->rcChild.top, + SWP_SHOWWINDOW); + } + } +} + + +static void +REBAR_InternalHitTest (WND *wndPtr, LPPOINT32 lpPt, UINT32 *pFlags, INT32 *pBand) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr(wndPtr); + REBAR_BAND *lpBand; RECT32 rect; - HBRUSH32 hbrBk; + INT32 iCount; GetClientRect32 (wndPtr->hwndSelf, &rect); - hbrBk = CreateSolidBrush32 (RGB (192, 192, 192)); - FillRect32 (hdc, &rect, hbrBk); - DeleteObject32 (hbrBk); -} + *pFlags = RBHT_NOWHERE; + if (PtInRect32 (&rect, *lpPt)) + { + if (infoPtr->uNumBands == 0) { + *pFlags = RBHT_NOWHERE; + if (pBand) + *pBand = -1; + TRACE (rebar, "NOWHERE\n"); + return; + } + else { + /* somewhere inside */ + for (iCount = 0; iCount < infoPtr->uNumBands; iCount++) { + lpBand = &infoPtr->bands[iCount]; + if (PtInRect32 (&lpBand->rcBand, *lpPt)) { + if (pBand) + *pBand = iCount; + if (PtInRect32 (&lpBand->rcGripper, *lpPt)) { + *pFlags = RBHT_GRABBER; + TRACE (rebar, "ON GRABBER %d\n", iCount); + return; + } + else if (PtInRect32 (&lpBand->rcCapImage, *lpPt)) { + *pFlags = RBHT_CAPTION; + TRACE (rebar, "ON CAPTION %d\n", iCount); + return; + } + else if (PtInRect32 (&lpBand->rcCapText, *lpPt)) { + *pFlags = RBHT_CAPTION; + TRACE (rebar, "ON CAPTION %d\n", iCount); + return; + } + else if (PtInRect32 (&lpBand->rcChild, *lpPt)) { + *pFlags = RBHT_CLIENT; + TRACE (rebar, "ON CLIENT %d\n", iCount); + return; + } + else { + *pFlags = RBHT_NOWHERE; + TRACE (rebar, "NOWHERE %d\n", iCount); + return; + } + } + } + *pFlags = RBHT_NOWHERE; + if (pBand) + *pBand = -1; + + TRACE (rebar, "NOWHERE\n"); + return; + } + } + else { + *pFlags = RBHT_NOWHERE; + if (pBand) + *pBand = -1; + TRACE (rebar, "NOWHERE\n"); + return; + } + + TRACE (rebar, "flags=0x%X\n", *pFlags); + return; +} @@ -55,13 +354,50 @@ FIXME (rebar, "deleting band %u!\n", uBand); + if (infoPtr->uNumBands == 1) { + TRACE (rebar, " simple delete!\n"); + COMCTL32_Free (infoPtr->bands); + infoPtr->bands = NULL; + infoPtr->uNumBands = 0; + } + else { + REBAR_BAND *oldBands = infoPtr->bands; + TRACE(rebar, "complex delete! [uBand=%u]\n", uBand); + + infoPtr->uNumBands--; + infoPtr->bands = COMCTL32_Alloc (sizeof (REBAR_BAND) * infoPtr->uNumBands); + if (uBand > 0) { + memcpy (&infoPtr->bands[0], &oldBands[0], + uBand * sizeof(REBAR_BAND)); + } + + if (uBand < infoPtr->uNumBands) { + memcpy (&infoPtr->bands[uBand], &oldBands[uBand+1], + (infoPtr->uNumBands - uBand) * sizeof(REBAR_BAND)); + } + + COMCTL32_Free (oldBands); + } + + REBAR_Layout (wndPtr, NULL); + REBAR_ForceResize (wndPtr); + REBAR_MoveChildWindows (wndPtr); + return TRUE; } // << REBAR_DragMove >> // << REBAR_EndDrag >> -// << REBAR_GetBandBorders >> + + +static LRESULT +REBAR_GetBandBorders (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); + + return 0; +} __inline__ static LRESULT @@ -154,9 +490,11 @@ { REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); - FIXME (rebar, "returns fixed height of 40 pixels!\n"); + REBAR_Layout (wndPtr, NULL); - return 40; + FIXME (rebar, "height = %d\n", infoPtr->calcSize.cy); + + return infoPtr->calcSize.cy; } @@ -195,8 +533,66 @@ // << REBAR_GetColorScheme >> +// << REBAR_GetDropTarget >> -// << REBAR_GetRowHeight >> + +static LRESULT +REBAR_GetPalette (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + FIXME (rebar, "empty stub!\n"); + + return 0; +} + + +static LRESULT +REBAR_GetRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); + INT32 iBand = (INT32)wParam; + LPRECT32 lprc = (LPRECT32)lParam; + REBAR_BAND *lpBand; + + if ((iBand < 0) && ((UINT32)iBand >= infoPtr->uNumBands)) + return FALSE; + if (!lprc) + return FALSE; + + TRACE (rebar, "band %d\n", iBand); + + lpBand = &infoPtr->bands[iBand]; + CopyRect32 (lprc, &lpBand->rcBand); +/* + lprc->left = lpBand->rcBand.left; + lprc->top = lpBand->rcBand.top; + lprc->right = lpBand->rcBand.right; + lprc->bottom = lpBand->rcBand.bottom; +*/ + + return TRUE; +} + + +__inline__ static LRESULT +REBAR_GetRowCount (WND *wndPtr) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); + + FIXME (rebar, "%u : semi stub!\n", infoPtr->uNumBands); + + return infoPtr->uNumBands; +} + + +static LRESULT +REBAR_GetRowHeight (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ +// REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); + + FIXME (rebar, "-- height = 20: semi stub!\n"); + + return 20; +} __inline__ static LRESULT @@ -210,9 +606,32 @@ } -// << REBAR_GetToolTips >> +__inline__ static LRESULT +REBAR_GetToolTips (WND *wndPtr) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); + + return infoPtr->hwndToolTip; +} + + // << REBAR_GetUnicodeFormat >> -// << REBAR_HitTest >> + + +static LRESULT +REBAR_HitTest (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); + LPRBHITTESTINFO lprbht = (LPRBHITTESTINFO)lParam; + + if (!lprbht) + return -1; + + REBAR_InternalHitTest (wndPtr, &lprbht->pt, + &lprbht->flags, &lprbht->iBand); + + return lprbht->iBand; +} static LRESULT @@ -298,6 +717,10 @@ lpBand->clrFore = lprbbi->clrFore; lpBand->clrBack = lprbbi->clrBack; } + else { + lpBand->clrFore = CLR_NONE; + lpBand->clrBack = CLR_NONE; + } if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) { INT32 len = lstrlen32A (lprbbi->lpText); @@ -309,8 +732,11 @@ if (lprbbi->fMask & RBBIM_IMAGE) lpBand->iImage = lprbbi->iImage; + else + lpBand->iImage = -1; if (lprbbi->fMask & RBBIM_CHILD) { + TRACE (rebar, "hwndChild = %x\n", lprbbi->hwndChild); lpBand->hwndChild = lprbbi->hwndChild; lpBand->hwndPrevParent = SetParent32 (lpBand->hwndChild, wndPtr->hwndSelf); @@ -323,9 +749,18 @@ lpBand->cyChild = lprbbi->cyChild; lpBand->cyIntegral = lprbbi->cyIntegral; } + else { + lpBand->cxMinChild = -1; + lpBand->cyMinChild = -1; + lpBand->cyMaxChild = -1; + lpBand->cyChild = -1; + lpBand->cyIntegral = -1; + } if (lprbbi->fMask & RBBIM_SIZE) lpBand->cx = lprbbi->cx; + else + lpBand->cx = -1; if (lprbbi->fMask & RBBIM_BACKGROUND) lpBand->hbmBack = lprbbi->hbmBack; @@ -345,6 +780,11 @@ lpBand->cxHeader = lprbbi->cxHeader; } + + REBAR_Layout (wndPtr, NULL); + REBAR_ForceResize (wndPtr); + REBAR_MoveChildWindows (wndPtr); + return TRUE; } @@ -383,13 +823,13 @@ } if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) { -/* +#if 0 INT32 len = lstrlen32A (lprbbi->lpText); if (len > 0) { lpBand->lpText = (LPSTR)COMCTL32_Alloc (len + 1); lstrcpy32A (lpBand->lpText, lprbbi->lpText); } -*/ +#endif } if (lprbbi->fMask & RBBIM_IMAGE) @@ -430,6 +870,11 @@ lpBand->cxHeader = lprbbi->cxHeader; } + + REBAR_Layout (wndPtr, NULL); + REBAR_ForceResize (wndPtr); + REBAR_MoveChildWindows (wndPtr); + return TRUE; } @@ -451,8 +896,17 @@ TRACE (rebar, "setting bar info!\n"); - if (lpInfo->fMask & RBIM_IMAGELIST) + if (lpInfo->fMask & RBIM_IMAGELIST) { infoPtr->himl = lpInfo->himl; + if (infoPtr->himl) { + ImageList_GetIconSize (infoPtr->himl, &infoPtr->imageSize.cx, + &infoPtr->imageSize.cy); + } + else { + infoPtr->imageSize.cx = 0; + infoPtr->imageSize.cy = 0; + } + } return TRUE; } @@ -475,7 +929,18 @@ // << REBAR_SetColorScheme >> // << REBAR_SetPalette >> -// << REBAR_SetParent >> + + +static LRESULT +REBAR_SetParent (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); + HWND32 hwndTemp = infoPtr->hwndNotify; + + infoPtr->hwndNotify = (HWND32)wParam; + + return (LRESULT)hwndTemp; +} static LRESULT @@ -501,14 +966,26 @@ REBAR_ShowBand (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); + REBAR_BAND *lpBand; if (((INT32)wParam < 0) || ((INT32)wParam > infoPtr->uNumBands)) return FALSE; - if ((BOOL32)lParam) + lpBand = &infoPtr->bands[(INT32)wParam]; + + if ((BOOL32)lParam) { FIXME (rebar, "show band %d\n", (INT32)wParam); - else + lpBand->fStyle = lpBand->fStyle & ~RBBS_HIDDEN; + + } + else { FIXME (rebar, "hide band %d\n", (INT32)wParam); + lpBand->fStyle = lpBand->fStyle | RBBS_HIDDEN; + } + + REBAR_Layout (wndPtr, NULL); + REBAR_ForceResize (wndPtr); + REBAR_MoveChildWindows (wndPtr); return TRUE; } @@ -524,7 +1001,19 @@ return FALSE; FIXME (rebar, "layout change not implemented!\n"); + FIXME (rebar, "[%d %d %d %d]\n", + lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); +#if 0 + SetWindowPos32 (wndPtr->hwndSelf, 0, lpRect->left, lpRect->top, + lpRect->right - lpRect->left, lpRect->bottom - lpRect->top, + SWP_NOZORDER); +#endif + + infoPtr->calcSize.cx = lpRect->right - lpRect->left; + infoPtr->calcSize.cy = lpRect->bottom - lpRect->top; + + REBAR_ForceResize (wndPtr); return TRUE; } @@ -550,9 +1039,23 @@ } /* initialize info structure */ - infoPtr->clrText = CLR_NONE; + infoPtr->clrBk = CLR_NONE; infoPtr->clrText = RGB(0, 0, 0); + infoPtr->bAutoResize = FALSE; + infoPtr->hcurArrow = LoadCursor32A (0, IDC_ARROW32A); + infoPtr->hcurHorz = LoadCursor32A (0, IDC_SIZEWE32A); + infoPtr->hcurVert = LoadCursor32A (0, IDC_SIZENS32A); + infoPtr->hcurDrag = LoadCursor32A (0, IDC_SIZE32A); + + if (wndPtr->dwStyle & RBS_AUTOSIZE) + FIXME (rebar, "style RBS_AUTOSIZE set!\n"); + +#if 0 + SendMessage32A (wndPtr->parent->hwndSelf, WM_NOTIFYFORMAT, + (WPARAM32)wndPtr->hwndSelf, NF_QUERY); +#endif + TRACE (rebar, "created!\n"); return 0; } @@ -584,6 +1087,17 @@ infoPtr->bands = NULL; } + + + + DeleteObject32 (infoPtr->hcurArrow); + DeleteObject32 (infoPtr->hcurHorz); + DeleteObject32 (infoPtr->hcurVert); + DeleteObject32 (infoPtr->hcurDrag); + + + + /* free rebar info data */ COMCTL32_Free (infoPtr); @@ -592,6 +1106,78 @@ } +static LRESULT +REBAR_GetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr(wndPtr); + + return (LRESULT)infoPtr->hFont; +} + + +#if 0 +static LRESULT +REBAR_MouseMove (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr(wndPtr); + + return 0; +} +#endif + + +__inline__ static LRESULT +REBAR_NCCalcSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + LONG result = 0; + + if (wndPtr->class->style & CS_VREDRAW) + result |= WVR_VREDRAW; + if (wndPtr->class->style & CS_HREDRAW) + result |= WVR_HREDRAW; + + if (wndPtr->dwStyle & WS_BORDER) { + ((LPRECT32)lParam)->left += sysMetrics[SM_CXEDGE]; + ((LPRECT32)lParam)->top += sysMetrics[SM_CYEDGE]; + ((LPRECT32)lParam)->right -= sysMetrics[SM_CXEDGE]; + ((LPRECT32)lParam)->bottom -= sysMetrics[SM_CYEDGE]; + } + +// return DefWindowProc32A (wndPtr->hwndSelf, WM_NCCALCSIZE, wParam, lParam); + return result; +} + + +static LRESULT +REBAR_NCPaint (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + HWND32 hwnd = wndPtr->hwndSelf; + HDC32 hdc; + + if ( wndPtr->dwStyle & WS_MINIMIZE || + !WIN_IsWindowDrawable( wndPtr, 0 )) return 0; /* Nothing to do */ + + DefWindowProc32A (hwnd, WM_NCPAINT, wParam, lParam); + + if (!(hdc = GetDCEx32( hwnd, 0, DCX_USESTYLE | DCX_WINDOW ))) return 0; + + if (ExcludeVisRect( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left, + wndPtr->rectClient.top-wndPtr->rectWindow.top, + wndPtr->rectClient.right-wndPtr->rectWindow.left, + wndPtr->rectClient.bottom-wndPtr->rectWindow.top ) + == NULLREGION){ + ReleaseDC32( hwnd, hdc ); + return 0; + } + + if (!(wndPtr->flags & WIN_MANAGED) && (wndPtr->dwStyle & WS_BORDER)) + DrawEdge32 (hdc, &wndPtr->rectWindow, EDGE_ETCHED, BF_RECT); + + ReleaseDC32( hwnd, hdc ); + + return 0; +} + static LRESULT REBAR_Paint (WND *wndPtr, WPARAM32 wParam) @@ -607,6 +1193,124 @@ } +static LRESULT +REBAR_SetCursor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr(wndPtr); + POINT32 pt; + UINT32 flags; + + TRACE (rebar, "code=0x%X id=0x%X\n", LOWORD(lParam), HIWORD(lParam)); + + GetCursorPos32 (&pt); + ScreenToClient32 (wndPtr->hwndSelf, &pt); + + REBAR_InternalHitTest (wndPtr, &pt, &flags, NULL); + + if (flags == RBHT_GRABBER) { + if ((wndPtr->dwStyle & CCS_VERT) && + (wndPtr->dwStyle & RBS_VERTICALGRIPPER)) + SetCursor32 (infoPtr->hcurVert); + else + SetCursor32 (infoPtr->hcurHorz); + } + else if (flags != RBHT_CLIENT) + SetCursor32 (infoPtr->hcurArrow); + + return 0; +} + + +static LRESULT +REBAR_SetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr(wndPtr); + TEXTMETRIC32A tm; + HFONT32 hFont, hOldFont; + HDC32 hdc; + + infoPtr->hFont = (HFONT32)wParam; + + hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject32 (SYSTEM_FONT); +/* + hdc = GetDC32 (0); + hOldFont = SelectObject32 (hdc, hFont); + GetTextMetrics32A (hdc, &tm); + infoPtr->nHeight = tm.tmHeight + VERT_BORDER; + SelectObject32 (hdc, hOldFont); + ReleaseDC32 (0, hdc); +*/ + if (lParam) { +/* + REBAR_Layout (wndPtr); + hdc = GetDC32 (wndPtr->hwndSelf); + REBAR_Refresh (wndPtr, hdc); + ReleaseDC32 (wndPtr->hwndSelf, hdc); +*/ + } + + return 0; +} + +static LRESULT +REBAR_Size (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) +{ + REBAR_INFO *infoPtr = REBAR_GetInfoPtr(wndPtr); + RECT32 rcParent; + INT32 x, y, cx, cy; + + /* auto resize deadlock check */ + if (infoPtr->bAutoResize) { + infoPtr->bAutoResize = FALSE; + return 0; + } + + TRACE (rebar, "sizing rebar!\n"); + + /* get parent rectangle */ + GetClientRect32 (GetParent32 (wndPtr->hwndSelf), &rcParent); +/* + REBAR_Layout (wndPtr, &rcParent); + + if (wndPtr->dwStyle & CCS_VERT) { + if (wndPtr->dwStyle & CCS_LEFT == CCS_LEFT) { + x = rcParent.left; + y = rcParent.top; + cx = infoPtr->calcSize.cx; + cy = infoPtr->calcSize.cy; + } + else { + x = rcParent.right - infoPtr->calcSize.cx; + y = rcParent.top; + cx = infoPtr->calcSize.cx; + cy = infoPtr->calcSize.cy; + } + } + else { + if (wndPtr->dwStyle & CCS_TOP) { + x = rcParent.left; + y = rcParent.top; + cx = infoPtr->calcSize.cx; + cy = infoPtr->calcSize.cy; + } + else { + x = rcParent.left; + y = rcParent.bottom - infoPtr->calcSize.cy; + cx = infoPtr->calcSize.cx; + cy = infoPtr->calcSize.cy; + } + } + + SetWindowPos32 (wndPtr->hwndSelf, 0, x, y, cx, cy, + SWP_NOZORDER | SWP_SHOWWINDOW); +*/ + REBAR_Layout (wndPtr, NULL); + REBAR_ForceResize (wndPtr); + REBAR_MoveChildWindows (wndPtr); + + return 0; +} + LRESULT WINAPI REBAR_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam) @@ -645,17 +1349,29 @@ // case RB_GETCOLORSCHEME: // case RB_GETDROPTARGET: -// case RB_GETPALETTE: -// case RB_GETRECT: -// case RB_GETROWCOUNT: -// case RB_GETROWHEIGHT: + + case RB_GETPALETTE: + return REBAR_GetPalette (wndPtr, wParam, lParam); + + case RB_GETRECT: + return REBAR_GetRect (wndPtr, wParam, lParam); + + case RB_GETROWCOUNT: + return REBAR_GetRowCount (wndPtr); + + case RB_GETROWHEIGHT: + return REBAR_GetRowHeight (wndPtr, wParam, lParam); case RB_GETTEXTCOLOR: return REBAR_GetTextColor (wndPtr); -// case RB_GETTOOLTIPS: + case RB_GETTOOLTIPS: + return REBAR_GetToolTips (wndPtr); + // case RB_GETUNICODEFORMAT: -// case RB_HITTEST: + + case RB_HITTEST: + return REBAR_HitTest (wndPtr, wParam, lParam); case RB_IDTOINDEX: return REBAR_IdToIndex (wndPtr, wParam, lParam); @@ -681,7 +1397,9 @@ // case RB_SETCOLORSCHEME: // case RB_SETPALETTE: -// case RB_SETPARENT: + + case RB_SETPARENT: + return REBAR_SetParent (wndPtr, wParam, lParam); case RB_SETTEXTCOLOR: return REBAR_SetTextColor (wndPtr, wParam, lParam); @@ -702,15 +1420,29 @@ case WM_DESTROY: return REBAR_Destroy (wndPtr, wParam, lParam); -// case WM_GETFONT: + case WM_GETFONT: + return REBAR_GetFont (wndPtr, wParam, lParam); // case WM_MOUSEMOVE: // return REBAR_MouseMove (wndPtr, wParam, lParam); + case WM_NCCALCSIZE: + return REBAR_NCCalcSize (wndPtr, wParam, lParam); + + case WM_NCPAINT: + return REBAR_NCPaint (wndPtr, wParam, lParam); + case WM_PAINT: return REBAR_Paint (wndPtr, wParam); -// case WM_SETFONT: + case WM_SETCURSOR: + return REBAR_SetCursor (wndPtr, wParam, lParam); + + case WM_SETFONT: + return REBAR_SetFont (wndPtr, wParam, lParam); + + case WM_SIZE: + return REBAR_Size (wndPtr, wParam, lParam); // case WM_TIMER: @@ -726,8 +1458,8 @@ } -void -REBAR_Register (void) +VOID +REBAR_Register (VOID) { WNDCLASS32A wndClass; @@ -739,9 +1471,17 @@ wndClass.cbClsExtra = 0; wndClass.cbWndExtra = sizeof(REBAR_INFO *); wndClass.hCursor = 0; - wndClass.hbrBackground = (HBRUSH32) COLOR_BTNFACE + 1; +// wndClass.hbrBackground = (HBRUSH32)(COLOR_BTNFACE + 1); wndClass.lpszClassName = REBARCLASSNAME32A; RegisterClass32A (&wndClass); } + +VOID +REBAR_Unregister (VOID) +{ + if (GlobalFindAtom32A (REBARCLASSNAME32A)) + UnregisterClass32A (REBARCLASSNAME32A, (HINSTANCE32)NULL); +} +
diff --git a/include/rebar.h b/include/rebar.h index 8dd760b..52ba2d7 100644 --- a/include/rebar.h +++ b/include/rebar.h
@@ -26,23 +26,42 @@ LPARAM lParam; UINT32 cxHeader; + UINT32 uMinHeight; + UINT32 fDraw; /* drawing flags */ + RECT32 rcBand; /* calculated band rectangle */ + RECT32 rcGripper; /* calculated gripper rectangle */ + RECT32 rcCapImage; /* calculated caption image rectangle */ + RECT32 rcCapText; /* calculated caption text rectangle */ + RECT32 rcChild; /* calculated child rectangle */ + LPSTR lpText; HWND32 hwndPrevParent; } REBAR_BAND; - typedef struct tagREBAR_INFO { - COLORREF clrBk; /* background color */ - COLORREF clrText; /* text color */ - HIMAGELIST himl; /* handle to imagelist */ - UINT32 uNumBands; /* number of bands in the rebar */ + COLORREF clrBk; /* background color */ + COLORREF clrText; /* text color */ + HIMAGELIST himl; /* handle to imagelist */ + UINT32 uNumBands; /* number of bands in the rebar */ + HWND32 hwndToolTip; /* handle to the tool tip control */ + HWND32 hwndNotify; /* notification window (parent) */ + HFONT32 hFont; /* handle to the rebar's font */ + SIZE32 imageSize; /* image size (image list) */ - REBAR_BAND *bands; /* pointer to the array of rebar bands */ + SIZE32 calcSize; /* calculated rebar size */ + BOOL32 bAutoResize; /* auto resize deadlock flag */ + HCURSOR32 hcurArrow; /* handle to the arrow cursor */ + HCURSOR32 hcurHorz; /* handle to the EW cursor */ + HCURSOR32 hcurVert; /* handle to the NS cursor */ + HCURSOR32 hcurDrag; /* handle to the drag cursor */ + + REBAR_BAND *bands; /* pointer to the array of rebar bands */ } REBAR_INFO; -extern void REBAR_Register (void); +extern VOID REBAR_Register (VOID); +extern VOID REBAR_Unregister (VOID); #endif /* __WINE_REBAR_H */