From 3704b45248c0924edf3c69208da1e615fd00e52d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 24 Feb 2016 23:20:24 +0100 Subject: [PATCH] Fix retrieving wxMask from wxBitmap in wxMSW In wxMask::GetBitmap() we need to create a copy of the mask bitmap and assign it to the resulting wxBitmap. We cannot simply assign existing mask bitmap to the resulting wxBitmap because when wxMask::GetBitmap would be called more then once then many independent wxBitmaps would own the same bitmap. Closes https://github.com/wxWidgets/wxWidgets/pull/230 Closes #17395. --- src/msw/bitmap.cpp | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/msw/bitmap.cpp b/src/msw/bitmap.cpp index 9b2c4ad9dc..984ad61074 100644 --- a/src/msw/bitmap.cpp +++ b/src/msw/bitmap.cpp @@ -1574,8 +1574,41 @@ bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour) wxBitmap wxMask::GetBitmap() const { + // We have to do a deep copy of the mask bitmap + // and assign it to the resulting wxBitmap. + + // Create new bitmap with the same parameters as a mask bitmap. + BITMAP bm; + ::GetObject(m_maskBitmap, sizeof(bm), (LPVOID)&bm); + + HBITMAP hNewBitmap = ::CreateBitmapIndirect(&bm); + if ( !hNewBitmap ) + { + wxLogLastError(wxS("CreateBitmapIndirect")); + return wxNullBitmap; + } + + // Copy the bitmap. + HDC hdcSrc = ::CreateCompatibleDC((HDC)NULL); + HBITMAP hSrcOldBmp = (HBITMAP)::SelectObject(hdcSrc, m_maskBitmap); + + HDC hdcMem = ::CreateCompatibleDC((HDC)NULL); + HBITMAP hMemOldBmp = (HBITMAP)::SelectObject(hdcMem, hNewBitmap); + + ::BitBlt(hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, hdcSrc, 0, 0, SRCCOPY); + ::SelectObject(hdcMem, hMemOldBmp); + + // Clean up. + ::SelectObject(hdcSrc, hSrcOldBmp); + ::DeleteDC(hdcSrc); + ::DeleteDC(hdcMem); + + // Create and return a new wxBitmap. wxBitmap bmp; - bmp.SetHBITMAP(m_maskBitmap); + bmp.SetHBITMAP((WXHBITMAP)hNewBitmap); + bmp.SetSize(bm.bmWidth, bm.bmHeight); + bmp.SetDepth(bm.bmPlanes); + return bmp; }