From ad0184614ea4211f844d3b032a1042600630773a Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Tue, 3 Oct 2006 22:46:26 +0000 Subject: [PATCH] update comctl32 to Wine-0.9.22 to get the new imagelist code. svn path=/trunk/; revision=24384 --- reactos/dll/win32/comctl32/comctl32.h | 1 + reactos/dll/win32/comctl32/comctl_Pl.rc | 5 + reactos/dll/win32/comctl32/commctrl.c | 61 +++ reactos/dll/win32/comctl32/header.c | 277 +++++-------- reactos/dll/win32/comctl32/imagelist.c | 5 +- reactos/dll/win32/comctl32/toolbar.c | 491 ++++++++++-------------- 6 files changed, 379 insertions(+), 461 deletions(-) diff --git a/reactos/dll/win32/comctl32/comctl32.h b/reactos/dll/win32/comctl32/comctl32.h index f6d233ff2fd..66a0973183c 100644 --- a/reactos/dll/win32/comctl32/comctl32.h +++ b/reactos/dll/win32/comctl32/comctl32.h @@ -143,6 +143,7 @@ extern COMCTL32_SysColor comctl32_color; HWND COMCTL32_CreateToolTip (HWND); VOID COMCTL32_RefreshSysColors(void); void COMCTL32_DrawInsertMark(HDC hDC, const RECT *lpRect, COLORREF clrInsertMark, BOOL bHorizontal); +void COMCTL32_EnsureBitmapSize(HBITMAP *pBitmap, int cxMinWidth, int cyMinHeight, COLORREF crBackground); INT Str_GetPtrWtoA (LPCWSTR lpSrc, LPSTR lpDest, INT nMaxLen); BOOL Str_SetPtrAtoW (LPWSTR *lppDest, LPCSTR lpSrc); BOOL Str_SetPtrWtoA (LPSTR *lppDest, LPCWSTR lpSrc); diff --git a/reactos/dll/win32/comctl32/comctl_Pl.rc b/reactos/dll/win32/comctl32/comctl_Pl.rc index 252c43eb1a3..91441344597 100644 --- a/reactos/dll/win32/comctl32/comctl_Pl.rc +++ b/reactos/dll/win32/comctl32/comctl_Pl.rc @@ -81,3 +81,8 @@ STRINGTABLE DISCARDABLE { IDS_SEPARATOR "Odstêp" } + +STRINGTABLE DISCARDABLE +{ + HKY_NONE "Brak" +} diff --git a/reactos/dll/win32/comctl32/commctrl.c b/reactos/dll/win32/comctl32/commctrl.c index 5cfc24cf844..81f5f86e000 100644 --- a/reactos/dll/win32/comctl32/commctrl.c +++ b/reactos/dll/win32/comctl32/commctrl.c @@ -1448,6 +1448,67 @@ void COMCTL32_DrawInsertMark(HDC hDC, const RECT *lpRect, COLORREF clrInsertMark DeleteObject(hPen); } +/*********************************************************************** + * COMCTL32_EnsureBitmapSize [internal] + * + * If needed enlarge the bitmap so that the width is at least cxMinWidth + * the height is at least cyMinHeight. If the bitmap already have these + * dimensions nothing changes. + * + * PARAMS + * hBitmap [I/O] Bitmap to modify. The handle may change + * cxMinWidth [I] If the width of the bitmap is smaller then it will + * be enlarged to this value + * cyMinHeight [I] If the height of the bitmap is smaller then it will + * be enlarged to this value + * cyBackground [I] The color with which the new area will be filled + * + * RETURNS + * none + */ +void COMCTL32_EnsureBitmapSize(HBITMAP *pBitmap, int cxMinWidth, int cyMinHeight, COLORREF crBackground) +{ + int cxNew, cyNew; + BITMAP bmp; + HBITMAP hNewBitmap; + HBITMAP hNewDCBitmap, hOldDCBitmap; + HBRUSH hNewDCBrush; + HDC hdcNew, hdcOld; + + if (!GetObjectW(*pBitmap, sizeof(BITMAP), &bmp)) + return; + cxNew = (cxMinWidth > bmp.bmWidth ? cxMinWidth : bmp.bmWidth); + cyNew = (cyMinHeight > bmp.bmHeight ? cyMinHeight : bmp.bmHeight); + if (cxNew == bmp.bmWidth && cyNew == bmp.bmHeight) + return; + + hdcNew = CreateCompatibleDC(NULL); + hNewBitmap = CreateBitmap(cxNew, cyNew, bmp.bmPlanes, bmp.bmBitsPixel, NULL); + hNewDCBitmap = SelectObject(hdcNew, hNewBitmap); + hNewDCBrush = SelectObject(hdcNew, CreateSolidBrush(crBackground)); + + hdcOld = CreateCompatibleDC(NULL); + hOldDCBitmap = SelectObject(hdcOld, *pBitmap); + + BitBlt(hdcNew, 0, 0, bmp.bmWidth, bmp.bmHeight, hdcOld, 0, 0, SRCCOPY); + if (bmp.bmWidth < cxMinWidth) + PatBlt(hdcNew, bmp.bmWidth, 0, cxNew, bmp.bmHeight, PATCOPY); + if (bmp.bmHeight < cyMinHeight) + PatBlt(hdcNew, 0, bmp.bmHeight, bmp.bmWidth, cyNew, PATCOPY); + if (bmp.bmWidth < cxMinWidth && bmp.bmHeight < cyMinHeight) + PatBlt(hdcNew, bmp.bmWidth, bmp.bmHeight, cxNew, cyNew, PATCOPY); + + SelectObject(hdcNew, hNewDCBitmap); + DeleteObject(SelectObject(hdcNew, hNewDCBrush)); + DeleteDC(hdcNew); + SelectObject(hdcOld, hOldDCBitmap); + DeleteDC(hdcOld); + + DeleteObject(*pBitmap); + *pBitmap = hNewBitmap; + return; +} + /*********************************************************************** * MirrorIcon [COMCTL32.414] * diff --git a/reactos/dll/win32/comctl32/header.c b/reactos/dll/win32/comctl32/header.c index 41c4071ca81..1d4f1fdb5e7 100644 --- a/reactos/dll/win32/comctl32/header.c +++ b/reactos/dll/win32/comctl32/header.c @@ -4,6 +4,7 @@ * Copyright 1998 Eric Kohl * Copyright 2000 Eric Kohl for CodeWeavers * Copyright 2003 Maxime Bellenge + * Copyright 2006 Mikolaj Zalewski * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,15 +21,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * TODO: - * - Imagelist support (partially). - * - Callback items (under construction). - * - Hottrack support (partially). - * - Custom draw support (including Notifications). - * - Drag and Drop support (including Notifications). - * - New messages. - * - Use notification format - * - Correct the order maintenance code to preserve valid order - * + * - Imagelist support (completed?) + * - Hottrack support (completed?) + * - Custom draw support (completed?) + * - Filters support (HDS_FILTER, HDI_FILTER, HDM_*FILTER*, HDN_*FILTER*) + * - New Windows Vista features */ #include @@ -84,7 +81,6 @@ typedef struct INT iMoveItem; /* index of tracked item. (Tracking mode) */ INT xTrackOffset; /* distance between the right side of the tracked item and the cursor */ INT xOldTrack; /* track offset (see above) after the last WM_MOUSEMOVE */ - INT nOldWidth; /* width of a sizing item after the last WM_MOUSEMOVE */ INT iHotItem; /* index of hot item (cursor is over this item) */ INT iHotDivider; /* index of the hot divider (used while dragging an item or by HDM_SETHOTDIVIDER) */ INT iMargin; /* width of the margin that surrounds a bitmap */ @@ -802,32 +798,11 @@ HEADER_SendSimpleNotify (HWND hwnd, UINT code) } static BOOL -HEADER_SendHeaderNotifyT (HWND hwnd, UINT code, INT iItem, INT mask, HDITEMW *lpItem) +HEADER_SendNotifyWithHDItemT(HWND hwnd, UINT code, INT iItem, HDITEMW *lpItem) { HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); NMHEADERW nmhdr; - HDITEMW nmitem; - if (lpItem == NULL) - { - /* lpItem == NULL means that we should take the actual data from the item */ - if (mask & HDI_TEXT) - { - FIXME("(): invalid parameters - lpItem == NULL and (mask & HDI_TEXT)\n"); - mask &= ~HDI_TEXT; - } - nmitem.mask = mask; - nmitem.cxy = infoPtr->items[iItem].cxy; - nmitem.hbm = infoPtr->items[iItem].hbm; - nmitem.pszText = NULL; - nmitem.cchTextMax = 0; - nmitem.fmt = infoPtr->items[iItem].fmt; - nmitem.lParam = infoPtr->items[iItem].lParam; - nmitem.iOrder = infoPtr->items[iItem].iOrder; - nmitem.iImage = infoPtr->items[iItem].iImage; - lpItem = &nmitem; - } - nmhdr.hdr.hwndFrom = hwnd; nmhdr.hdr.idFrom = GetWindowLongPtrW (hwnd, GWLP_ID); nmhdr.hdr.code = (infoPtr->nNotifyFormat == NFR_UNICODE ? code : HEADER_NotifyCodeWtoA(code)); @@ -839,6 +814,38 @@ HEADER_SendHeaderNotifyT (HWND hwnd, UINT code, INT iItem, INT mask, HDITEMW *lp (WPARAM)nmhdr.hdr.idFrom, (LPARAM)&nmhdr); } +static BOOL +HEADER_SendNotifyWithIntFieldT(HWND hwnd, UINT code, INT iItem, INT mask, INT iValue) +{ + HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); + HDITEMW nmitem; + + /* copying only the iValue should be ok but to make the code more robust we copy everything */ + nmitem.cxy = infoPtr->items[iItem].cxy; + nmitem.hbm = infoPtr->items[iItem].hbm; + nmitem.pszText = NULL; + nmitem.cchTextMax = 0; + nmitem.fmt = infoPtr->items[iItem].fmt; + nmitem.lParam = infoPtr->items[iItem].lParam; + nmitem.iOrder = infoPtr->items[iItem].iOrder; + nmitem.iImage = infoPtr->items[iItem].iImage; + + nmitem.mask = mask; + switch (mask) + { + case HDI_WIDTH: + nmitem.cxy = iValue; + break; + case HDI_ORDER: + nmitem.iOrder = iValue; + break; + default: + ERR("invalid mask value 0x%x\n", iValue); + } + + return HEADER_SendNotifyWithHDItemT(hwnd, code, iItem, &nmitem); +} + /** * Prepare callback items * depends on NMHDDISPINFOW having same structure as NMHDDISPINFOA @@ -952,23 +959,6 @@ HEADER_FreeCallbackItems(HEADER_ITEM *lpItem) lpItem->iImage = I_IMAGECALLBACK; } -static BOOL -HEADER_SendClickNotify (HWND hwnd, UINT code, INT iItem) -{ - HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd); - NMHEADERA nmhdr; - - nmhdr.hdr.hwndFrom = hwnd; - nmhdr.hdr.idFrom = GetWindowLongPtrW (hwnd, GWLP_ID); - nmhdr.hdr.code = code; - nmhdr.iItem = iItem; - nmhdr.iButton = 0; - nmhdr.pitem = NULL; - - return (BOOL)SendMessageA (infoPtr->hwndNotify, WM_NOTIFY, - (WPARAM)nmhdr.hdr.idFrom, (LPARAM)&nmhdr); -} - static LRESULT HEADER_CreateDragImage (HWND hwnd, WPARAM wParam) { @@ -1060,67 +1050,40 @@ HEADER_DeleteItem (HWND hwnd, WPARAM wParam) { HEADER_INFO *infoPtr = HEADER_GetInfoPtr(hwnd); INT iItem = (INT)wParam; + INT iOrder; + INT i; TRACE("[iItem=%d]\n", iItem); if ((iItem < 0) || (iItem >= (INT)infoPtr->uNumItem)) return FALSE; - if (infoPtr->uNumItem == 1) { - TRACE("Simple delete!\n"); - HEADER_DisposeItem(&infoPtr->items[0]); - Free (infoPtr->items); - Free(infoPtr->order); - infoPtr->items = 0; - infoPtr->order = 0; - infoPtr->uNumItem = 0; - } - else { - HEADER_ITEM *oldItems = infoPtr->items; - INT i; - INT iOrder; - TRACE("Complex delete! [iItem=%d]\n", iItem); - - for (i = 0; i < infoPtr->uNumItem; i++) - TRACE("%d: order=%d, iOrder=%d, ->iOrder=%d\n", i, infoPtr->order[i], infoPtr->items[i].iOrder, infoPtr->items[infoPtr->order[i]].iOrder); - HEADER_DisposeItem(&infoPtr->items[iItem]); - iOrder = infoPtr->items[iItem].iOrder; - - infoPtr->uNumItem--; - infoPtr->items = Alloc (sizeof (HEADER_ITEM) * infoPtr->uNumItem); - /* pre delete copy */ - if (iItem > 0) { - memcpy (&infoPtr->items[0], &oldItems[0], - iItem * sizeof(HEADER_ITEM)); - } - - /* post delete copy */ - if (iItem < infoPtr->uNumItem) { - memcpy (&infoPtr->items[iItem], &oldItems[iItem+1], - (infoPtr->uNumItem - iItem) * sizeof(HEADER_ITEM)); - } - - /* Correct the orders */ - if (iOrder < infoPtr->uNumItem) - { - memmove(&infoPtr->order[iOrder], &infoPtr->order[iOrder + 1], - (infoPtr->uNumItem - iOrder) * sizeof(INT)); - for (i = 0; i < infoPtr->uNumItem; i++) - { - if (infoPtr->order[i] > iItem) - infoPtr->order[i]--; - if (i >= iOrder) - infoPtr->items[infoPtr->order[i]].iOrder = infoPtr->order[i]; - } - } - - for (i = 0; i < infoPtr->uNumItem; i++) - TRACE("%d: order=%d, iOrder=%d, ->iOrder=%d\n", i, infoPtr->order[i], infoPtr->items[i].iOrder, infoPtr->items[infoPtr->order[i]].iOrder); - Free (oldItems); + for (i = 0; i < infoPtr->uNumItem; i++) + TRACE("%d: order=%d, iOrder=%d, ->iOrder=%d\n", i, infoPtr->order[i], infoPtr->items[i].iOrder, infoPtr->items[infoPtr->order[i]].iOrder); + + iOrder = infoPtr->items[iItem].iOrder; + HEADER_DisposeItem(&infoPtr->items[iItem]); + + infoPtr->uNumItem--; + memmove(&infoPtr->items[iItem], &infoPtr->items[iItem + 1], + (infoPtr->uNumItem - iItem) * sizeof(HEADER_ITEM)); + memmove(&infoPtr->order[iOrder], &infoPtr->order[iOrder + 1], + (infoPtr->uNumItem - iOrder) * sizeof(INT)); + infoPtr->items = ReAlloc(infoPtr->items, sizeof(HEADER_ITEM) * infoPtr->uNumItem); + infoPtr->order = ReAlloc(infoPtr->order, sizeof(INT) * infoPtr->uNumItem); + + /* Correct the orders */ + for (i = 0; i < infoPtr->uNumItem; i++) + { + if (infoPtr->order[i] > iItem) + infoPtr->order[i]--; + if (i >= iOrder) + infoPtr->items[infoPtr->order[i]].iOrder = i; } + for (i = 0; i < infoPtr->uNumItem; i++) + TRACE("%d: order=%d, iOrder=%d, ->iOrder=%d\n", i, infoPtr->order[i], infoPtr->items[i].iOrder, infoPtr->items[infoPtr->order[i]].iOrder); HEADER_SetItemBounds (hwnd); - InvalidateRect(hwnd, NULL, FALSE); return TRUE; @@ -1299,51 +1262,23 @@ HEADER_InsertItemT (HWND hwnd, INT nItem, LPHDITEMW phdi, BOOL bUnicode) else if (infoPtr->uNumItem < iOrder) iOrder = infoPtr->uNumItem; - if (infoPtr->uNumItem == 0) { - infoPtr->items = Alloc (sizeof (HEADER_ITEM)); - infoPtr->order = Alloc(sizeof(INT)); - infoPtr->uNumItem++; - } - else { - HEADER_ITEM *oldItems = infoPtr->items; - INT *oldOrder = infoPtr->order; - - infoPtr->uNumItem++; - infoPtr->items = Alloc (sizeof (HEADER_ITEM) * infoPtr->uNumItem); - if (nItem == 0) { - memcpy (&infoPtr->items[1], &oldItems[0], - (infoPtr->uNumItem-1) * sizeof(HEADER_ITEM)); - } - else - { - /* pre insert copy */ - if (nItem > 0) { - memcpy (&infoPtr->items[0], &oldItems[0], - nItem * sizeof(HEADER_ITEM)); - } - - /* post insert copy */ - if (nItem < infoPtr->uNumItem - 1) { - memcpy (&infoPtr->items[nItem+1], &oldItems[nItem], - (infoPtr->uNumItem - nItem - 1) * sizeof(HEADER_ITEM)); - } - } - - infoPtr->order = Alloc(sizeof(INT) * infoPtr->uNumItem); - memcpy(infoPtr->order, oldOrder, iOrder * sizeof(INT)); - infoPtr->order[iOrder] = nItem; - memcpy(&infoPtr->order[iOrder + 1], &oldOrder[iOrder], - (infoPtr->uNumItem - iOrder - 1) * sizeof(INT)); - - Free (oldItems); - Free(oldOrder); - } + infoPtr->uNumItem++; + infoPtr->items = ReAlloc(infoPtr->items, sizeof(HEADER_ITEM) * infoPtr->uNumItem); + infoPtr->order = ReAlloc(infoPtr->order, sizeof(INT) * infoPtr->uNumItem); + + /* make space for the new item */ + memmove(&infoPtr->items[nItem + 1], &infoPtr->items[nItem], + (infoPtr->uNumItem - nItem - 1) * sizeof(HEADER_ITEM)); + memmove(&infoPtr->order[iOrder + 1], &infoPtr->order[iOrder], + (infoPtr->uNumItem - iOrder - 1) * sizeof(INT)); + /* update the order array */ + infoPtr->order[iOrder] = nItem; for (i = 0; i < infoPtr->uNumItem; i++) { if (i != iOrder && infoPtr->order[i] >= nItem) infoPtr->order[i]++; - infoPtr->items[infoPtr->order[i]].iOrder = infoPtr->order[i]; + infoPtr->items[infoPtr->order[i]].iOrder = i; } lpItem = &infoPtr->items[nItem]; @@ -1351,6 +1286,7 @@ HEADER_InsertItemT (HWND hwnd, INT nItem, LPHDITEMW phdi, BOOL bUnicode) /* cxy, fmt and lParam are copied even if not in the HDITEM mask */ copyMask = phdi->mask | HDI_WIDTH | HDI_FORMAT | HDI_LPARAM; HEADER_StoreHDItemInHeader(lpItem, copyMask, phdi, bUnicode); + lpItem->iOrder = iOrder; /* set automatically some format bits */ if (phdi->mask & HDI_TEXT) @@ -1366,10 +1302,7 @@ HEADER_InsertItemT (HWND hwnd, INT nItem, LPHDITEMW phdi, BOOL bUnicode) if (phdi->mask & HDI_IMAGE) lpItem->fmt |= HDF_IMAGE; - lpItem->iOrder = iOrder; - HEADER_SetItemBounds (hwnd); - InvalidateRect(hwnd, NULL, FALSE); return nItem; @@ -1456,7 +1389,7 @@ HEADER_SetItemT (HWND hwnd, INT nItem, LPHDITEMW phdi, BOOL bUnicode) TRACE("[nItem=%d]\n", nItem); HEADER_CopyHDItemForNotify(infoPtr, &hdNotify, phdi, bUnicode, &pvScratch); - if (HEADER_SendHeaderNotifyT (hwnd, HDN_ITEMCHANGINGW, nItem, phdi->mask, &hdNotify)) + if (HEADER_SendNotifyWithHDItemT(hwnd, HDN_ITEMCHANGINGW, nItem, &hdNotify)) { if (pvScratch) Free(pvScratch); return FALSE; @@ -1469,7 +1402,7 @@ HEADER_SetItemT (HWND hwnd, INT nItem, LPHDITEMW phdi, BOOL bUnicode) if (phdi->iOrder >= 0 && phdi->iOrder < infoPtr->uNumItem) HEADER_ChangeItemOrder(infoPtr, nItem, phdi->iOrder); - HEADER_SendHeaderNotifyT (hwnd, HDN_ITEMCHANGEDW, nItem, phdi->mask, &hdNotify); + HEADER_SendNotifyWithHDItemT(hwnd, HDN_ITEMCHANGEDW, nItem, &hdNotify); HEADER_SetItemBounds (hwnd); @@ -1597,9 +1530,9 @@ HEADER_LButtonDblClk (HWND hwnd, WPARAM wParam, LPARAM lParam) HEADER_InternalHitTest (hwnd, &pt, &flags, &nItem); if ((GetWindowLongW (hwnd, GWL_STYLE) & HDS_BUTTONS) && (flags == HHT_ONHEADER)) - HEADER_SendHeaderNotifyT (hwnd, HDN_ITEMDBLCLICKW, nItem, 0, NULL); + HEADER_SendNotifyWithHDItemT(hwnd, HDN_ITEMDBLCLICKW, nItem, NULL); else if ((flags == HHT_ONDIVIDER) || (flags == HHT_ONDIVOPEN)) - HEADER_SendHeaderNotifyT (hwnd, HDN_DIVIDERDBLCLICKW, nItem, 0, NULL); + HEADER_SendNotifyWithHDItemT(hwnd, HDN_DIVIDERDBLCLICKW, nItem, NULL); return 0; } @@ -1637,12 +1570,13 @@ HEADER_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam) TRACE("Pressed item %d!\n", nItem); } else if ((flags == HHT_ONDIVIDER) || (flags == HHT_ONDIVOPEN)) { - if (!(HEADER_SendHeaderNotifyT (hwnd, HDN_BEGINTRACKW, nItem, HDI_WIDTH, NULL))) { + INT iCurrWidth = infoPtr->items[nItem].cxy; + if (!HEADER_SendNotifyWithIntFieldT(hwnd, HDN_BEGINTRACKW, nItem, HDI_WIDTH, iCurrWidth)) + { SetCapture (hwnd); infoPtr->bCaptured = TRUE; infoPtr->bTracking = TRUE; infoPtr->iMoveItem = nItem; - infoPtr->nOldWidth = infoPtr->items[nItem].cxy; infoPtr->xTrackOffset = infoPtr->items[nItem].rect.right - pt.x; if (!(dwStyle & HDS_FULLDRAG)) { @@ -1667,7 +1601,7 @@ HEADER_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam) DWORD dwStyle = GetWindowLongW (hwnd, GWL_STYLE); POINT pt; UINT flags; - INT nItem, nWidth; + INT nItem; HDC hdc; pt.x = (INT)(SHORT)LOWORD(lParam); @@ -1695,9 +1629,8 @@ HEADER_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam) iNewOrder--; } - /* FIXME: the new order field should be sent, not the old one */ if (iNewOrder != -1 && - !HEADER_SendHeaderNotifyT(hwnd, HDN_ENDDRAG, infoPtr->iMoveItem, HDI_ORDER, NULL)) + !HEADER_SendNotifyWithIntFieldT(hwnd, HDN_ENDDRAG, infoPtr->iMoveItem, HDI_ORDER, iNewOrder)) { HEADER_ChangeItemOrder(infoPtr, infoPtr->iMoveItem, iNewOrder); infoPtr->bRectsValid = FALSE; @@ -1715,17 +1648,20 @@ HEADER_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam) HEADER_RefreshItem (hwnd, hdc, infoPtr->iMoveItem); ReleaseDC (hwnd, hdc); - HEADER_SendClickNotify (hwnd, HDN_ITEMCLICKA, infoPtr->iMoveItem); + HEADER_SendNotifyWithHDItemT(hwnd, HDN_ITEMCLICKW, infoPtr->iMoveItem, NULL); } TRACE("Released item %d!\n", infoPtr->iMoveItem); infoPtr->bPressed = FALSE; } else if (infoPtr->bTracking) { + INT iNewWidth = pt.x - infoPtr->items[infoPtr->iMoveItem].rect.left + infoPtr->xTrackOffset; + if (iNewWidth < 0) + iNewWidth = 0; TRACE("End tracking item %d!\n", infoPtr->iMoveItem); infoPtr->bTracking = FALSE; - HEADER_SendHeaderNotifyT (hwnd, HDN_ENDTRACKW, infoPtr->iMoveItem, HDI_WIDTH, NULL); + HEADER_SendNotifyWithIntFieldT(hwnd, HDN_ENDTRACKW, infoPtr->iMoveItem, HDI_WIDTH, iNewWidth); if (!(dwStyle & HDS_FULLDRAG)) { hdc = GetDC (hwnd); @@ -1733,20 +1669,14 @@ HEADER_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam) ReleaseDC (hwnd, hdc); } - if (HEADER_SendHeaderNotifyT(hwnd, HDN_ITEMCHANGINGW, infoPtr->iMoveItem, HDI_WIDTH, NULL)) - { - infoPtr->items[infoPtr->iMoveItem].cxy = infoPtr->nOldWidth; - } - else { - nWidth = pt.x - infoPtr->items[infoPtr->iMoveItem].rect.left + infoPtr->xTrackOffset; - if (nWidth < 0) - nWidth = 0; - infoPtr->items[infoPtr->iMoveItem].cxy = nWidth; + if (!HEADER_SendNotifyWithIntFieldT(hwnd, HDN_ITEMCHANGINGW, infoPtr->iMoveItem, HDI_WIDTH, iNewWidth)) + { + infoPtr->items[infoPtr->iMoveItem].cxy = iNewWidth; + HEADER_SendNotifyWithIntFieldT(hwnd, HDN_ITEMCHANGEDW, infoPtr->iMoveItem, HDI_WIDTH, iNewWidth); } HEADER_SetItemBounds (hwnd); InvalidateRect(hwnd, NULL, TRUE); - HEADER_SendHeaderNotifyT(hwnd, HDN_ITEMCHANGEDW, infoPtr->iMoveItem, HDI_WIDTH, NULL); } if (infoPtr->bCaptured) { @@ -1826,7 +1756,7 @@ HEADER_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam) if (infoPtr->bPressed && !infoPtr->bDragging && dwStyle&HDS_DRAGDROP && HEADER_IsDragDistance(infoPtr, &pt)) { - if (!HEADER_SendHeaderNotifyT(hwnd, HDN_BEGINDRAG, infoPtr->iMoveItem, 0, NULL)) + if (!HEADER_SendNotifyWithHDItemT(hwnd, HDN_BEGINDRAG, infoPtr->iMoveItem, NULL)) { HIMAGELIST hDragItem = (HIMAGELIST)HEADER_CreateDragImage(hwnd, infoPtr->iMoveItem); if (hDragItem != NULL) @@ -1867,14 +1797,14 @@ HEADER_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam) } else if (infoPtr->bTracking) { if (dwStyle & HDS_FULLDRAG) { - if (!HEADER_SendHeaderNotifyT (hwnd, HDN_ITEMCHANGINGW, infoPtr->iMoveItem, HDI_WIDTH, NULL)) + HEADER_ITEM *lpItem = &infoPtr->items[infoPtr->iMoveItem]; + nWidth = pt.x - lpItem->rect.left + infoPtr->xTrackOffset; + if (!HEADER_SendNotifyWithIntFieldT(hwnd, HDN_ITEMCHANGINGW, infoPtr->iMoveItem, HDI_WIDTH, nWidth)) { - HEADER_ITEM *lpItem = &infoPtr->items[infoPtr->iMoveItem]; INT nOldWidth = lpItem->rect.right - lpItem->rect.left; RECT rcClient; RECT rcScroll; - nWidth = pt.x - lpItem->rect.left + infoPtr->xTrackOffset; if (nWidth < 0) nWidth = 0; infoPtr->items[infoPtr->iMoveItem].cxy = nWidth; HEADER_SetItemBounds(hwnd); @@ -1886,20 +1816,21 @@ HEADER_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam) InvalidateRect(hwnd, &lpItem->rect, FALSE); UpdateWindow(hwnd); - HEADER_SendHeaderNotifyT(hwnd, HDN_ITEMCHANGEDW, infoPtr->iMoveItem, HDI_WIDTH, NULL); + HEADER_SendNotifyWithIntFieldT(hwnd, HDN_ITEMCHANGEDW, infoPtr->iMoveItem, HDI_WIDTH, nWidth); } } else { + INT iTrackWidth; hdc = GetDC (hwnd); HEADER_DrawTrackLine (hwnd, hdc, infoPtr->xOldTrack); infoPtr->xOldTrack = pt.x + infoPtr->xTrackOffset; if (infoPtr->xOldTrack < infoPtr->items[infoPtr->iMoveItem].rect.left) infoPtr->xOldTrack = infoPtr->items[infoPtr->iMoveItem].rect.left; - infoPtr->items[infoPtr->iMoveItem].cxy = - infoPtr->xOldTrack - infoPtr->items[infoPtr->iMoveItem].rect.left; HEADER_DrawTrackLine (hwnd, hdc, infoPtr->xOldTrack); ReleaseDC (hwnd, hdc); - HEADER_SendHeaderNotifyT (hwnd, HDN_TRACKW, infoPtr->iMoveItem, HDI_WIDTH, NULL); + iTrackWidth = infoPtr->xOldTrack - infoPtr->items[infoPtr->iMoveItem].rect.left; + /* FIXME: should stop tracking if HDN_TRACK returnes TRUE */ + HEADER_SendNotifyWithIntFieldT(hwnd, HDN_TRACKW, infoPtr->iMoveItem, HDI_WIDTH, iTrackWidth); } TRACE("Tracking item %d!\n", infoPtr->iMoveItem); diff --git a/reactos/dll/win32/comctl32/imagelist.c b/reactos/dll/win32/comctl32/imagelist.c index cc3078ea463..faf537183bb 100644 --- a/reactos/dll/win32/comctl32/imagelist.c +++ b/reactos/dll/win32/comctl32/imagelist.c @@ -2546,11 +2546,12 @@ ImageList_SetImageCount (HIMAGELIST himl, UINT iImageCount) if (!is_valid(himl)) return FALSE; - if (himl->cCurImage >= iImageCount) - return FALSE; + if (iImageCount < 0) + return FALSE; if (himl->cMaxImage > iImageCount) { himl->cCurImage = iImageCount; + /* TODO: shrink the bitmap when cMaxImage-cCurImage>cGrow ? */ return TRUE; } diff --git a/reactos/dll/win32/comctl32/toolbar.c b/reactos/dll/win32/comctl32/toolbar.c index 108bf048f12..9de8e768798 100644 --- a/reactos/dll/win32/comctl32/toolbar.c +++ b/reactos/dll/win32/comctl32/toolbar.c @@ -250,6 +250,7 @@ static HIMAGELIST TOOLBAR_InsertImageList(PIMLENTRY **pies, INT *cies, HIMAGELIS static LRESULT TOOLBAR_LButtonDown(HWND hwnd, WPARAM wParam, LPARAM lParam); static void TOOLBAR_SetHotItemEx (TOOLBAR_INFO *infoPtr, INT nHit, DWORD dwReason); static LRESULT TOOLBAR_AutoSize(HWND hwnd); +static void TOOLBAR_CheckImageListIconSize(TOOLBAR_INFO *infoPtr); static LRESULT TOOLBAR_NotifyFormat(TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam); @@ -1091,6 +1092,9 @@ TOOLBAR_Refresh (HWND hwnd, HDC hdc, PAINTSTRUCT* ps) TOOLBAR_DumpToolbar (infoPtr, __LINE__); + /* change the imagelist icon size if we manage the list and it is necessary */ + TOOLBAR_CheckImageListIconSize(infoPtr); + /* Send initial notify */ ZeroMemory (&tbcd, sizeof(NMTBCUSTOMDRAW)); tbcd.nmcd.dwDrawStage = CDDS_PREPAINT; @@ -2568,6 +2572,101 @@ TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } } +static BOOL +TOOLBAR_AddBitmapToImageList(TOOLBAR_INFO *infoPtr, HIMAGELIST himlDef, const TBITMAP_INFO *bitmap) +{ + HBITMAP hbmLoad; + INT nCountBefore = ImageList_GetImageCount(himlDef); + INT nCountAfter; + INT cxIcon, cyIcon; + INT nAdded; + INT nIndex; + + TRACE("adding hInst=%p nID=%d nButtons=%d\n", bitmap->hInst, bitmap->nID, bitmap->nButtons); + /* Add bitmaps to the default image list */ + if (bitmap->hInst == NULL) /* a handle was passed */ + { + BITMAP bmp; + HBITMAP hOldBitmapBitmap, hOldBitmapLoad; + HDC hdcImage, hdcBitmap; + + /* copy the bitmap before adding it so that the user's bitmap + * doesn't get modified. + */ + GetObjectW ((HBITMAP)bitmap->nID, sizeof(BITMAP), (LPVOID)&bmp); + + hdcImage = CreateCompatibleDC(0); + hdcBitmap = CreateCompatibleDC(0); + + /* create new bitmap */ + hbmLoad = CreateBitmap (bmp.bmWidth, bmp.bmHeight, bmp.bmPlanes, bmp.bmBitsPixel, NULL); + hOldBitmapBitmap = SelectObject(hdcBitmap, (HBITMAP)bitmap->nID); + hOldBitmapLoad = SelectObject(hdcImage, hbmLoad); + + /* Copy the user's image */ + BitBlt (hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, + hdcBitmap, 0, 0, SRCCOPY); + + SelectObject (hdcImage, hOldBitmapLoad); + SelectObject (hdcBitmap, hOldBitmapBitmap); + DeleteDC (hdcImage); + DeleteDC (hdcBitmap); + } + else + hbmLoad = CreateMappedBitmap(bitmap->hInst, bitmap->nID, 0, NULL, 0); + + /* enlarge the bitmap if needed */ + ImageList_GetIconSize(himlDef, &cxIcon, &cyIcon); + COMCTL32_EnsureBitmapSize(&hbmLoad, cxIcon*(INT)bitmap->nButtons, cyIcon, comctl32_color.clrBtnFace); + + nIndex = ImageList_AddMasked(himlDef, hbmLoad, comctl32_color.clrBtnFace); + DeleteObject(hbmLoad); + if (nIndex == -1) + return FALSE; + + nCountAfter = ImageList_GetImageCount(himlDef); + nAdded = nCountAfter - nCountBefore; + if (bitmap->nButtons == 0) /* wParam == 0 is special and means add only one image */ + { + ImageList_SetImageCount(himlDef, nCountBefore + 1); + } else if (nAdded > (INT)bitmap->nButtons) { + TRACE("Added more images than wParam: Previous image number %i added %i while wParam %i. Images in list %i\n", + nCountBefore, nAdded, bitmap->nButtons, nCountAfter); + } + + infoPtr->nNumBitmaps += nAdded; + return TRUE; +} + +static void +TOOLBAR_CheckImageListIconSize(TOOLBAR_INFO *infoPtr) +{ + HIMAGELIST himlDef; + HIMAGELIST himlNew; + INT cx, cy; + INT i; + + himlDef = GETDEFIMAGELIST(infoPtr, 0); + if (himlDef == NULL || himlDef != infoPtr->himlInt) + return; + if (!ImageList_GetIconSize(himlDef, &cx, &cy)) + return; + if (cx == infoPtr->nBitmapWidth && cy == infoPtr->nBitmapHeight) + return; + + TRACE("Update icon size: %dx%d -> %dx%d\n", + cx, cy, infoPtr->nBitmapWidth, infoPtr->nBitmapHeight); + + himlNew = ImageList_Create(infoPtr->nBitmapWidth, infoPtr->nBitmapHeight, + ILC_COLORDDB|ILC_MASK, 8, 2); + for (i = 0; i < infoPtr->nNumBitmapInfos; i++) + TOOLBAR_AddBitmapToImageList(infoPtr, himlNew, &infoPtr->bitmaps[i]); + TOOLBAR_InsertImageList(&infoPtr->himlDef, &infoPtr->cimlDef, himlNew, 0); + infoPtr->himlInt = himlNew; + + infoPtr->nNumBitmaps -= ImageList_GetImageCount(himlDef); + ImageList_Destroy(himlDef); +} /*********************************************************************** * TOOLBAR_AddBitmap: Add the bitmaps to the default image list. @@ -2578,8 +2677,8 @@ TOOLBAR_AddBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam) { TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd); LPTBADDBITMAP lpAddBmp = (LPTBADDBITMAP)lParam; - INT nIndex = 0, nButtons, nCount; - HBITMAP hbmLoad; + TBITMAP_INFO info; + INT iSumButtons, i; HIMAGELIST himlDef; TRACE("hwnd=%p wParam=%x lParam=%lx\n", hwnd, wParam, lParam); @@ -2588,16 +2687,38 @@ TOOLBAR_AddBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam) if (lpAddBmp->hInst == HINST_COMMCTRL) { - if ((lpAddBmp->nID & ~1) == IDB_STD_SMALL_COLOR) - nButtons = 15; - else if ((lpAddBmp->nID & ~1) == IDB_VIEW_SMALL_COLOR) - nButtons = 13; - else if ((lpAddBmp->nID & ~1) == IDB_HIST_SMALL_COLOR) - nButtons = 5; - else - return -1; + info.hInst = COMCTL32_hModule; + switch (lpAddBmp->nID) + { + case IDB_STD_SMALL_COLOR: + info.nButtons = 15; + info.nID = IDB_STD_SMALL; + break; + case IDB_STD_LARGE_COLOR: + info.nButtons = 15; + info.nID = IDB_STD_LARGE; + break; + case IDB_VIEW_SMALL_COLOR: + info.nButtons = 12; + info.nID = IDB_VIEW_SMALL; + break; + case IDB_VIEW_LARGE_COLOR: + info.nButtons = 12; + info.nID = IDB_VIEW_LARGE; + break; + case IDB_HIST_SMALL_COLOR: + info.nButtons = 5; + info.nID = IDB_HIST_SMALL; + break; + case IDB_HIST_LARGE_COLOR: + info.nButtons = 5; + info.nID = IDB_HIST_LARGE; + break; + default: + return -1; + } - TRACE ("adding %d internal bitmaps!\n", nButtons); + TRACE ("adding %d internal bitmaps!\n", info.nButtons); /* Windows resize all the buttons to the size of a newly added standard image */ if (lpAddBmp->nID & 1) @@ -2624,11 +2745,20 @@ TOOLBAR_AddBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam) } else { - nButtons = (INT)wParam; - if (nButtons <= 0) - return -1; - - TRACE ("adding %d bitmaps!\n", nButtons); + info.nButtons = (INT)wParam; + info.hInst = lpAddBmp->hInst; + info.nID = lpAddBmp->nID; + TRACE("adding %d bitmaps!\n", info.nButtons); + } + + /* check if the bitmap is already loaded and compute iSumButtons */ + iSumButtons = 0; + for (i = 0; i < infoPtr->nNumBitmapInfos; i++) + { + if (infoPtr->bitmaps[i].hInst == info.hInst && + infoPtr->bitmaps[i].nID == info.nID) + return iSumButtons; + iSumButtons += infoPtr->bitmaps[i].nButtons; } if (!infoPtr->cimlDef) { @@ -2636,7 +2766,7 @@ TOOLBAR_AddBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam) TRACE ("creating default image list!\n"); himlDef = ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight, - ILC_COLORDDB | ILC_MASK, nButtons, 2); + ILC_COLORDDB | ILC_MASK, info.nButtons, 2); TOOLBAR_InsertImageList(&infoPtr->himlDef, &infoPtr->cimlDef, himlDef, 0); infoPtr->himlInt = himlDef; } @@ -2649,145 +2779,17 @@ TOOLBAR_AddBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam) return -1; } - nCount = ImageList_GetImageCount(himlDef); - - /* Add bitmaps to the default image list */ - if (lpAddBmp->hInst == NULL) - { - BITMAP bmp; - HBITMAP hOldBitmapBitmap, hOldBitmapLoad; - HDC hdcImage, hdcBitmap; - - /* copy the bitmap before adding it so that the user's bitmap - * doesn't get modified. - */ - GetObjectW ((HBITMAP)lpAddBmp->nID, sizeof(BITMAP), (LPVOID)&bmp); - - hdcImage = CreateCompatibleDC(0); - hdcBitmap = CreateCompatibleDC(0); - - /* create new bitmap */ - hbmLoad = CreateBitmap (bmp.bmWidth, bmp.bmHeight, bmp.bmPlanes, bmp.bmBitsPixel, NULL); - hOldBitmapBitmap = SelectObject(hdcBitmap, (HBITMAP)lpAddBmp->nID); - hOldBitmapLoad = SelectObject(hdcImage, hbmLoad); - - /* Copy the user's image */ - BitBlt (hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, - hdcBitmap, 0, 0, SRCCOPY); - - SelectObject (hdcImage, hOldBitmapLoad); - SelectObject (hdcBitmap, hOldBitmapBitmap); - DeleteDC (hdcImage); - DeleteDC (hdcBitmap); - - nIndex = ImageList_AddMasked (himlDef, hbmLoad, comctl32_color.clrBtnFace); - DeleteObject (hbmLoad); - } - else if (lpAddBmp->hInst == HINST_COMMCTRL) - { - /* Add system bitmaps */ - switch (lpAddBmp->nID) - { - case IDB_STD_SMALL_COLOR: - hbmLoad = CreateMappedBitmap (COMCTL32_hModule, - IDB_STD_SMALL, 0, NULL, 0); - nIndex = ImageList_AddMasked (himlDef, - hbmLoad, comctl32_color.clrBtnFace); - DeleteObject (hbmLoad); - break; - - case IDB_STD_LARGE_COLOR: - hbmLoad = CreateMappedBitmap (COMCTL32_hModule, - IDB_STD_LARGE, 0, NULL, 0); - nIndex = ImageList_AddMasked (himlDef, - hbmLoad, comctl32_color.clrBtnFace); - DeleteObject (hbmLoad); - break; - - case IDB_VIEW_SMALL_COLOR: - hbmLoad = CreateMappedBitmap (COMCTL32_hModule, - IDB_VIEW_SMALL, 0, NULL, 0); - nIndex = ImageList_AddMasked (himlDef, - hbmLoad, comctl32_color.clrBtnFace); - DeleteObject (hbmLoad); - break; - - case IDB_VIEW_LARGE_COLOR: - hbmLoad = CreateMappedBitmap (COMCTL32_hModule, - IDB_VIEW_LARGE, 0, NULL, 0); - nIndex = ImageList_AddMasked (himlDef, - hbmLoad, comctl32_color.clrBtnFace); - DeleteObject (hbmLoad); - break; - - case IDB_HIST_SMALL_COLOR: - hbmLoad = CreateMappedBitmap (COMCTL32_hModule, - IDB_HIST_SMALL, 0, NULL, 0); - nIndex = ImageList_AddMasked (himlDef, - hbmLoad, comctl32_color.clrBtnFace); - DeleteObject (hbmLoad); - break; - - case IDB_HIST_LARGE_COLOR: - hbmLoad = CreateMappedBitmap (COMCTL32_hModule, - IDB_HIST_LARGE, 0, NULL, 0); - nIndex = ImageList_AddMasked (himlDef, - hbmLoad, comctl32_color.clrBtnFace); - DeleteObject (hbmLoad); - break; - - default: - nIndex = ImageList_GetImageCount (himlDef); - ERR ("invalid imagelist!\n"); - break; - } - } - else - { - hbmLoad = CreateMappedBitmap(lpAddBmp->hInst, lpAddBmp->nID, 0, NULL, 0); - nIndex = ImageList_AddMasked (himlDef, hbmLoad, comctl32_color.clrBtnFace); - DeleteObject (hbmLoad); - } + if (!TOOLBAR_AddBitmapToImageList(infoPtr, himlDef, &info)) + return -1; TRACE("Number of bitmap infos: %d\n", infoPtr->nNumBitmapInfos); - - if (infoPtr->nNumBitmapInfos == 0) - { - infoPtr->bitmaps = Alloc(sizeof(TBITMAP_INFO)); - } - else - { - TBITMAP_INFO *oldBitmaps = infoPtr->bitmaps; - infoPtr->bitmaps = Alloc((infoPtr->nNumBitmapInfos + 1) * sizeof(TBITMAP_INFO)); - memcpy(&infoPtr->bitmaps[0], &oldBitmaps[0], infoPtr->nNumBitmapInfos * sizeof(TBITMAP_INFO)); - } - - infoPtr->bitmaps[infoPtr->nNumBitmapInfos].nButtons = nButtons; - infoPtr->bitmaps[infoPtr->nNumBitmapInfos].hInst = lpAddBmp->hInst; - infoPtr->bitmaps[infoPtr->nNumBitmapInfos].nID = lpAddBmp->nID; - + infoPtr->bitmaps = ReAlloc(infoPtr->bitmaps, (infoPtr->nNumBitmapInfos + 1) * sizeof(TBITMAP_INFO)); + infoPtr->bitmaps[infoPtr->nNumBitmapInfos] = info; infoPtr->nNumBitmapInfos++; TRACE("Number of bitmap infos: %d\n", infoPtr->nNumBitmapInfos); - if (nIndex != -1) - { - INT imagecount = ImageList_GetImageCount(himlDef); - - if (infoPtr->nNumBitmaps + nButtons != imagecount) - { - WARN("Desired images do not match received images : Previous image number %i Previous images in list %i added %i expecting total %i, Images in list %i\n", - infoPtr->nNumBitmaps, nCount, imagecount - nCount, - infoPtr->nNumBitmaps+nButtons,imagecount); - - infoPtr->nNumBitmaps = imagecount; - } - else - infoPtr->nNumBitmaps += nButtons; - } - InvalidateRect(hwnd, NULL, TRUE); - - return nIndex; + return iSumButtons; } @@ -2929,64 +2931,57 @@ TOOLBAR_AddButtonsW (HWND hwnd, WPARAM wParam, LPARAM lParam) static LRESULT -TOOLBAR_AddStringA (HWND hwnd, WPARAM wParam, LPARAM lParam) +TOOLBAR_AddStringW (HWND hwnd, WPARAM wParam, LPARAM lParam) { +#define MAX_RESOURCE_STRING_LENGTH 512 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd); - INT nIndex; + INT nIndex = infoPtr->nNumStrings; if ((wParam) && (HIWORD(lParam) == 0)) { - char szString[256]; + WCHAR szString[MAX_RESOURCE_STRING_LENGTH]; + WCHAR delimiter; + WCHAR *next_delim; + WCHAR *p; INT len; TRACE("adding string from resource!\n"); - len = LoadStringA ((HINSTANCE)wParam, (UINT)lParam, szString, sizeof(szString)); + LoadStringW ((HINSTANCE)wParam, (UINT)lParam, + szString, MAX_RESOURCE_STRING_LENGTH); + len = lstrlenW(szString); - TRACE("len=%d \"%s\"\n", len, szString); - nIndex = infoPtr->nNumStrings; - if (infoPtr->nNumStrings == 0) { - infoPtr->strings = - Alloc (sizeof(LPWSTR)); - } - else { - LPWSTR *oldStrings = infoPtr->strings; - infoPtr->strings = - Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1)); - memcpy (&infoPtr->strings[0], &oldStrings[0], - sizeof(LPWSTR) * infoPtr->nNumStrings); - Free (oldStrings); - } + TRACE("len=%d %s\n", len, debugstr_w(szString)); + if (len == 0 || len == 1) + return nIndex; - /*Alloc zeros out the allocated memory*/ - Str_SetPtrAtoW (&infoPtr->strings[infoPtr->nNumStrings], szString ); - infoPtr->nNumStrings++; + TRACE("Delimiter: 0x%x\n", *szString); + delimiter = *szString; + p = szString + 1; + if (szString[len-1] == delimiter) + szString[len-1] = 0; + + while ((next_delim = strchrW(p, delimiter)) != NULL) { + *next_delim = 0; + + infoPtr->strings = ReAlloc(infoPtr->strings, sizeof(LPWSTR)*(infoPtr->nNumStrings+1)); + Str_SetPtrW(&infoPtr->strings[infoPtr->nNumStrings], p); + infoPtr->nNumStrings++; + + p = next_delim + 1; + } } else { - LPSTR p = (LPSTR)lParam; + LPWSTR p = (LPWSTR)lParam; INT len; if (p == NULL) return -1; TRACE("adding string(s) from array!\n"); - - nIndex = infoPtr->nNumStrings; while (*p) { - len = strlen (p); - TRACE("len=%d \"%s\"\n", len, p); + len = strlenW (p); - if (infoPtr->nNumStrings == 0) { - infoPtr->strings = - Alloc (sizeof(LPWSTR)); - } - else { - LPWSTR *oldStrings = infoPtr->strings; - infoPtr->strings = - Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1)); - memcpy (&infoPtr->strings[0], &oldStrings[0], - sizeof(LPWSTR) * infoPtr->nNumStrings); - Free (oldStrings); - } - - Str_SetPtrAtoW (&infoPtr->strings[infoPtr->nNumStrings], p ); + TRACE("len=%d %s\n", len, debugstr_w(p)); + infoPtr->strings = ReAlloc(infoPtr->strings, sizeof(LPWSTR)*(infoPtr->nNumStrings+1)); + Str_SetPtrW (&infoPtr->strings[infoPtr->nNumStrings], p); infoPtr->nNumStrings++; p += (len+1); @@ -2998,109 +2993,31 @@ TOOLBAR_AddStringA (HWND hwnd, WPARAM wParam, LPARAM lParam) static LRESULT -TOOLBAR_AddStringW (HWND hwnd, WPARAM wParam, LPARAM lParam) +TOOLBAR_AddStringA (HWND hwnd, WPARAM wParam, LPARAM lParam) { -#define MAX_RESOURCE_STRING_LENGTH 512 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd); + LPSTR p; INT nIndex; + INT len; - if ((wParam) && (HIWORD(lParam) == 0)) { - WCHAR szString[MAX_RESOURCE_STRING_LENGTH]; - INT len; - TRACE("adding string from resource!\n"); + if ((wParam) && (HIWORD(lParam) == 0)) /* load from resources */ + return TOOLBAR_AddStringW(hwnd, wParam, lParam); - len = LoadStringW ((HINSTANCE)wParam, (UINT)lParam, - szString, MAX_RESOURCE_STRING_LENGTH); + p = (LPSTR)lParam; + if (p == NULL) + return -1; - TRACE("len=%d %s\n", len, debugstr_w(szString)); - TRACE("First char: 0x%x\n", *szString); - if (szString[0] == L'|') - { - PWSTR p = szString + 1; + TRACE("adding string(s) from array!\n"); + nIndex = infoPtr->nNumStrings; + while (*p) { + len = strlen (p); + TRACE("len=%d \"%s\"\n", len, p); - nIndex = infoPtr->nNumStrings; - while (*p != L'|' && *p != L'\0') { - PWSTR np; + infoPtr->strings = ReAlloc(infoPtr->strings, sizeof(LPWSTR)*(infoPtr->nNumStrings+1)); + Str_SetPtrAtoW(&infoPtr->strings[infoPtr->nNumStrings], p); + infoPtr->nNumStrings++; - if (infoPtr->nNumStrings == 0) { - infoPtr->strings = Alloc (sizeof(LPWSTR)); - } - else - { - LPWSTR *oldStrings = infoPtr->strings; - infoPtr->strings = Alloc(sizeof(LPWSTR) * (infoPtr->nNumStrings + 1)); - memcpy(&infoPtr->strings[0], &oldStrings[0], - sizeof(LPWSTR) * infoPtr->nNumStrings); - Free(oldStrings); - } - - np=strchrW (p, '|'); - if (np!=NULL) { - len = np - p; - np++; - } else { - len = strlenW(p); - np = p + len; - } - TRACE("len=%d %s\n", len, debugstr_w(p)); - infoPtr->strings[infoPtr->nNumStrings] = - Alloc (sizeof(WCHAR)*(len+1)); - lstrcpynW (infoPtr->strings[infoPtr->nNumStrings], p, len+1); - infoPtr->nNumStrings++; - - p = np; - } - } - else - { - nIndex = infoPtr->nNumStrings; - if (infoPtr->nNumStrings == 0) { - infoPtr->strings = - Alloc (sizeof(LPWSTR)); - } - else { - LPWSTR *oldStrings = infoPtr->strings; - infoPtr->strings = - Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1)); - memcpy (&infoPtr->strings[0], &oldStrings[0], - sizeof(LPWSTR) * infoPtr->nNumStrings); - Free (oldStrings); - } - - Str_SetPtrW (&infoPtr->strings[infoPtr->nNumStrings], szString); - infoPtr->nNumStrings++; - } - } - else { - LPWSTR p = (LPWSTR)lParam; - INT len; - - if (p == NULL) - return -1; - TRACE("adding string(s) from array!\n"); - nIndex = infoPtr->nNumStrings; - while (*p) { - len = strlenW (p); - - TRACE("len=%d %s\n", len, debugstr_w(p)); - if (infoPtr->nNumStrings == 0) { - infoPtr->strings = - Alloc (sizeof(LPWSTR)); - } - else { - LPWSTR *oldStrings = infoPtr->strings; - infoPtr->strings = - Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1)); - memcpy (&infoPtr->strings[0], &oldStrings[0], - sizeof(LPWSTR) * infoPtr->nNumStrings); - Free (oldStrings); - } - - Str_SetPtrW (&infoPtr->strings[infoPtr->nNumStrings], p); - infoPtr->nNumStrings++; - - p += (len+1); - } + p += (len+1); } return nIndex; @@ -3301,7 +3218,7 @@ TOOLBAR_Customize (HWND hwnd) return FALSE; ret = DialogBoxIndirectParamW ((HINSTANCE)GetWindowLongPtrW(hwnd, GWLP_HINSTANCE), - (LPDLGTEMPLATEW)template, + (LPCDLGTEMPLATEW)template, hwnd, TOOLBAR_CustomizeDialogProc, (LPARAM)&custInfo); @@ -4746,6 +4663,7 @@ TOOLBAR_SetBitmapSize (HWND hwnd, WPARAM wParam, LPARAM lParam) infoPtr->nBitmapHeight); } + InvalidateRect(infoPtr->hwndSelf, NULL, FALSE); return TRUE; } @@ -5672,6 +5590,7 @@ TOOLBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam) /* delete temporary buffer for tooltip text */ Free (infoPtr->pszTooltipText); + Free (infoPtr->bitmaps); /* bitmaps list */ /* delete button data */ if (infoPtr->buttons)