From 3192fb5396c05d84d351c3a08218d5308ba61b38 Mon Sep 17 00:00:00 2001 From: Ziqing Hui Date: Tue, 31 Mar 2020 17:45:42 +0300 Subject: [PATCH] comctl32/toolbar: Correctly draw disabled button which contains 32 bpp bitmap with alpha channel. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=24784 Signed-off-by: Ziqing Hui Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/comctl32/comctl32.h | 1 + dlls/comctl32/imagelist.c | 5 +++++ dlls/comctl32/toolbar.c | 36 ++++++++++++++++++++++++++++++++---- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/dlls/comctl32/comctl32.h b/dlls/comctl32/comctl32.h index 78e97983381..66b341ae5ad 100644 --- a/dlls/comctl32/comctl32.h +++ b/dlls/comctl32/comctl32.h @@ -191,6 +191,7 @@ INT Str_GetPtrWtoA (LPCWSTR lpSrc, LPSTR lpDest, INT nMaxLen) DECLSPEC_HIDDEN; INT Str_GetPtrAtoW (LPCSTR lpSrc, LPWSTR lpDest, INT nMaxLen) DECLSPEC_HIDDEN; BOOL Str_SetPtrAtoW (LPWSTR *lppDest, LPCSTR lpSrc) DECLSPEC_HIDDEN; BOOL Str_SetPtrWtoA (LPSTR *lppDest, LPCWSTR lpSrc) DECLSPEC_HIDDEN; +BOOL imagelist_has_alpha(HIMAGELIST, UINT) DECLSPEC_HIDDEN; #define COMCTL32_VERSION_MINOR 81 diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c index 925952351fa..013ae42f888 100644 --- a/dlls/comctl32/imagelist.c +++ b/dlls/comctl32/imagelist.c @@ -143,6 +143,11 @@ static BOOL is_valid(HIMAGELIST himl); #define TILE_COUNT 4 +BOOL imagelist_has_alpha( HIMAGELIST himl, UINT index ) +{ + return himl->item_flags[index] & ILIF_ALPHA; +} + static inline UINT imagelist_height( UINT count ) { return ((count + TILE_COUNT - 1)/TILE_COUNT); diff --git a/dlls/comctl32/toolbar.c b/dlls/comctl32/toolbar.c index c302e6c111f..b869cc4d7b3 100644 --- a/dlls/comctl32/toolbar.c +++ b/dlls/comctl32/toolbar.c @@ -675,18 +675,45 @@ TOOLBAR_DrawPattern (const RECT *lpRect, const NMTBCUSTOMDRAW *tbcd) static void TOOLBAR_DrawMasked(HIMAGELIST himl, int index, HDC hdc, INT x, INT y, UINT draw_flags) { + IMAGELISTDRAWPARAMS draw_params = { 0 }; INT cx, cy; HBITMAP hbmMask, hbmImage; HDC hdcMask, hdcImage; ImageList_GetIconSize(himl, &cx, &cy); + draw_params.cbSize = sizeof(draw_params); + draw_params.himl = himl; + draw_params.i = index; + draw_params.hdcDst = hdc; + draw_params.x = x; + draw_params.y = y; + draw_params.cx = cx; + draw_params.cy = cy; + draw_params.rgbBk = CLR_NONE; + draw_params.rgbFg = CLR_NONE; + draw_params.fStyle = draw_flags; + draw_params.fState = ILS_NORMAL; + + /* 32bpp image with alpha channel is converted to grayscale */ + if (imagelist_has_alpha(himl, index)) + { + draw_params.fState = ILS_SATURATE; + ImageList_DrawIndirect(&draw_params); + return; + } + /* Create src image */ hdcImage = CreateCompatibleDC(hdc); hbmImage = CreateCompatibleBitmap(hdc, cx, cy); SelectObject(hdcImage, hbmImage); - ImageList_DrawEx(himl, index, hdcImage, 0, 0, cx, cy, - RGB(0xff, 0xff, 0xff), RGB(0,0,0), draw_flags); + + draw_params.x = 0; + draw_params.y = 0; + draw_params.rgbBk = RGB(0xff, 0xff, 0xff); + draw_params.rgbFg = RGB(0,0,0); + draw_params.hdcDst = hdcImage; + ImageList_DrawIndirect(&draw_params); /* Create Mask */ hdcMask = CreateCompatibleDC(0); @@ -694,8 +721,9 @@ static void TOOLBAR_DrawMasked(HIMAGELIST himl, int index, HDC hdc, INT x, INT y SelectObject(hdcMask, hbmMask); /* Remove the background and all white pixels */ - ImageList_DrawEx(himl, index, hdcMask, 0, 0, cx, cy, - RGB(0xff, 0xff, 0xff), RGB(0,0,0), ILD_MASK); + draw_params.fStyle = ILD_MASK; + draw_params.hdcDst = hdcMask; + ImageList_DrawIndirect(&draw_params); SetBkColor(hdcImage, RGB(0xff, 0xff, 0xff)); BitBlt(hdcMask, 0, 0, cx, cy, hdcImage, 0, 0, NOTSRCERASE);