ImageList - reuse DCs

Vitaliy Margolen wine-patch at kievinfo.com
Sun May 11 14:31:55 CDT 2003


This patch is mostly an optimization for ImageList. Instead of creating DCs
every time we need to access images & | masks why not to keep them around?

Sorry for attaching the patch - it's kind of big and my e-mail client can't inline text.

Vitaliy Margolen

changelog:
  - imagelist.c
    reuse Image and Mask DCs
  - imagelist.h
    rearrange members of HIMAGELIST to match Windows
-------------- next part --------------
Index: dlls/comctl32/imagelist.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/imagelist.c,v
retrieving revision 1.73
diff -u -r1.73 imagelist.c
--- dlls/comctl32/imagelist.c	2 Apr 2003 23:18:17 -0000	1.73
+++ dlls/comctl32/imagelist.c	11 May 2003 19:18:01 -0000
@@ -100,8 +100,8 @@
 static void
 IMAGELIST_InternalExpandBitmaps (HIMAGELIST himl, INT nImageCount, INT cx, INT cy)
 {
-    HDC     hdcImageList, hdcBitmap;
-    HBITMAP hbmNewBitmap;
+    HDC     hdcBitmap;
+    HBITMAP hbmNewBitmap, hbmNull;
     INT     nNewWidth, nNewCount;
 
     if ((himl->cCurImage + nImageCount <= himl->cMaxImage)
@@ -113,7 +113,6 @@
     nNewWidth = nNewCount * himl->cx;
 
     TRACE("Create expanded bitmaps : himl=%p x=%d y=%d count=%d\n", himl, nNewWidth, cy, nNewCount);
-    hdcImageList = CreateCompatibleDC (0);
     hdcBitmap = CreateCompatibleDC (0);
 
     hbmNewBitmap =
@@ -121,11 +120,12 @@
     if (hbmNewBitmap == 0)
         ERR("creating new image bitmap (x=%d y=%d)!\n", nNewWidth, cy);
 
-    SelectObject (hdcImageList, himl->hbmImage);
-    SelectObject (hdcBitmap, hbmNewBitmap);
+    hbmNull = SelectObject (hdcBitmap, hbmNewBitmap);
     BitBlt (hdcBitmap, 0, 0, himl->cCurImage * himl->cx, cy,
-              hdcImageList, 0, 0, SRCCOPY);
+              himl->hdcImage, 0, 0, SRCCOPY);
 
+    SelectObject (hdcBitmap, hbmNull);
+    SelectObject (himl->hdcImage, hbmNewBitmap);
     DeleteObject (himl->hbmImage);
     himl->hbmImage = hbmNewBitmap;
 
@@ -136,17 +136,17 @@
         if (hbmNewBitmap == 0)
             ERR("creating new mask bitmap!\n");
 
-        SelectObject (hdcImageList, himl->hbmMask);
         SelectObject (hdcBitmap, hbmNewBitmap);
         BitBlt (hdcBitmap, 0, 0, himl->cCurImage * himl->cx, cy,
-                  hdcImageList, 0, 0, SRCCOPY);
+                  himl->hdcMask, 0, 0, SRCCOPY);
+        SelectObject (hdcBitmap, hbmNull);
+        SelectObject (himl->hdcMask, hbmNewBitmap);
         DeleteObject (himl->hbmMask);
         himl->hbmMask = hbmNewBitmap;
     }
 
     himl->cMaxImage = nNewCount;
 
-    DeleteDC (hdcImageList);
     DeleteDC (hdcBitmap);
 }
 
@@ -169,11 +169,11 @@
 INT WINAPI
 ImageList_Add (HIMAGELIST himl,	HBITMAP hbmImage, HBITMAP hbmMask)
 {
-    HDC     hdcImage, hdcBitmap;
+    HDC     hdcBitmap;
     INT     nFirstIndex, nImageCount;
     INT     nStartX;
     BITMAP  bmp;
-    HBITMAP hOldBitmapImage, hOldBitmap;
+    HBITMAP hOldBitmap;
 
     TRACE("himl=%p hbmimage=%p hbmmask=%p\n", himl, hbmImage, hbmMask);
     if (!is_valid(himl))
@@ -186,28 +186,24 @@
 
     nStartX = himl->cCurImage * himl->cx;
 
-    hdcImage  = CreateCompatibleDC(0);
     hdcBitmap = CreateCompatibleDC(0);
 
-    hOldBitmapImage = SelectObject(hdcImage, himl->hbmImage);
     hOldBitmap = SelectObject(hdcBitmap, hbmImage);
 
     /* Copy result to the imagelist
     */
-    BitBlt (hdcImage, nStartX, 0, bmp.bmWidth, bmp.bmHeight,
+    BitBlt (himl->hdcImage, nStartX, 0, bmp.bmWidth, bmp.bmHeight,
         hdcBitmap, 0, 0, SRCCOPY);
 
     if(himl->hbmMask)
     {
-	HDC hdcMask, hdcTemp;
-	HBITMAP hOldBitmapMask, hOldBitmapTemp;
+	HDC hdcTemp;
+	HBITMAP hOldBitmapTemp;
 
-        hdcMask   = CreateCompatibleDC (0);
         hdcTemp   = CreateCompatibleDC(0);
-        hOldBitmapMask = SelectObject(hdcMask, himl->hbmMask);
         hOldBitmapTemp = SelectObject(hdcTemp, hbmMask);
 
-        BitBlt (hdcMask,
+        BitBlt (himl->hdcMask,
             nStartX, 0, bmp.bmWidth, bmp.bmHeight,
             hdcTemp,
             0, 0,
@@ -218,19 +214,14 @@
 
         /* Remove the background from the image
         */
-        BitBlt (hdcImage,
+        BitBlt (himl->hdcImage,
             nStartX, 0, bmp.bmWidth, bmp.bmHeight,
-            hdcMask,
+            himl->hdcMask,
             nStartX, 0,
             0x220326); /* NOTSRCAND */
-
-        SelectObject(hdcMask, hOldBitmapMask);
-        DeleteDC(hdcMask);
     }
 
-    SelectObject(hdcImage, hOldBitmapImage);
     SelectObject(hdcBitmap, hOldBitmap);
-    DeleteDC(hdcImage);
     DeleteDC(hdcBitmap);
 
     nFirstIndex = himl->cCurImage;
@@ -279,10 +270,10 @@
 INT WINAPI
 ImageList_AddMasked (HIMAGELIST himl, HBITMAP hBitmap, COLORREF clrMask)
 {
-    HDC    hdcImage, hdcMask, hdcBitmap;
+    HDC    hdcMask, hdcBitmap;
     INT    nIndex, nImageCount, nMaskXOffset=0;
     BITMAP bmp;
-    HBITMAP hOldBitmap, hOldBitmapMask, hOldBitmapImage;
+    HBITMAP hOldBitmap;
     HBITMAP hMaskBitmap=0;
     COLORREF bkColor;
 
@@ -300,16 +291,13 @@
     nIndex = himl->cCurImage;
     himl->cCurImage += nImageCount;
 
-    hdcMask   = CreateCompatibleDC (0);
-    hdcImage  = CreateCompatibleDC(0);
     hdcBitmap = CreateCompatibleDC(0);
 
 
-    hOldBitmapImage = SelectObject(hdcImage, himl->hbmImage);
     hOldBitmap = SelectObject(hdcBitmap, hBitmap);
     if(himl->hbmMask)
     {
-        hOldBitmapMask = SelectObject(hdcMask, himl->hbmMask);
+        hdcMask = himl->hdcMask;
         nMaskXOffset = nIndex * himl->cx;
     }
     else
@@ -318,8 +306,9 @@
             Create a temp Mask so we can remove the background of
             the Image (Windows does this even if there is no mask)
         */
+        hdcMask = CreateCompatibleDC(0);
         hMaskBitmap = CreateBitmap(bmp.bmWidth, bmp.bmHeight, 1, 1, NULL);
-        hOldBitmapMask = SelectObject(hdcMask, hMaskBitmap);
+        SelectObject(hdcMask, hMaskBitmap);
         nMaskXOffset = 0;
     }
     /* create monochrome image to the mask bitmap */
@@ -350,22 +339,19 @@
         0x220326); /* NOTSRCAND */
     /* Copy result to the imagelist
     */
-    BitBlt (hdcImage,
+    BitBlt (himl->hdcImage,
         nIndex * himl->cx, 0, bmp.bmWidth, bmp.bmHeight,
         hdcBitmap,
         0, 0,
         SRCCOPY);
     /* Clean up
     */
-    SelectObject(hdcMask,hOldBitmapMask);
-    SelectObject(hdcImage, hOldBitmapImage);
     SelectObject(hdcBitmap, hOldBitmap);
-    DeleteDC(hdcMask);
-    DeleteDC(hdcImage);
     DeleteDC(hdcBitmap);
     if(!himl->hbmMask)
     {
         DeleteObject(hMaskBitmap);
+        DeleteDC(hdcMask);
     }
 
     return nIndex;
@@ -393,7 +379,6 @@
 ImageList_BeginDrag (HIMAGELIST himlTrack, INT iTrack,
 	             INT dxHotspot, INT dyHotspot)
 {
-    HDC hdcSrc, hdcDst;
     INT cx, cy;
 
     TRACE("(himlTrack=%p iTrack=%d dx=%d dy=%d)\n", himlTrack, iTrack,
@@ -417,21 +402,11 @@
     InternalDrag.dxHotspot = dxHotspot;
     InternalDrag.dyHotspot = dyHotspot;
 
-    hdcSrc = CreateCompatibleDC (0);
-    hdcDst = CreateCompatibleDC (0);
-
     /* copy image */
-    SelectObject (hdcSrc, himlTrack->hbmImage);
-    SelectObject (hdcDst, InternalDrag.himl->hbmImage);
-    BitBlt (hdcDst, 0, 0, cx, cy, hdcSrc, iTrack * cx, 0, SRCCOPY);
+    BitBlt (InternalDrag.himl->hdcImage, 0, 0, cx, cy, himlTrack->hdcImage, iTrack * cx, 0, SRCCOPY);
 
     /* copy mask */
-    SelectObject (hdcSrc, himlTrack->hbmMask);
-    SelectObject (hdcDst, InternalDrag.himl->hbmMask);
-    BitBlt (hdcDst, 0, 0, cx, cy, hdcSrc, iTrack * cx, 0, SRCCOPY);
-
-    DeleteDC (hdcSrc);
-    DeleteDC (hdcDst);
+    BitBlt (InternalDrag.himl->hdcMask, 0, 0, cx, cy, himlTrack->hdcMask, iTrack * cx, 0, SRCCOPY);
 
     InternalDrag.himl->cCurImage = 1;
     InternalDrag.bHSPending = TRUE;
@@ -467,8 +442,6 @@
 ImageList_Copy (HIMAGELIST himlDst, INT iDst,	HIMAGELIST himlSrc,
 		INT iSrc, INT uFlags)
 {
-    HDC hdcSrc, hdcDst;
-
     TRACE("iDst=%d  iSrc=%d\n", iDst, iSrc);
 
     if (!is_valid(himlSrc) || !is_valid(himlDst))
@@ -478,16 +451,13 @@
     if ((iSrc < 0) || (iSrc >= himlSrc->cCurImage))
 	return FALSE;
 
-    hdcSrc = CreateCompatibleDC (0);
-    if (himlDst == himlSrc)
-        hdcDst = hdcSrc;
-    else
-        hdcDst = CreateCompatibleDC (0);
-
     if (uFlags & ILCF_SWAP) {
         /* swap */
+        HDC     hdcBmp;
         HBITMAP hbmTempImage, hbmTempMask;
 
+        hdcBmp = CreateCompatibleDC (0);
+        
         /* create temporary bitmaps */
         hbmTempImage = CreateBitmap (himlSrc->cx, himlSrc->cy, 1,
                                        himlSrc->uBitsPixel, NULL);
@@ -496,74 +466,51 @@
 
         /* copy (and stretch) destination to temporary bitmaps.(save) */
         /* image */
-        SelectObject (hdcSrc, himlDst->hbmImage);
-        SelectObject (hdcDst, hbmTempImage);
-        StretchBlt (hdcDst, 0, 0, himlSrc->cx, himlSrc->cy,
-                      hdcSrc, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
+        SelectObject (hdcBmp, hbmTempImage);
+        StretchBlt   (hdcBmp, 0, 0, himlSrc->cx, himlSrc->cy,
+                      himlDst->hdcImage, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
                       SRCCOPY);
         /* mask */
-        SelectObject (hdcSrc, himlDst->hbmMask);
-        SelectObject (hdcDst, hbmTempMask);
-        StretchBlt (hdcDst, 0, 0, himlSrc->cx, himlSrc->cy,
-                      hdcSrc, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
+        SelectObject (hdcBmp, hbmTempMask);
+        StretchBlt   (hdcBmp, 0, 0, himlSrc->cx, himlSrc->cy,
+                      himlDst->hdcMask, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
                       SRCCOPY);
 
         /* copy (and stretch) source to destination */
         /* image */
-        SelectObject (hdcSrc, himlSrc->hbmImage);
-        SelectObject (hdcDst, himlDst->hbmImage);
-        StretchBlt (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
-                      hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
+        StretchBlt   (himlDst->hdcImage, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
+                      himlSrc->hdcImage, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
                       SRCCOPY);
         /* mask */
-        SelectObject (hdcSrc, himlSrc->hbmMask);
-        SelectObject (hdcDst, himlDst->hbmMask);
-        StretchBlt (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
-                      hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
+        StretchBlt   (himlDst->hdcMask, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
+                      himlSrc->hdcMask, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
                       SRCCOPY);
 
         /* copy (without stretching) temporary bitmaps to source (restore) */
-        /* image */
-        SelectObject (hdcSrc, hbmTempImage);
-        SelectObject (hdcDst, himlSrc->hbmImage);
-        BitBlt (hdcDst, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
-                  hdcSrc, 0, 0, SRCCOPY);
         /* mask */
-        SelectObject (hdcSrc, hbmTempMask);
-        SelectObject (hdcDst, himlSrc->hbmMask);
-        BitBlt (hdcDst, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
-                  hdcSrc, 0, 0, SRCCOPY);
+        BitBlt       (himlSrc->hdcMask, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
+                      hdcBmp, 0, 0, SRCCOPY);
 
+        /* image */
+        BitBlt       (himlSrc->hdcImage, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
+                      hdcBmp, 0, 0, SRCCOPY);
         /* delete temporary bitmaps */
         DeleteObject (hbmTempMask);
         DeleteObject (hbmTempImage);
+        DeleteDC(hdcBmp);
     }
     else {
         /* copy image */
-        SelectObject (hdcSrc, himlSrc->hbmImage);
-        if (himlSrc == himlDst)
-            hdcDst = hdcSrc;
-        else
-            SelectObject (hdcDst, himlDst->hbmImage);
-        StretchBlt (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
-                      hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
+        StretchBlt   (himlDst->hdcImage, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
+                      himlSrc->hdcImage, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
                       SRCCOPY);
 
         /* copy mask */
-        SelectObject (hdcSrc, himlSrc->hbmMask);
-        if (himlSrc == himlDst)
-            hdcDst = hdcSrc;
-        else
-            SelectObject (hdcDst, himlDst->hbmMask);
-        StretchBlt (hdcDst, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
-                      hdcSrc, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
+        StretchBlt   (himlDst->hdcMask, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
+                      himlSrc->hdcMask, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
                       SRCCOPY);
     }
 
-    DeleteDC (hdcSrc);
-    if (himlSrc != himlDst)
-        DeleteDC (hdcDst);
-
     return TRUE;
 }
 
@@ -588,7 +535,6 @@
 		  INT cInitial, INT cGrow)
 {
     HIMAGELIST himl;
-    HDC      hdc;
     INT      nCount;
     HBITMAP  hbmTemp;
     static WORD aBitBlend25[] =
@@ -603,6 +549,8 @@
     if (!himl)
         return NULL;
 
+    cGrow = (cGrow < 4) ? 4 : (cGrow + 3) & ~3;
+
     himl->magic     = IMAGELIST_MAGIC;
     himl->cx        = cx;
     himl->cy        = cy;
@@ -610,21 +558,24 @@
     himl->cMaxImage = cInitial + cGrow;
     himl->cInitial  = cInitial;
     himl->cGrow     = cGrow;
-    himl->cCurImage = 0;
     himl->clrFg     = CLR_DEFAULT;
     himl->clrBk     = CLR_NONE;
-    himl->hbmImage  = 0;
-    himl->hbmMask   = 0;
-    himl->hbrBlend25 = 0;
-    himl->hbrBlend50 = 0;
 
     /* initialize overlay mask indices */
     for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
         himl->nOvlIdx[nCount] = -1;
 
-    hdc = CreateCompatibleDC (0);
-    himl->uBitsPixel = (UINT)GetDeviceCaps (hdc, BITSPIXEL);
-    DeleteDC (hdc);
+    /* Create Image & Mask DCs */
+    himl->hdcImage = CreateCompatibleDC (0);
+    if (!himl->hdcImage)
+        goto cleanup;
+    if (himl->flags & ILC_MASK){
+        himl->hdcMask = CreateCompatibleDC(0);
+        if (!himl->hdcMask)
+            goto cleanup;
+    }
+
+    himl->uBitsPixel = (UINT)GetDeviceCaps (himl->hdcImage, BITSPIXEL);
 
     TRACE("Image: %d Bits per Pixel\n", himl->uBitsPixel);
 
@@ -634,28 +585,21 @@
                         1, himl->uBitsPixel, NULL);
 	if (himl->hbmImage == 0) {
 	    ERR("Error creating image bitmap!\n");
-	    ImageList_Destroy(himl);
-	    return NULL;
+            goto cleanup;
 	}
+        SelectObject(himl->hdcImage, himl->hbmImage);
     }
-    else
-        himl->hbmImage = 0;
-
-    if ( (himl->flags & ILC_MASK)) {
-        int images = himl->cMaxImage;
-        if (images <= 0)
-            images = 1;
 
-        himl->hbmMask = CreateBitmap (himl->cx * images, himl->cy,
-					1, 1, NULL);
+    if (himl->flags & ILC_MASK) {
+        himl->hbmMask =
+          CreateBitmap (himl->cx * himl->cMaxImage, himl->cy,
+			1, 1, NULL);
         if (himl->hbmMask == 0) {
             ERR("Error creating mask bitmap!\n");
-            ImageList_Destroy(himl);
-            return NULL;
+            goto cleanup;
         }
+        SelectObject(himl->hdcMask, himl->hbmMask);
     }
-    else
-        himl->hbmMask = 0;
 
     /* create blending brushes */
     hbmTemp = CreateBitmap (8, 8, 1, 1, &aBitBlend25);
@@ -668,6 +612,10 @@
 
     TRACE("created imagelist %p\n", himl);
     return himl;
+
+cleanup:
+    if (himl) ImageList_Destroy(himl);
+    return NULL;
 }
 
 
@@ -696,6 +644,12 @@
     if (himl->hbmMask)
         DeleteObject (himl->hbmMask);
 
+    /* delete image & mask DCs */
+    if (himl->hdcImage)
+        DeleteDC(himl->hdcImage);
+    if (himl->hdcMask)
+        DeleteDC(himl->hdcMask);
+
     /* delete blending brushes */
     if (himl->hbrBlend25)
         DeleteObject (himl->hbrBlend25);
@@ -1090,7 +1044,7 @@
     UINT fStyle;
     COLORREF clrBk, oldImageBk, oldImageFg;
     HDC hImageDC, hImageListDC, hMaskListDC;
-    HBITMAP hImageBmp, hOldImageBmp, hOldImageListBmp, hOldMaskListBmp, hBlendMaskBmp;
+    HBITMAP hImageBmp, hOldImageBmp, hBlendMaskBmp;
     BOOL bIsTransparent, bBlend, bResult = FALSE;
     HIMAGELIST himl;
 
@@ -1113,8 +1067,8 @@
           himl->hbmMask, pimldp->i, pimldp->x, pimldp->y, cx, cy);
 
     /* we will use these DCs to access the images and masks in the ImageList */
-    hImageListDC = CreateCompatibleDC(0);
-    hMaskListDC = himl->hbmMask ? CreateCompatibleDC(0) : 0;
+    hImageListDC = himl->hdcImage;
+    hMaskListDC  = himl->hdcMask;
 
     /* these will accumulate the image and mask for the image we're drawing */
     hImageDC = CreateCompatibleDC( pimldp->hdcDst );
@@ -1126,9 +1080,7 @@
 	(bBlend && !hBlendMaskBmp) || (himl->hbmMask && !hMaskListDC))
 	goto cleanup;
     
-    hOldImageListBmp = SelectObject(hImageListDC, himl->hbmImage);
     hOldImageBmp = SelectObject(hImageDC, hImageBmp);
-    hOldMaskListBmp = hMaskListDC ? SelectObject(hMaskListDC, himl->hbmMask) : 0;
   
     /*
      * To obtain a transparent look, background color should be set
@@ -1230,14 +1182,10 @@
     SetBkColor(hImageDC, oldImageBk);
     SetTextColor(hImageDC, oldImageFg);
     SelectObject(hImageDC, hOldImageBmp);
-    SelectObject(hImageListDC, hOldImageListBmp);
-    if (hMaskListDC) SelectObject(hMaskListDC, hOldMaskListBmp);
 cleanup:
     DeleteObject(hBlendMaskBmp);
     DeleteObject(hImageBmp);
     DeleteDC(hImageDC);
-    DeleteDC(hImageListDC);
-    DeleteDC(hMaskListDC);
 
     return bResult;
 }
@@ -1258,7 +1206,6 @@
 ImageList_Duplicate (HIMAGELIST himlSrc)
 {
     HIMAGELIST himlDst;
-    HDC hdcSrc, hdcDst;
 
     if (!is_valid(himlSrc)) {
         ERR("Invalid image list handle!\n");
@@ -1270,23 +1217,12 @@
 
     if (himlDst)
     {
-        hdcSrc = CreateCompatibleDC (0);
-        hdcDst = CreateCompatibleDC (0);
-        SelectObject (hdcSrc, himlSrc->hbmImage);
-        SelectObject (hdcDst, himlDst->hbmImage);
-        BitBlt (hdcDst, 0, 0, himlSrc->cCurImage * himlSrc->cx, himlSrc->cy,
-                  hdcSrc, 0, 0, SRCCOPY);
+        BitBlt (himlDst->hdcImage, 0, 0, himlSrc->cCurImage * himlSrc->cx, himlSrc->cy,
+                himlSrc->hdcImage, 0, 0, SRCCOPY);
 
         if (himlDst->hbmMask)
-        {
-            SelectObject (hdcSrc, himlSrc->hbmMask);
-            SelectObject (hdcDst, himlDst->hbmMask);
-            BitBlt (hdcDst, 0, 0, himlSrc->cCurImage * himlSrc->cx,
-                      himlSrc->cy, hdcSrc, 0, 0, SRCCOPY);
-        }
-
-        DeleteDC (hdcDst);
-        DeleteDC (hdcSrc);
+            BitBlt (himlDst->hdcMask, 0, 0, himlSrc->cCurImage * himlSrc->cx, himlSrc->cy,
+                    himlSrc->hdcMask, 0, 0, SRCCOPY);
 
 	himlDst->cCurImage = himlSrc->cCurImage;
 	himlDst->cMaxImage = himlSrc->cMaxImage;
@@ -1419,22 +1355,26 @@
     HBITMAP hOldDstBitmap;
     HDC hdcDst;
 
+    TRACE("%p %d %d\n", himl, i, fStyle);
     if (!is_valid(himl) || (i < 0) || (i >= himl->cCurImage)) return NULL;
 
     hdcDst = CreateCompatibleDC(0);
 
     ii.fIcon = TRUE;
+    ii.xHotspot = 0;
+    ii.yHotspot = 0;
 
     /* draw mask*/
     ii.hbmMask  = CreateCompatibleBitmap (hdcDst, himl->cx, himl->cy);
-    hOldDstBitmap = (HBITMAP)SelectObject (hdcDst, ii.hbmMask);
-    ImageList_Draw(himl, i, hdcDst, 0, 0, ILD_MASK);
+    hOldDstBitmap = SelectObject (hdcDst, ii.hbmMask);
+    PatBlt (hdcDst, 0, 0, himl->cx, himl->cy, WHITENESS);
+    ImageList_Draw(himl, i, hdcDst, 0, 0, fStyle | ILD_MASK);
 
     /* draw image*/
-    SelectObject (hdcDst, himl->hbmImage);
-    ii.hbmColor = CreateCompatibleBitmap (hdcDst, himl->cx, himl->cy);
+    ii.hbmColor = CreateCompatibleBitmap (himl->hdcImage, himl->cx, himl->cy);
     SelectObject (hdcDst, ii.hbmColor);
-    ImageList_Draw(himl, i, hdcDst, 0, 0, fStyle);
+    PatBlt (hdcDst, 0, 0, himl->cx, himl->cy, BLACKNESS);
+    ImageList_Draw(himl, i, hdcDst, 0, 0, fStyle | ILD_TRANSPARENT);
 
     /*
      * CreateIconIndirect requires us to deselect the bitmaps from
@@ -1779,7 +1719,6 @@
 		 INT dx, INT dy)
 {
     HIMAGELIST himlDst = NULL;
-    HDC      hdcSrcImage, hdcDstImage;
     INT      cxDst, cyDst;
     INT      xOff1, yOff1, xOff2, yOff2;
     INT      nX1, nX2;
@@ -1838,41 +1777,20 @@
         return NULL;
 
     if (himlDst) {
-        hdcSrcImage = CreateCompatibleDC (0);
-        hdcDstImage = CreateCompatibleDC (0);
         nX1 = i1 * himl1->cx;
         nX2 = i2 * himl2->cx;
 
         /* copy image */
-        SelectObject (hdcSrcImage, himl1->hbmImage);
-        SelectObject (hdcDstImage, himlDst->hbmImage);
-        BitBlt (hdcDstImage, 0, 0, cxDst, cyDst,
-                  hdcSrcImage, 0, 0, BLACKNESS);
-        BitBlt (hdcDstImage, xOff1, yOff1, himl1->cx, himl1->cy,
-                  hdcSrcImage, nX1, 0, SRCCOPY);
-
-        SelectObject (hdcSrcImage, himl2->hbmMask);
-        BitBlt (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy,
-                  hdcSrcImage, nX2, 0, SRCAND);
-
-        SelectObject (hdcSrcImage, himl2->hbmImage);
-        BitBlt (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy,
-                  hdcSrcImage, nX2, 0, SRCPAINT);
+        BitBlt (himlDst->hdcImage,     0,     0,     cxDst,     cyDst, himl1->hdcImage,   0, 0, BLACKNESS);
+        BitBlt (himlDst->hdcImage, xOff1, yOff1, himl1->cx, himl1->cy, himl1->hdcImage, nX1, 0, SRCCOPY);
+        BitBlt (himlDst->hdcImage, xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcMask , nX2, 0, SRCAND);
+        BitBlt (himlDst->hdcImage, xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcImage, nX2, 0, SRCPAINT);
 
         /* copy mask */
-        SelectObject (hdcSrcImage, himl1->hbmMask);
-        SelectObject (hdcDstImage, himlDst->hbmMask);
-        BitBlt (hdcDstImage, 0, 0, cxDst, cyDst,
-                  hdcSrcImage, 0, 0, WHITENESS);
-        BitBlt (hdcDstImage, xOff1, yOff1, himl1->cx, himl1->cy,
-                  hdcSrcImage, nX1, 0, SRCCOPY);
-
-        SelectObject (hdcSrcImage, himl2->hbmMask);
-        BitBlt (hdcDstImage, xOff2, yOff2, himl2->cx, himl2->cy,
-                  hdcSrcImage, nX2, 0, SRCAND);
+        BitBlt (himlDst->hdcMask,      0,     0,     cxDst,     cyDst, himl1->hdcMask,    0, 0, WHITENESS);
+        BitBlt (himlDst->hdcMask,  xOff1, yOff1, himl1->cx, himl1->cy, himl1->hdcMask,  nX1, 0, SRCCOPY);
+        BitBlt (himlDst->hdcMask,  xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcMask,  nX2, 0, SRCAND);
 
-        DeleteDC (hdcSrcImage);
-        DeleteDC (hdcDstImage);
 	himlDst->cCurImage = 1;
     }
 
@@ -2069,8 +1987,14 @@
 	DeleteObject(hbmMask);
 	return NULL;
     }
+    SelectObject(himl->hdcImage, hbmColor);
+    DeleteObject(himl->hbmImage);
     himl->hbmImage = hbmColor;
-    himl->hbmMask = hbmMask;
+    if (hbmMask){
+        SelectObject(himl->hdcMask, hbmMask);
+        DeleteObject(himl->hbmMask);
+        himl->hbmMask = hbmMask;
+    }
     himl->cCurImage = ilHead.cCurImage;
     himl->cMaxImage = ilHead.cMaxImage;
 
@@ -2097,7 +2021,7 @@
 ImageList_Remove (HIMAGELIST himl, INT i)
 {
     HBITMAP hbmNewImage, hbmNewMask;
-    HDC     hdcSrc, hdcDst;
+    HDC     hdcBmp;
     INT     cxNew, nCount;
 
     TRACE("(himl=%p i=%d)\n", himl, i);
@@ -2125,16 +2049,18 @@
         for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
              himl->nOvlIdx[nCount] = -1;
 
-        DeleteObject (himl->hbmImage);
-        himl->hbmImage =
-            CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
+        hbmNewImage = CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
                             1, himl->uBitsPixel, NULL);
+        SelectObject (himl->hdcImage, hbmNewImage);
+        DeleteObject (himl->hbmImage);
+        himl->hbmImage = hbmNewImage;
 
         if (himl->hbmMask) {
-            DeleteObject (himl->hbmMask);
-            himl->hbmMask =
-                CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
+            hbmNewMask = CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
                                 1, 1, NULL);
+            SelectObject (himl->hdcMask, hbmNewMask);
+            DeleteObject (himl->hbmMask);
+            himl->hbmMask = hbmNewMask;
         }
     }
     else {
@@ -2157,50 +2083,46 @@
         else
             hbmNewMask = 0;  /* Just to keep compiler happy! */
 
-        hdcSrc = CreateCompatibleDC (0);
-        hdcDst = CreateCompatibleDC (0);
+        hdcBmp = CreateCompatibleDC (0);
 
         /* copy all images and masks prior to the "removed" image */
         if (i > 0) {
             TRACE("Pre image copy: Copy %d images\n", i);
 
-            SelectObject (hdcSrc, himl->hbmImage);
-            SelectObject (hdcDst, hbmNewImage);
-            BitBlt (hdcDst, 0, 0, i * himl->cx, himl->cy,
-                      hdcSrc, 0, 0, SRCCOPY);
+            SelectObject (hdcBmp, hbmNewImage);
+            BitBlt (hdcBmp, 0, 0, i * himl->cx, himl->cy,
+                    himl->hdcImage, 0, 0, SRCCOPY);
 
             if (himl->hbmMask) {
-                SelectObject (hdcSrc, himl->hbmMask);
-                SelectObject (hdcDst, hbmNewMask);
-                BitBlt (hdcDst, 0, 0, i * himl->cx, himl->cy,
-                          hdcSrc, 0, 0, SRCCOPY);
+                SelectObject (hdcBmp, hbmNewMask);
+                BitBlt (hdcBmp, 0, 0, i * himl->cx, himl->cy,
+                        himl->hdcMask, 0, 0, SRCCOPY);
             }
         }
 
         /* copy all images and masks behind the removed image */
         if (i < himl->cCurImage - 1) {
             TRACE("Post image copy!\n");
-            SelectObject (hdcSrc, himl->hbmImage);
-            SelectObject (hdcDst, hbmNewImage);
-            BitBlt (hdcDst, i * himl->cx, 0, (himl->cCurImage - i - 1) * himl->cx,
-                      himl->cy, hdcSrc, (i + 1) * himl->cx, 0, SRCCOPY);
+            SelectObject (hdcBmp, hbmNewImage);
+            BitBlt (hdcBmp, i * himl->cx, 0, (himl->cCurImage - i - 1) * himl->cx,
+                      himl->cy, himl->hdcImage, (i + 1) * himl->cx, 0, SRCCOPY);
 
             if (himl->hbmMask) {
-                SelectObject (hdcSrc, himl->hbmMask);
-                SelectObject (hdcDst, hbmNewMask);
-                BitBlt (hdcDst, i * himl->cx, 0,
+                SelectObject (hdcBmp, hbmNewMask);
+                BitBlt (hdcBmp, i * himl->cx, 0,
                           (himl->cCurImage - i - 1) * himl->cx,
-                          himl->cy, hdcSrc, (i + 1) * himl->cx, 0, SRCCOPY);
+                          himl->cy, himl->hdcMask, (i + 1) * himl->cx, 0, SRCCOPY);
             }
         }
 
-        DeleteDC (hdcSrc);
-        DeleteDC (hdcDst);
+        DeleteDC (hdcBmp);
 
         /* delete old images and insert new ones */
+        SelectObject (himl->hdcImage, hbmNewImage);
         DeleteObject (himl->hbmImage);
         himl->hbmImage = hbmNewImage;
         if (himl->hbmMask) {
+            SelectObject (himl->hdcMask, hbmNewMask);
             DeleteObject (himl->hbmMask);
             himl->hbmMask = hbmNewMask;
         }
@@ -2233,7 +2155,7 @@
 ImageList_Replace (HIMAGELIST himl, INT i, HBITMAP hbmImage,
 		   HBITMAP hbmMask)
 {
-    HDC hdcImageList, hdcImage;
+    HDC hdcImage;
     BITMAP bmp;
 
     TRACE("%p %d %p %p\n", himl, i, hbmImage, hbmMask);
@@ -2248,31 +2170,27 @@
         return FALSE;
     }
 
-    hdcImageList = CreateCompatibleDC (0);
     hdcImage = CreateCompatibleDC (0);
     GetObjectA (hbmImage, sizeof(BITMAP), (LPVOID)&bmp);
 
     /* Replace Image */
-    SelectObject (hdcImageList, himl->hbmImage);
     SelectObject (hdcImage, hbmImage);
 
-    StretchBlt (hdcImageList, i * himl->cx, 0, himl->cx, himl->cy,
+    StretchBlt (himl->hdcImage, i * himl->cx, 0, himl->cx, himl->cy,
                   hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
 
     if (himl->hbmMask)
     {
         /* Replace Mask */
-        SelectObject (hdcImageList, himl->hbmMask);
         SelectObject (hdcImage, hbmMask);
 
-        StretchBlt (hdcImageList, i * himl->cx, 0, himl->cx, himl->cy,
+        StretchBlt (himl->hdcMask, i * himl->cx, 0, himl->cx, himl->cy,
                       hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
 
 
         /* Remove the background from the image
         */
-        SelectObject (hdcImageList, himl->hbmImage);
-        StretchBlt (hdcImageList,
+        StretchBlt (himl->hdcImage,
             i*himl->cx, 0, himl->cx, himl->cy,
             hdcImage,
             0, 0, bmp.bmWidth, bmp.bmHeight,
@@ -2280,7 +2198,6 @@
     }
 
     DeleteDC (hdcImage);
-    DeleteDC (hdcImageList);
 
     return TRUE;
 }
@@ -2304,10 +2221,10 @@
 INT WINAPI
 ImageList_ReplaceIcon (HIMAGELIST himl, INT i, HICON hIcon)
 {
-    HDC     hdcImageList, hdcImage;
+    HDC     hdcImage;
     INT     nIndex;
     HICON   hBestFitIcon;
-    HBITMAP hbmOldSrc, hbmOldDst;
+    HBITMAP hbmOldSrc;
     ICONINFO  ii;
     BITMAP  bmp;
 
@@ -2340,37 +2257,28 @@
     else
         nIndex = i;
 
-    hdcImageList = CreateCompatibleDC (0);
-    TRACE("hdcImageList=%p!\n", hdcImageList);
-    if (hdcImageList == 0)
-	ERR("invalid hdcImageList!\n");
-
     hdcImage = CreateCompatibleDC (0);
-    TRACE("hdcImage=%p!\n", hdcImage);
+    TRACE("hdcImage=%p\n", hdcImage);
     if (hdcImage == 0)
 	ERR("invalid hdcImage!\n");
 
-    hbmOldDst = SelectObject (hdcImageList, himl->hbmImage);
-    SetTextColor( hdcImageList, RGB(0,0,0));
-    SetBkColor( hdcImageList, RGB(255,255,255));
+    SetTextColor(himl->hdcImage, RGB(0,0,0));
+    SetBkColor  (himl->hdcImage, RGB(255,255,255));
     hbmOldSrc = SelectObject (hdcImage, ii.hbmColor);
-    StretchBlt (hdcImageList, nIndex * himl->cx, 0, himl->cx, himl->cy,
+
+    StretchBlt (himl->hdcImage, nIndex * himl->cx, 0, himl->cx, himl->cy,
                   hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
 
     if (himl->hbmMask) {
-        SelectObject (hdcImageList, himl->hbmMask);
         SelectObject (hdcImage, ii.hbmMask);
-        StretchBlt (hdcImageList, nIndex * himl->cx, 0, himl->cx, himl->cy,
+        StretchBlt   (himl->hdcMask, nIndex * himl->cx, 0, himl->cx, himl->cy,
                       hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
     }
 
     SelectObject (hdcImage, hbmOldSrc);
-    SelectObject (hdcImageList, hbmOldDst);
 
     if(hBestFitIcon)
 	DestroyIcon(hBestFitIcon);
-    if (hdcImageList)
-	DeleteDC (hdcImageList);
     if (hdcImage)
 	DeleteDC (hdcImage);
     if (ii.hbmColor)
@@ -2555,6 +2463,7 @@
 ImageList_SetIconSize (HIMAGELIST himl, INT cx, INT cy)
 {
     INT nCount;
+    HBITMAP hbmNew;
 
     if (!is_valid(himl))
 	return FALSE;
@@ -2569,16 +2478,18 @@
     for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
         himl->nOvlIdx[nCount] = -1;
 
-    DeleteObject (himl->hbmImage);
-    himl->hbmImage =
-        CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
+    hbmNew = CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
                         1, himl->uBitsPixel, NULL);
+    SelectObject (himl->hdcImage, hbmNew);
+    DeleteObject (himl->hbmImage);
+    himl->hbmImage = hbmNew;
 
     if (himl->hbmMask) {
-        DeleteObject (himl->hbmMask);
-        himl->hbmMask =
-            CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
+        hbmNew = CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
                             1, 1, NULL);
+        SelectObject (himl->hdcMask, hbmNew);
+        DeleteObject (himl->hbmMask);
+        himl->hbmMask = hbmNew;
     }
 
     return TRUE;
@@ -2602,7 +2513,7 @@
 BOOL WINAPI
 ImageList_SetImageCount (HIMAGELIST himl, INT iImageCount)
 {
-    HDC     hdcImageList, hdcBitmap;
+    HDC     hdcBitmap;
     HBITMAP hbmNewBitmap;
     INT     nNewCount, nCopyCount;
 
@@ -2621,19 +2532,17 @@
     nNewCount = iImageCount + himl->cGrow;
     nCopyCount = min(himl->cCurImage, iImageCount);
 
-    hdcImageList = CreateCompatibleDC (0);
     hdcBitmap = CreateCompatibleDC (0);
 
     hbmNewBitmap = CreateBitmap (nNewCount * himl->cx, himl->cy,
                                    1, himl->uBitsPixel, NULL);
     if (hbmNewBitmap != 0)
     {
-        SelectObject (hdcImageList, himl->hbmImage);
         SelectObject (hdcBitmap, hbmNewBitmap);
 
 	/* copy images */
         BitBlt (hdcBitmap, 0, 0, nCopyCount * himl->cx, himl->cy,
-                  hdcImageList, 0, 0, SRCCOPY);
+                himl->hdcImage, 0, 0, SRCCOPY);
 #if 0
 	/* delete 'empty' image space */
 	SetBkColor (hdcBitmap, RGB(255, 255, 255));
@@ -2641,6 +2550,7 @@
 	PatBlt (hdcBitmap,  nCopyCount * himl->cx, 0,
 		  (nNewCount - nCopyCount) * himl->cx, himl->cy, BLACKNESS);
 #endif
+        SelectObject (himl->hdcImage, hbmNewBitmap);
 	DeleteObject (himl->hbmImage);
 	himl->hbmImage = hbmNewBitmap;
     }
@@ -2653,12 +2563,11 @@
                                        1, 1, NULL);
         if (hbmNewBitmap != 0)
         {
-            SelectObject (hdcImageList, himl->hbmMask);
             SelectObject (hdcBitmap, hbmNewBitmap);
 
 	    /* copy images */
             BitBlt (hdcBitmap, 0, 0, nCopyCount * himl->cx, himl->cy,
-                      hdcImageList, 0, 0, SRCCOPY);
+                    himl->hdcMask, 0, 0, SRCCOPY);
 #if 0
 	    /* delete 'empty' image space */
 	    SetBkColor (hdcBitmap, RGB(255, 255, 255));
@@ -2666,6 +2575,7 @@
             PatBlt (hdcBitmap,  nCopyCount * himl->cx, 0,
 		      (nNewCount - nCopyCount) * himl->cx, himl->cy, BLACKNESS);
 #endif
+            SelectObject (himl->hdcMask, hbmNewBitmap);
             DeleteObject (himl->hbmMask);
             himl->hbmMask = hbmNewBitmap;
         }
@@ -2673,7 +2583,6 @@
             ERR("Could not create new mask bitmap!\n");
     }
 
-    DeleteDC (hdcImageList);
     DeleteDC (hdcBitmap);
 
     /* Update max image count and current image count */
Index: dlls/comctl32/imagelist.h
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/imagelist.h,v
retrieving revision 1.4
diff -u -r1.4 imagelist.h
--- dlls/comctl32/imagelist.h	2 Jan 2003 17:51:13 -0000	1.4
+++ dlls/comctl32/imagelist.h	11 May 2003 19:18:01 -0000
@@ -29,28 +29,29 @@
 /* the ones with offsets at the end are the same as in Windows */
 struct _IMAGELIST
 {
-    DWORD	magic; 			/* 00:	'SAMX' */
-    INT		cCurImage;		/* 04: ImageCount */
-    INT		cMaxImage;		/* 08: maximages */
-    DWORD	x3;
-    INT		cx;			/* 10: cx */
-    INT		cy;			/* 14: cy */
-    DWORD	x4;
-    UINT	flags;			/* 1c: flags */
-    DWORD   	x5;
-    COLORREF	clrBk;			/* 24: bkcolor */
+    DWORD       magic;                  /* 00: 'SAMX' */
+    INT         cCurImage;              /* 04: ImageCount */
+    INT         cMaxImage;              /* 08: maximages */
+    INT         cGrow;                  /* 0c: cGrow */
+    INT         cx;                     /* 10: cx */
+    INT         cy;                     /* 14: cy */
+    DWORD       x4;
+    UINT        flags;                  /* 1c: flags */
+    COLORREF    clrFg;                  /* 20: foreground color */
+    COLORREF    clrBk;                  /* 24: backgournd color */
 
 
+    HBITMAP     hbmImage;               /* 30: images Bitmap */
+    HBITMAP     hbmMask;                /* 34: masks  Bitmap */
+    HDC         hdcImage;               /* 38: images MemDC  */
+    HDC         hdcMask;                /* 3C: masks  MemDC  */
+    INT         nOvlIdx[15];            /* 40: overlay images inedx */
+
     /* not yet found out */
-    HBITMAP hbmImage;
-    HBITMAP hbmMask;
     HBRUSH  hbrBlend25;
     HBRUSH  hbrBlend50;
-    COLORREF  clrFg;
     INT     cInitial;
-    INT     cGrow;
     UINT    uBitsPixel;
-    INT     nOvlIdx[15];
 };
 
 #define IMAGELIST_MAGIC 0x53414D58




More information about the wine-patches mailing list