comctl32[1/2]: toolbar: resize the imagelist icons after a
TB_SETBITMAPSIZE (fixes bug #5654)
Mikołaj Zalewski
mikolaj at zalewski.pl
Thu Sep 21 15:12:24 CDT 2006
We do it during a WM_PAINT, like in the native implementation.
-------------- next part --------------
diff --git a/dlls/comctl32/tests/toolbar.c b/dlls/comctl32/tests/toolbar.c
index 096bfbe..dc0041e 100644
--- a/dlls/comctl32/tests/toolbar.c
+++ b/dlls/comctl32/tests/toolbar.c
@@ -150,6 +150,7 @@ void test_add_bitmap()
TBADDBITMAP bmp80;
TBADDBITMAP stdsmall;
TBADDBITMAP addbmp;
+ HIMAGELIST himl;
INT ret;
/* empty 128x15 bitmap */
@@ -235,11 +236,48 @@ void test_add_bitmap()
/* the icons can be resized - an UpdateWindow is needed as this probably happens during WM_PAINT */
ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(8, 8)) == TRUE, "TB_SETBITMAPSIZE failed\n");
UpdateWindow(hToolbar);
- CHECK_IMAGELIST_TODO_COUNT_SIZE(26, 8, 8);
+ CHECK_IMAGELIST(26, 8, 8);
/* loading a standard bitmaps automatically resizes the icons */
ok(SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&stdsmall) == 2, "TB_ADDBITMAP - unexpected return\n");
UpdateWindow(hToolbar);
- CHECK_IMAGELIST_TODO_COUNT_SIZE(28, 16, 15);
+ CHECK_IMAGELIST(28, 16, 15);
+
+ /* two more SETBITMAPSIZE tests */
+ rebuild_toolbar(&hToolbar);
+ ok(SendMessageA(hToolbar, TB_ADDBITMAP, 100, (LPARAM)&bmp128) == 0, "TB_ADDBITMAP - unexpected return\n");
+ CHECK_IMAGELIST(100, 16, 15);
+ ok(SendMessageA(hToolbar, TB_ADDBITMAP, 100, (LPARAM)&bmp80) == 100, "TB_ADDBITMAP - unexpected return\n");
+ CHECK_IMAGELIST(200, 16, 15);
+ ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(8, 8)) == TRUE, "TB_SETBITMAPSIZE failed\n");
+ UpdateWindow(hToolbar);
+ CHECK_IMAGELIST(200, 8, 8);
+ ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(30, 30)) == TRUE, "TB_SETBITMAPSIZE failed\n");
+ UpdateWindow(hToolbar);
+ CHECK_IMAGELIST(200, 30, 30);
+ rebuild_toolbar(&hToolbar);
+ ok(SendMessageA(hToolbar, TB_ADDBITMAP, 5, (LPARAM)&bmp128) == 0, "TB_ADDBITMAP - unexpected return\n");
+ CHECK_IMAGELIST(8, 16, 15);
+ ok(SendMessageA(hToolbar, TB_ADDBITMAP, 3, (LPARAM)&bmp80) == 5, "TB_ADDBITMAP - unexpected return\n");
+ CHECK_IMAGELIST(13, 16, 15);
+ ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(30, 30)) == TRUE, "TB_SETBITMAPSIZE failed\n");
+ UpdateWindow(hToolbar);
+ CHECK_IMAGELIST(8, 30, 30);
+
+ /* the control can add bitmaps to an existing image list */
+ rebuild_toolbar(&hToolbar);
+ himl = ImageList_LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BITMAP_80x15), 20, 2, CLR_NONE, IMAGE_BITMAP, LR_DEFAULTCOLOR);
+ ok(himl != NULL, "failed to create imagelist\n");
+ ok(SendMessageA(hToolbar, TB_SETIMAGELIST, 0, (LPARAM)himl) == 0, "TB_SETIMAGELIST failed\n");
+ CHECK_IMAGELIST(4, 20, 15);
+ ok(SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&bmp128) == 0, "TB_ADDBITMAP - unexpected return");
+ CHECK_IMAGELIST(10, 20, 15);
+ /* however TB_SETBITMAPSIZE/add std bitmap won't change the image size (the button size does change!) */
+ ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(8, 8)) == TRUE, "TB_SETBITMAPSIZE failed\n");
+ UpdateWindow(hToolbar);
+ CHECK_IMAGELIST(10, 20, 15);
+ ok(SendMessageA(hToolbar, TB_ADDBITMAP, 0, (LPARAM)&stdsmall) == 1, "TB_SETBITMAPSIZE failed\n");
+ UpdateWindow(hToolbar);
+ CHECK_IMAGELIST_TODO_COUNT(22, 20, 15);
/* check standard bitmaps */
addbmp.hInst = HINST_COMMCTRL;
diff --git a/dlls/comctl32/toolbar.c b/dlls/comctl32/toolbar.c
index f7c5aae..164a2fe 100644
--- a/dlls/comctl32/toolbar.c
+++ b/dlls/comctl32/toolbar.c
@@ -250,6 +250,7 @@ static HIMAGELIST TOOLBAR_InsertImageLis
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, PAI
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,98 @@ TOOLBAR_CustomizeDialogProc(HWND hwnd, U
}
}
+static BOOL
+TOOLBAR_AddBitmapToImageList(TOOLBAR_INFO *infoPtr, HIMAGELIST himlDef, const TBITMAP_INFO *bitmap)
+{
+ HBITMAP hbmLoad;
+ INT nCountBefore = ImageList_GetImageCount(himlDef);
+ INT nCountAfter;
+ 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);
+
+ 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) { /* if not enough buttons, grow the list */
+ ImageList_SetImageCount(himlDef, nCountBefore + bitmap->nButtons);
+ } 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.
@@ -2579,9 +2675,7 @@ TOOLBAR_AddBitmap (HWND hwnd, WPARAM wPa
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
LPTBADDBITMAP lpAddBmp = (LPTBADDBITMAP)lParam;
TBITMAP_INFO info;
- INT nIndex = 0, nCount;
INT iSumButtons, i;
- HBITMAP hbmLoad;
HIMAGELIST himlDef;
TRACE("hwnd=%p wParam=%x lParam=%lx\n", hwnd, wParam, lParam);
@@ -2682,42 +2776,8 @@ TOOLBAR_AddBitmap (HWND hwnd, WPARAM wPa
return -1;
}
- nCount = ImageList_GetImageCount(himlDef);
-
- /* Add bitmaps to the default image list */
- if (lpAddBmp->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)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);
- }
- else
- hbmLoad = CreateMappedBitmap(info.hInst, info.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);
infoPtr->bitmaps = ReAlloc(infoPtr->bitmaps, (infoPtr->nNumBitmapInfos + 1) * sizeof(TBITMAP_INFO));
@@ -2725,25 +2785,7 @@ TOOLBAR_AddBitmap (HWND hwnd, WPARAM wPa
infoPtr->nNumBitmapInfos++;
TRACE("Number of bitmap infos: %d\n", infoPtr->nNumBitmapInfos);
- if (nIndex != -1)
- {
- INT imagecount = ImageList_GetImageCount(himlDef);
- INT added = imagecount - nCount;
- if (info.nButtons == 0) /* wParam == 0 is special and means add only one image */
- {
- ImageList_SetImageCount(himlDef, nCount + 1);
- } else if (added < (INT)info.nButtons) { /* if not enough buttons, grow the list */
- ImageList_SetImageCount(himlDef, nCount + info.nButtons);
- } else if (added > (INT)info.nButtons) {
- TRACE("Added more images than wParam: Previous image number %i added %i while wParam %i. Images in list %i\n",
- nCount, added, info.nButtons, imagecount);
- }
-
- infoPtr->nNumBitmaps += added;
- }
-
InvalidateRect(hwnd, NULL, TRUE);
-
return iSumButtons;
}
@@ -4703,6 +4745,7 @@ TOOLBAR_SetBitmapSize (HWND hwnd, WPARAM
infoPtr->nBitmapHeight);
}
+ InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);
return TRUE;
}
--
1.4.1
More information about the wine-patches
mailing list