diff --git a/src/msw/bitmap.cpp b/src/msw/bitmap.cpp index f724ee7001..f5fe48e148 100644 --- a/src/msw/bitmap.cpp +++ b/src/msw/bitmap.cpp @@ -55,6 +55,9 @@ #define CLR_INVALID ((COLORREF)-1) #endif // no CLR_INVALID +// ROP which doesn't have standard name +#define DSTERASE 0x00220326 // dest = (NOT src) AND dest + // ---------------------------------------------------------------------------- // wxBitmapRefData // ---------------------------------------------------------------------------- @@ -513,7 +516,6 @@ bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon, // AND mask: 0 <= y <= h-1 // XOR mask: h <= y <= 2*h-1 // First we need to extract and store XOR mask from this bitmap. - // AND mask will be extracted later at creation of inverted mask. HBITMAP hbmp = ::CreateBitmap(w, h, 1, wxDisplayDepth(), NULL); if ( !hbmp ) { @@ -531,6 +533,18 @@ bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon, { wxLogLastError(wxT("wxBitmap::CopyFromIconOrCursor - BitBlt")); } + // Prepare the AND mask to be compatible with wxBitmap mask + // by seting its bits to 0 wherever XOR mask (image) bits are set to 1. + // This is done in-place by applying the following ROP: + // dest = dest AND (NOT src) where dest=AND mask, src=XOR mask + // + // AND mask will be extracted later at creation of inverted mask. + if ( !::BitBlt((HDC)dcSrc, 0, 0, w, h, + (HDC)dcSrc, 0, h, + DSTERASE) ) + { + wxLogLastError(wxT("wxBitmap::CopyFromIconOrCursor - BitBlt")); + } } refData->m_width = w; refData->m_height = h; @@ -1908,6 +1922,21 @@ HICON wxBitmapToIconOrCursor(const wxBitmap& bmp, iconInfo.hbmMask = hbmpMask; iconInfo.hbmColor = GetHbitmapOf(bmp); + // black out the transparent area to preserve background colour, because + // Windows blits the original bitmap using SRCINVERT (XOR) after applying + // the mask to the dest rect. + { + MemoryHDC dcSrc, dcDst; + SelectInHDC selectMask(dcSrc, (HBITMAP)mask->GetMaskBitmap()), + selectBitmap(dcDst, iconInfo.hbmColor); + + if ( !::BitBlt(dcDst, 0, 0, bmp.GetWidth(), bmp.GetHeight(), + dcSrc, 0, 0, SRCAND) ) + { + wxLogLastError(wxT("BitBlt")); + } + } + HICON hicon = ::CreateIconIndirect(&iconInfo); if ( !bmp.GetMask() && !bmp.HasAlpha() )