[PATCH 1/2] comctl32/imagelist: Implement IImageList::GetItemFlags().

Nikolay Sivov nsivov at codeweavers.com
Thu Mar 19 07:04:54 CDT 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/comctl32/imagelist.c       | 67 ++++++++++++---------------------
 dlls/comctl32/tests/imagelist.c | 26 ++++++++++++-
 include/commoncontrols.idl      |  3 +-
 3 files changed, 51 insertions(+), 45 deletions(-)

diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c
index 14a17c2717..237719cf7d 100644
--- a/dlls/comctl32/imagelist.c
+++ b/dlls/comctl32/imagelist.c
@@ -76,7 +76,7 @@ struct _IMAGELIST
     HBRUSH  hbrBlend50;
     INT     cInitial;
     UINT    uBitsPixel;
-    char   *has_alpha;
+    DWORD  *item_flags;
     BOOL    color_table_set;
 
     LONG        ref;                       /* reference count */
@@ -217,7 +217,7 @@ static void add_dib_bits( HIMAGELIST himl, int pos, int count, int width, int he
 
         if (has_alpha)
         {
-            himl->has_alpha[pos + n] = 1;
+            himl->item_flags[pos + n] = ILIF_ALPHA;
 
             if (mask_info && himl->hbmMask)  /* generate the mask from the alpha channel */
             {
@@ -251,7 +251,7 @@ static BOOL add_with_alpha( HIMAGELIST himl, HDC hdc, int pos, int count,
     if (!GetObjectW( hbmImage, sizeof(bm), &bm )) return FALSE;
 
     /* if either the imagelist or the source bitmap don't have an alpha channel, bail out now */
-    if (!himl->has_alpha) return FALSE;
+    if ((himl->flags & 0xfe) != ILC_COLOR32) return FALSE;
     if (bm.bmBitsPixel != 32) return FALSE;
 
     SelectObject( hdc, hbmImage );
@@ -368,17 +368,8 @@ IMAGELIST_InternalExpandBitmaps(HIMAGELIST himl, INT nImageCount)
         himl->hbmMask = hbmNewBitmap;
     }
 
-    if (himl->has_alpha)
-    {
-        char *new_alpha = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, himl->has_alpha, nNewCount );
-        if (new_alpha) himl->has_alpha = new_alpha;
-        else
-        {
-            heap_free( himl->has_alpha );
-            himl->has_alpha = NULL;
-        }
-    }
-
+    himl->item_flags = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, himl->item_flags,
+            nNewCount * sizeof(*himl->item_flags));
     himl->cMaxImage = nNewCount;
 
     DeleteDC (hdcBitmap);
@@ -844,10 +835,7 @@ ImageList_Create (INT cx, INT cy, UINT flags,
     else
         himl->hbmMask = 0;
 
-    if (ilc == ILC_COLOR32)
-        himl->has_alpha = heap_alloc_zero( himl->cMaxImage );
-    else
-        himl->has_alpha = NULL;
+    himl->item_flags = heap_alloc_zero( himl->cMaxImage * sizeof(*himl->item_flags) );
 
     /* create blending brushes */
     hbmTemp = CreateBitmap (8, 8, 1, 1, aBitBlend25);
@@ -1433,7 +1421,7 @@ ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
     oldImageFg = SetTextColor( hImageDC, RGB( 0, 0, 0 ) );
     oldImageBk = SetBkColor( hImageDC, RGB( 0xff, 0xff, 0xff ) );
 
-    has_alpha = (himl->has_alpha && himl->has_alpha[pimldp->i]);
+    has_alpha = himl->item_flags[pimldp->i] & ILIF_ALPHA;
     if (!bMask && (has_alpha || (fState & ILS_ALPHA) || (fState & ILS_SATURATE)))
     {
         COLORREF colour, blend_col = CLR_NONE;
@@ -1632,8 +1620,7 @@ ImageList_Duplicate (HIMAGELIST himlSrc)
                     himlSrc->hdcMask, 0, 0, SRCCOPY);
 
 	himlDst->cCurImage = himlSrc->cCurImage;
-        if (himlSrc->has_alpha && himlDst->has_alpha)
-            memcpy( himlDst->has_alpha, himlSrc->has_alpha, himlDst->cCurImage );
+        memcpy( himlDst->item_flags, himlSrc->item_flags, himlDst->cCurImage * sizeof(*himlDst->item_flags) );
     }
     return himlDst;
 }
@@ -2300,7 +2287,7 @@ HIMAGELIST WINAPI ImageList_Read(IStream *pstm)
     }
     else mask_info = NULL;
 
-    if (himl->has_alpha && image_info->bmiHeader.biBitCount == 32)
+    if ((himl->flags & 0xfe) == ILC_COLOR32 && image_info->bmiHeader.biBitCount == 32)
     {
         DWORD *ptr = image_bits;
         BYTE *mask_ptr = mask_bits;
@@ -2396,11 +2383,8 @@ ImageList_Remove (HIMAGELIST himl, INT i)
         for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
              himl->nOvlIdx[nCount] = -1;
 
-        if (himl->has_alpha)
-        {
-            heap_free( himl->has_alpha );
-            himl->has_alpha = heap_alloc_zero( himl->cMaxImage );
-        }
+        heap_free( himl->item_flags );
+        himl->item_flags = heap_alloc_zero( himl->cMaxImage * sizeof(*himl->item_flags) );
 
         hbmNewImage = ImageList_CreateImage(himl->hdcImage, himl, himl->cMaxImage);
         SelectObject (himl->hdcImage, hbmNewImage);
@@ -2615,7 +2599,7 @@ ImageList_ReplaceIcon (HIMAGELIST himl, INT nIndex, HICON hIcon)
         himl->cCurImage++;
     }
 
-    if (himl->has_alpha && GetIconInfo (hBestFitIcon, &ii))
+    if ((himl->flags & 0xfe) == ILC_COLOR32 && GetIconInfo (hBestFitIcon, &ii))
     {
         HDC hdcImage = CreateCompatibleDC( 0 );
         GetObjectW (ii.hbmMask, sizeof(BITMAP), &bmp);
@@ -2940,16 +2924,8 @@ ImageList_SetImageCount (HIMAGELIST himl, UINT iImageCount)
 
     DeleteDC (hdcBitmap);
 
-    if (himl->has_alpha)
-    {
-        char *new_alpha = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, himl->has_alpha, nNewCount );
-        if (new_alpha) himl->has_alpha = new_alpha;
-        else
-        {
-            heap_free( himl->has_alpha );
-            himl->has_alpha = NULL;
-        }
-    }
+    himl->item_flags = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, himl->item_flags,
+            nNewCount * sizeof(*himl->item_flags));
 
     /* Update max image count and current image count */
     himl->cMaxImage = nNewCount;
@@ -3292,7 +3268,7 @@ static ULONG WINAPI ImageListImpl_Release(IImageList2 *iface)
         if (This->hbrBlend50) DeleteObject (This->hbrBlend50);
 
         This->IImageList2_iface.lpVtbl = NULL;
-        heap_free(This->has_alpha);
+        heap_free(This->item_flags);
         heap_free(This);
     }
 
@@ -3626,11 +3602,16 @@ static HRESULT WINAPI ImageListImpl_GetDragImage(IImageList2 *iface, POINT *ppt,
     return ret;
 }
 
-static HRESULT WINAPI ImageListImpl_GetItemFlags(IImageList2 *iface, int i,
-    DWORD *dwFlags)
+static HRESULT WINAPI ImageListImpl_GetItemFlags(IImageList2 *iface, int i, DWORD *flags)
 {
-    FIXME("STUB: %p %d %p\n", iface, i, dwFlags);
-    return E_NOTIMPL;
+    HIMAGELIST This = impl_from_IImageList2(iface);
+
+    if (i < 0 || i >= This->cCurImage)
+        return E_INVALIDARG;
+
+    *flags = This->item_flags[i];
+
+    return S_OK;
 }
 
 static HRESULT WINAPI ImageListImpl_GetOverlayImage(IImageList2 *iface, int iOverlay,
diff --git a/dlls/comctl32/tests/imagelist.c b/dlls/comctl32/tests/imagelist.c
index 984ca053c8..427ce1a84c 100644
--- a/dlls/comctl32/tests/imagelist.c
+++ b/dlls/comctl32/tests/imagelist.c
@@ -1502,6 +1502,9 @@ static void test_ImageList_DrawIndirect(void)
     UINT32 *bits = 0;
     UINT32 maskBits = 0x00000000, inverseMaskBits = 0xFFFFFFFF;
     int bpp, broken_value;
+    IImageList *imgl;
+    DWORD flags;
+    HRESULT hr;
 
     BITMAPINFO bitmapInfo = {{sizeof(BITMAPINFOHEADER), 2, 1, 1, 32, BI_RGB,
                                 0, 0, 0, 0, 0}};
@@ -1524,6 +1527,9 @@ static void test_ImageList_DrawIndirect(void)
     ok(himl != 0, "ImageList_Create failed\n");
     if(!himl) goto cleanup;
 
+    hr = pHIMAGELIST_QueryInterface(himl, &IID_IImageList, (void **) &imgl);
+    ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
+
     /* Add a no-alpha image */
     hbmImage = create_test_bitmap(hdcDst, 2, 1, 32, bits_image);
     if(!hbmImage) goto cleanup;
@@ -1532,6 +1538,16 @@ static void test_ImageList_DrawIndirect(void)
     ok(iImage != -1, "ImageList_Add failed\n");
     if(iImage == -1) goto cleanup;
 
+    hr = IImageList_GetItemFlags(imgl, 1000, &flags);
+    ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+
+    hr = IImageList_GetItemFlags(imgl, 1000, NULL);
+    ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+
+    hr = IImageList_GetItemFlags(imgl, iImage, &flags);
+    ok(hr == S_OK, "Failed to get item flags, hr %#x.\n", hr);
+    ok(!flags, "Unexpected flags %#x.\n", flags);
+
     /* Add an alpha image */
     hbmAlphaImage = create_test_bitmap(hdcDst, 2, 1, 32, bits_alpha);
     if(!hbmAlphaImage) goto cleanup;
@@ -1540,6 +1556,10 @@ static void test_ImageList_DrawIndirect(void)
     ok(iAlphaImage != -1, "ImageList_Add failed\n");
     if(iAlphaImage == -1) goto cleanup;
 
+    hr = IImageList_GetItemFlags(imgl, iAlphaImage, &flags);
+    ok(hr == S_OK, "Failed to get item flags, hr %#x.\n", hr);
+    ok(flags & ILIF_ALPHA, "Unexpected flags %#x.\n", flags);
+
     /* Add a transparent alpha image */
     hbmTransparentImage = create_test_bitmap(hdcDst, 2, 1, 32, bits_transparent);
     if(!hbmTransparentImage) goto cleanup;
@@ -1548,6 +1568,10 @@ static void test_ImageList_DrawIndirect(void)
     ok(iTransparentImage != -1, "ImageList_Add failed\n");
     if(iTransparentImage == -1) goto cleanup;
 
+    hr = IImageList_GetItemFlags(imgl, iTransparentImage, &flags);
+    ok(hr == S_OK, "Failed to get item flags, hr %#x.\n", hr);
+    ok(flags & ILIF_ALPHA, "Unexpected flags %#x.\n", flags);
+
     /* 32-bit Tests */
     bitmapInfo.bmiHeader.biBitCount = 32;
     hbmDst = CreateDIBSection(hdcDst, &bitmapInfo, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
@@ -1713,7 +1737,7 @@ static void test_iimagelist(void)
     if (!himl)
         return;
 
-    hr = (pHIMAGELIST_QueryInterface)(himl, &IID_IImageList, (void **) &imgl);
+    hr = pHIMAGELIST_QueryInterface(himl, &IID_IImageList, (void **) &imgl);
     ok(SUCCEEDED(hr), "HIMAGELIST_QueryInterface failed, hr=%x\n", hr);
 
     if (hr == S_OK)
diff --git a/include/commoncontrols.idl b/include/commoncontrols.idl
index 8cfcb56309..407274994e 100644
--- a/include/commoncontrols.idl
+++ b/include/commoncontrols.idl
@@ -63,7 +63,8 @@ cpp_quote("#endif")
 
 cpp_quote("HRESULT WINAPI ImageList_CoCreateInstance(REFCLSID,const IUnknown *, REFIID,void **);")
 
-const UINT ILIF_ALPHA = 1;
+cpp_quote("#define ILIF_ALPHA      0x00000001")
+cpp_quote("#define ILIF_LOWQUALITY 0x00000002")
 
 [
     uuid(46eb5926-582e-4017-9fdf-e8998daa0950),
-- 
2.25.1




More information about the wine-devel mailing list