/* * Rebar control * * Copyright 1998 Eric Kohl * * NOTES * This is just a dummy control. An author is needed! Any volunteers? * I will only improve this control once in a while. * Eric * * TODO: * - All messages. * - All notifications. */ #include "windows.h" #include "commctrl.h" #include "rebar.h" #include "heap.h" #include "win.h" #include "debug.h" #define REBAR_GetInfoPtr(wndPtr) ((REBAR_INFO *)wndPtr->wExtra[0]) static VOID REBAR_Refresh (WND *wndPtr, HDC32 hdc) { RECT32 rect; HBRUSH32 hbrBk; GetClientRect32 (wndPtr->hwndSelf, &rect); hbrBk = CreateSolidBrush32 (RGB (192, 192, 192)); FillRect32 (hdc, &rect, hbrBk); DeleteObject32 (hbrBk); } // << REBAR_BeginDrag >> // << REBAR_DeleteBand >> // << REBAR_DragMove >> // << REBAR_EndDrag >> // << REBAR_GetBandBorders >> __inline__ static LRESULT REBAR_GetBandCount (WND *wndPtr) { REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); TRACE (rebar, "band count %u!\n", infoPtr->uNumBands); return infoPtr->uNumBands; } static LRESULT REBAR_GetBandInfo32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); LPREBARBANDINFO32A lprbbi = (LPREBARBANDINFO32A)lParam; REBAR_BAND *lpBand; if (lprbbi == NULL) return FALSE; if (lprbbi->cbSize < REBARBANDINFO_V3_SIZE32A) return FALSE; if ((UINT32)wParam >= infoPtr->uNumBands) return FALSE; TRACE (rebar, "index %u\n", (UINT32)wParam); /* copy band information */ lpBand = &infoPtr->bands[(UINT32)wParam]; if (lprbbi->fMask & RBBIM_STYLE) lprbbi->fStyle = lpBand->fStyle; if (lprbbi->fMask & RBBIM_COLORS) { lprbbi->clrFore = lpBand->clrFore; lprbbi->clrBack = lpBand->clrBack; } if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText) && (lpBand->lpText)) { lstrcpyn32A (lprbbi->lpText, lpBand->lpText, lprbbi->cch); } if (lprbbi->fMask & RBBIM_IMAGE) lprbbi->iImage = lpBand->iImage; if (lprbbi->fMask & RBBIM_CHILD) lprbbi->hwndChild = lpBand->hwndChild; if (lprbbi->fMask & RBBIM_CHILDSIZE) { lprbbi->cxMinChild = lpBand->cxMinChild; lprbbi->cyMinChild = lpBand->cyMinChild; lprbbi->cyMaxChild = lpBand->cyMaxChild; lprbbi->cyChild = lpBand->cyChild; lprbbi->cyIntegral = lpBand->cyIntegral; } if (lprbbi->fMask & RBBIM_SIZE) lprbbi->cx = lpBand->cx; if (lprbbi->fMask & RBBIM_BACKGROUND) lprbbi->hbmBack = lpBand->hbmBack; if (lprbbi->fMask & RBBIM_ID) lprbbi->wID = lpBand->wID; /* check for additional data */ if (lprbbi->cbSize >= sizeof (REBARBANDINFO32A)) { if (lprbbi->fMask & RBBIM_IDEALSIZE) lprbbi->cxIdeal = lpBand->cxIdeal; if (lprbbi->fMask & RBBIM_LPARAM) lprbbi->lParam = lpBand->lParam; if (lprbbi->fMask & RBBIM_HEADERSIZE) lprbbi->cxHeader = lpBand->cxHeader; } return TRUE; } // << REBAR_GetBandInfo32W >> static LRESULT REBAR_GetBarHeight (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); FIXME (rebar, "returns fixed height of 40 pixels!\n"); return 40; } static LRESULT REBAR_GetBarInfo (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); LPREBARINFO lpInfo = (LPREBARINFO)lParam; if (lpInfo == NULL) return FALSE; if (lpInfo->cbSize < sizeof (REBARINFO)) return FALSE; TRACE (rebar, "getting bar info!\n"); if (infoPtr->himl) { lpInfo->himl = infoPtr->himl; lpInfo->fMask |= RBIM_IMAGELIST; } return TRUE; } __inline__ static LRESULT REBAR_GetBkColor (WND *wndPtr) { REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); TRACE (rebar, "background color 0x%06lx!\n", infoPtr->clrBk); return infoPtr->clrBk; } // << REBAR_GetColorScheme >> // << REBAR_GetRowHeight >> __inline__ static LRESULT REBAR_GetTextColor (WND *wndPtr) { REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); TRACE (rebar, "text color 0x%06lx!\n", infoPtr->clrText); return infoPtr->clrText; } // << REBAR_GetToolTips >> // << REBAR_GetUnicodeFormat >> // << REBAR_HitTest >> static LRESULT REBAR_IdToIndex (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); UINT32 i; if (infoPtr == NULL) return -1; if (infoPtr->uNumBands < 1) return -1; TRACE (rebar, "id %u\n", (UINT32)wParam); for (i = 0; i < infoPtr->uNumBands; i++) { if (infoPtr->bands[i].wID == (UINT32)wParam) { TRACE (rebar, "band %u found!\n", i); return i; } } TRACE (rebar, "no band found!\n"); return -1; } static LRESULT REBAR_InsertBand32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); LPREBARBANDINFO32A lprbbi = (LPREBARBANDINFO32A)lParam; UINT32 uIndex = (UINT32)wParam; REBAR_BAND *lpBand; if (infoPtr == NULL) return FALSE; if (lprbbi == NULL) return FALSE; if (lprbbi->cbSize < REBARBANDINFO_V3_SIZE32A) return FALSE; TRACE (rebar, "insert band at %u!\n", uIndex); if (infoPtr->uNumBands == 0) { infoPtr->bands = (REBAR_BAND *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof (REBAR_BAND)); uIndex = 0; } else { REBAR_BAND *oldBands = infoPtr->bands; infoPtr->bands = (REBAR_BAND *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, (infoPtr->uNumBands+1)*sizeof(REBAR_BAND)); if (((INT32)uIndex == -1) || (uIndex > infoPtr->uNumBands)) uIndex = infoPtr->uNumBands; /* pre insert copy */ if (uIndex > 0) { memcpy (&infoPtr->bands[0], &oldBands[0], uIndex * sizeof(REBAR_BAND)); } /* post copy */ if (uIndex < infoPtr->uNumBands - 1) { memcpy (&infoPtr->bands[uIndex+1], &oldBands[uIndex], (infoPtr->uNumBands - uIndex - 1) * sizeof(REBAR_BAND)); } HeapFree (GetProcessHeap (), 0, &oldBands); } infoPtr->uNumBands++; TRACE (rebar, "index %u!\n", uIndex); /* initialize band (infoPtr->bands[uIndex])*/ lpBand = &infoPtr->bands[uIndex]; if (lprbbi->fMask & RBBIM_STYLE) lpBand->fStyle = lprbbi->fStyle; if (lprbbi->fMask & RBBIM_COLORS) { lpBand->clrFore = lprbbi->clrFore; lpBand->clrBack = lprbbi->clrBack; } if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) { INT32 len = lstrlen32A (lprbbi->lpText); if (len > 0) { lpBand->lpText = (LPSTR)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len + 1); lstrcpy32A (lpBand->lpText, lprbbi->lpText); } } if (lprbbi->fMask & RBBIM_IMAGE) lpBand->iImage = lprbbi->iImage; if (lprbbi->fMask & RBBIM_CHILD) { lpBand->hwndChild = lprbbi->hwndChild; lpBand->hwndPrevParent = SetParent32 (lpBand->hwndChild, wndPtr->hwndSelf); } if (lprbbi->fMask & RBBIM_CHILDSIZE) { lpBand->cxMinChild = lprbbi->cxMinChild; lpBand->cyMinChild = lprbbi->cyMinChild; lpBand->cyMaxChild = lprbbi->cyMaxChild; lpBand->cyChild = lprbbi->cyChild; lpBand->cyIntegral = lprbbi->cyIntegral; } if (lprbbi->fMask & RBBIM_SIZE) lpBand->cx = lprbbi->cx; if (lprbbi->fMask & RBBIM_BACKGROUND) lpBand->hbmBack = lprbbi->hbmBack; if (lprbbi->fMask & RBBIM_ID) lpBand->wID = lprbbi->wID; /* check for additional data */ if (lprbbi->cbSize >= sizeof (REBARBANDINFO32A)) { if (lprbbi->fMask & RBBIM_IDEALSIZE) lpBand->cxIdeal = lprbbi->cxIdeal; if (lprbbi->fMask & RBBIM_LPARAM) lpBand->lParam = lprbbi->lParam; if (lprbbi->fMask & RBBIM_HEADERSIZE) lpBand->cxHeader = lprbbi->cxHeader; } return TRUE; } // << REBAR_InsertBand32W >> // << REBAR_MaximizeBand >> // << REBAR_MinimizeBand >> // << REBAR_MoveBand >> static LRESULT REBAR_SetBandInfo32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); LPREBARBANDINFO32A lprbbi = (LPREBARBANDINFO32A)lParam; REBAR_BAND *lpBand; if (lprbbi == NULL) return FALSE; if (lprbbi->cbSize < REBARBANDINFO_V3_SIZE32A) return FALSE; if ((UINT32)wParam >= infoPtr->uNumBands) return FALSE; TRACE (rebar, "index %u\n", (UINT32)wParam); /* set band information */ lpBand = &infoPtr->bands[(UINT32)wParam]; if (lprbbi->fMask & RBBIM_STYLE) lpBand->fStyle = lprbbi->fStyle; if (lprbbi->fMask & RBBIM_COLORS) { lpBand->clrFore = lprbbi->clrFore; lpBand->clrBack = lprbbi->clrBack; } if ((lprbbi->fMask & RBBIM_TEXT) && (lprbbi->lpText)) { /* INT32 len = lstrlen32A (lprbbi->lpText); if (len > 0) { lpBand->lpText = (LPSTR)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, len + 1); lstrcpy32A (lpBand->lpText, lprbbi->lpText); } */ } if (lprbbi->fMask & RBBIM_IMAGE) lpBand->iImage = lprbbi->iImage; if (lprbbi->fMask & RBBIM_CHILD) { lpBand->hwndChild = lprbbi->hwndChild; lpBand->hwndPrevParent = SetParent32 (lpBand->hwndChild, wndPtr->hwndSelf); } if (lprbbi->fMask & RBBIM_CHILDSIZE) { lpBand->cxMinChild = lprbbi->cxMinChild; lpBand->cyMinChild = lprbbi->cyMinChild; lpBand->cyMaxChild = lprbbi->cyMaxChild; lpBand->cyChild = lprbbi->cyChild; lpBand->cyIntegral = lprbbi->cyIntegral; } if (lprbbi->fMask & RBBIM_SIZE) lpBand->cx = lprbbi->cx; if (lprbbi->fMask & RBBIM_BACKGROUND) lpBand->hbmBack = lprbbi->hbmBack; if (lprbbi->fMask & RBBIM_ID) lpBand->wID = lprbbi->wID; /* check for additional data */ if (lprbbi->cbSize >= sizeof (REBARBANDINFO32A)) { if (lprbbi->fMask & RBBIM_IDEALSIZE) lpBand->cxIdeal = lprbbi->cxIdeal; if (lprbbi->fMask & RBBIM_LPARAM) lpBand->lParam = lprbbi->lParam; if (lprbbi->fMask & RBBIM_HEADERSIZE) lpBand->cxHeader = lprbbi->cxHeader; } return TRUE; } // << REBAR_SetBandInfo32W >> static LRESULT REBAR_SetBarInfo (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); LPREBARINFO lpInfo = (LPREBARINFO)lParam; if (lpInfo == NULL) return FALSE; if (lpInfo->cbSize < sizeof (REBARINFO)) return FALSE; TRACE (rebar, "setting bar info!\n"); if (lpInfo->fMask & RBIM_IMAGELIST) infoPtr->himl = lpInfo->himl; return TRUE; } static LRESULT REBAR_SetBkColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); COLORREF clrTemp; clrTemp = infoPtr->clrBk; infoPtr->clrBk = (COLORREF)lParam; TRACE (rebar, "background color 0x%06lx!\n", infoPtr->clrBk); return clrTemp; } // << REBAR_SetColorScheme >> // << REBAR_SetPalette >> // << REBAR_SetParent >> static LRESULT REBAR_SetTextColor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); COLORREF clrTemp; clrTemp = infoPtr->clrText; infoPtr->clrText = (COLORREF)lParam; TRACE (rebar, "text color 0x%06lx!\n", infoPtr->clrText); return clrTemp; } // << REBAR_SetTooltips >> // << REBAR_SetUnicodeFormat >> static LRESULT REBAR_ShowBand (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); if (((INT32)wParam < 0) || ((INT32)wParam > infoPtr->uNumBands)) return FALSE; if ((BOOL32)lParam) FIXME (rebar, "show band %d\n", (INT32)wParam); else FIXME (rebar, "hide band %d\n", (INT32)wParam); return TRUE; } static LRESULT REBAR_SizeToRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { REBAR_INFO *infoPtr = REBAR_GetInfoPtr (wndPtr); LPRECT32 lpRect = (LPRECT32)lParam; if (lpRect == NULL) return FALSE; FIXME (rebar, "layout change not implemented!\n"); return TRUE; } static LRESULT REBAR_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { REBAR_INFO *infoPtr; /* allocate memory for info structure */ infoPtr = (REBAR_INFO *)COMCTL32_Alloc (sizeof(REBAR_INFO)); wndPtr->wExtra[0] = (DWORD)infoPtr; if (infoPtr == NULL) { ERR (rebar, "could not allocate info memory!\n"); return 0; } if ((REBAR_INFO*)wndPtr->wExtra[0] != infoPtr) { ERR (rebar, "pointer assignment error!\n"); return 0; } /* initialize info structure */ infoPtr->clrText = CLR_NONE; infoPtr->clrText = RGB(0, 0, 0); TRACE (rebar, "created!\n"); return 0; } static LRESULT REBAR_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam) { REBAR_INFO *infoPtr = REBAR_GetInfoPtr(wndPtr); REBAR_BAND *lpBand; INT32 i; /* free rebar bands */ if ((infoPtr->uNumBands > 0) && infoPtr->bands) { /* clean up each band */ for (i = 0; i < infoPtr->uNumBands; i++) { lpBand = &infoPtr->bands[i]; /* delete text strings */ if (lpBand->lpText) { HeapFree (GetProcessHeap (), 0, lpBand->lpText); lpBand->lpText = NULL; } } /* free band array */ HeapFree (GetProcessHeap (), 0, infoPtr->bands); infoPtr->bands = NULL; } /* free rebar info data */ COMCTL32_Free (infoPtr); TRACE (rebar, "destroyed!\n"); return 0; } static LRESULT REBAR_Paint (WND *wndPtr, WPARAM32 wParam) { HDC32 hdc; PAINTSTRUCT32 ps; hdc = wParam==0 ? BeginPaint32 (wndPtr->hwndSelf, &ps) : (HDC32)wParam; REBAR_Refresh (wndPtr, hdc); if (!wParam) EndPaint32 (wndPtr->hwndSelf, &ps); return 0; } LRESULT WINAPI REBAR_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam) { WND *wndPtr = WIN_FindWndPtr(hwnd); switch (uMsg) { // case RB_BEGINDRAG: // case RB_DELETEBAND: // case RB_DRAGMOVE: // case RB_ENDDRAG: // case RB_GETBANDBORDERS: case RB_GETBANDCOUNT: return REBAR_GetBandCount (wndPtr); // case RB_GETBANDINFO32: /* outdated, just for compatibility */ case RB_GETBANDINFO32A: return REBAR_GetBandInfo32A (wndPtr, wParam, lParam); // case RB_GETBANDINFO32W: case RB_GETBARHEIGHT: return REBAR_GetBarHeight (wndPtr, wParam, lParam); case RB_GETBARINFO: return REBAR_GetBarInfo (wndPtr, wParam, lParam); case RB_GETBKCOLOR: return REBAR_GetBkColor (wndPtr); // case RB_GETCOLORSCHEME: // case RB_GETDROPTARGET: // case RB_GETPALETTE: // case RB_GETRECT: // case RB_GETROWCOUNT: // case RB_GETROWHEIGHT: case RB_GETTEXTCOLOR: return REBAR_GetTextColor (wndPtr); // case RB_GETTOOLTIPS: // case RB_GETUNICODEFORMAT: // case RB_HITTEST: case RB_IDTOINDEX: return REBAR_IdToIndex (wndPtr, wParam, lParam); case RB_INSERTBAND32A: return REBAR_InsertBand32A (wndPtr, wParam, lParam); // case RB_INSERTBAND32W: // case RB_MAXIMIZEBAND: // case RB_MINIMIZEBAND: // case RB_MOVEBAND: case RB_SETBANDINFO32A: return REBAR_SetBandInfo32A (wndPtr, wParam, lParam); // case RB_SETBANDINFO32W: case RB_SETBARINFO: return REBAR_SetBarInfo (wndPtr, wParam, lParam); case RB_SETBKCOLOR: return REBAR_SetBkColor (wndPtr, wParam, lParam); // case RB_SETCOLORSCHEME: // case RB_SETPALETTE: // case RB_SETPARENT: case RB_SETTEXTCOLOR: return REBAR_SetTextColor (wndPtr, wParam, lParam); // case RB_SETTOOLTIPS: // case RB_SETUNICODEFORMAT: case RB_SHOWBAND: return REBAR_ShowBand (wndPtr, wParam, lParam); case RB_SIZETORECT: return REBAR_SizeToRect (wndPtr, wParam, lParam); case WM_CREATE: return REBAR_Create (wndPtr, wParam, lParam); case WM_DESTROY: return REBAR_Destroy (wndPtr, wParam, lParam); // case WM_GETFONT: // case WM_MOUSEMOVE: // return REBAR_MouseMove (wndPtr, wParam, lParam); case WM_PAINT: return REBAR_Paint (wndPtr, wParam); // case WM_SETFONT: // case WM_TIMER: // case WM_WININICHANGE: default: if (uMsg >= WM_USER) ERR (rebar, "unknown msg %04x wp=%08x lp=%08lx\n", uMsg, wParam, lParam); return DefWindowProc32A (hwnd, uMsg, wParam, lParam); } return 0; } void REBAR_Register (void) { WNDCLASS32A wndClass; if (GlobalFindAtom32A (REBARCLASSNAME32A)) return; ZeroMemory (&wndClass, sizeof(WNDCLASS32A)); wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS; wndClass.lpfnWndProc = (WNDPROC32)REBAR_WindowProc; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = sizeof(REBAR_INFO *); wndClass.hCursor = 0; wndClass.hbrBackground = (HBRUSH32) COLOR_BTNFACE + 1; wndClass.lpszClassName = REBARCLASSNAME32A; RegisterClass32A (&wndClass); }