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.
This commit is contained in:
Vadim Zeitlin
2016-02-24 23:20:24 +01:00
parent 1c9a4694ff
commit 3704b45248

View File

@@ -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;
}