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