From d9947ba7f7665fb34f3ef2d9b1cc60a36e90e33d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 19 Oct 2014 12:56:56 +0000 Subject: [PATCH] Fix creating wxBitmap from monochrome icon or cursor in wxMSW. Handle the "AND" and "XOR" masks inside monochrome icons/cursors correctly instead of simply copying the monochrome data which didn't work at all. See #16512. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@78038 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/msw/bitmap.cpp | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/msw/bitmap.cpp b/src/msw/bitmap.cpp index 49af364e2d..7ff59d3bc3 100644 --- a/src/msw/bitmap.cpp +++ b/src/msw/bitmap.cpp @@ -508,14 +508,34 @@ bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon, } else // we only have monochrome icon/cursor { - // Then we need to create our own empty bitmap, which will be modified - // by the mask below. - wxDIB dib(w, h, wxDisplayDepth()); - if ( dib.IsOk() ) + // For monochrome icons/cursor bitmap mask is of height 2*h + // and contains both AND and XOR masks. + // 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 ) { - memset(dib.GetData(), 0, wxDIB::GetLineSize(w, dib.GetDepth())*h); - refData->AssignDIB(dib); + wxLogLastError(wxT("wxBitmap::CopyFromIconOrCursor - CreateBitmap")); } + else + { + MemoryHDC dcSrc; + MemoryHDC dcDst; + SelectInHDC selSrc(dcSrc, iconInfo.hbmMask); + SelectInHDC selDst(dcDst, hbmp); + if ( !::BitBlt((HDC)dcDst, 0, 0, w, h, + (HDC)dcSrc, 0, h, + SRCCOPY) ) + { + wxLogLastError(wxT("wxBitmap::CopyFromIconOrCursor - BitBlt")); + } + } + refData->m_width = w; + refData->m_height = h; + refData->m_depth = wxDisplayDepth(); + refData->m_hBitmap = hbmp; } switch ( transp )