+ const wxBitmapRefData *
+ data = wx_static_cast(const wxBitmapRefData *, dataOrig);
+ if ( !data )
+ return NULL;
+
+ // FIXME: this method is backwards, it should just create a new
+ // wxBitmapRefData using its copy ctor but instead it modifies this
+ // bitmap itself and then returns its m_refData -- which works, of
+ // course (except in !wxUSE_WXDIB), but is completely illogical
+ wxBitmap *self = wx_const_cast(wxBitmap *, this);
+
+#if wxUSE_WXDIB
+ // copy the other bitmap
+ if ( data->m_hBitmap )
+ {
+ wxDIB dib((HBITMAP)(data->m_hBitmap));
+ self->CopyFromDIB(dib);
+ }
+ else
+#endif // wxUSE_WXDIB
+ {
+ // copy the bitmap data
+ self->m_refData = new wxBitmapRefData(*data);
+ }
+
+ wxBitmapRefData * const
+ selfdata = wx_static_cast(wxBitmapRefData *, m_refData);
+
+ // copy also the mask
+ wxMask * const maskSrc = data->GetMask();
+ if ( maskSrc )
+ {
+ selfdata->SetMask(new wxMask(*maskSrc));
+ }
+
+ return selfdata;
+}
+
+bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon,
+ wxBitmapTransparency transp)
+{
+#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
+ // it may be either HICON or HCURSOR
+ HICON hicon = (HICON)icon.GetHandle();
+
+ ICONINFO iconInfo;
+ if ( !::GetIconInfo(hicon, &iconInfo) )
+ {
+ wxLogLastError(wxT("GetIconInfo"));
+
+ return false;
+ }
+
+ wxBitmapRefData *refData = new wxBitmapRefData;
+ m_refData = refData;
+
+ int w = icon.GetWidth(),
+ h = icon.GetHeight();
+
+ refData->m_width = w;
+ refData->m_height = h;
+ refData->m_depth = wxDisplayDepth();
+
+ refData->m_hBitmap = (WXHBITMAP)iconInfo.hbmColor;
+
+ switch ( transp )
+ {
+ default:
+ wxFAIL_MSG( _T("unknown wxBitmapTransparency value") );
+
+ case wxBitmapTransparency_None:
+ // nothing to do, refData->m_hasAlpha is false by default
+ break;
+
+ case wxBitmapTransparency_Auto:
+#if wxUSE_WXDIB
+ // If the icon is 32 bits per pixel then it may have alpha channel
+ // data, although there are some icons that are 32 bpp but have no
+ // alpha... So convert to a DIB and manually check the 4th byte for
+ // each pixel.
+ {
+ BITMAP bm;
+ if ( ::GetObject(iconInfo.hbmColor, sizeof(bm), &bm) &&
+ (bm.bmBitsPixel == 32) )
+ {
+ wxDIB dib(iconInfo.hbmColor);
+ if (dib.IsOk())
+ {
+ const unsigned char* pixels = dib.GetData();
+ for (int idx = 0; idx < w*h*4; idx+=4)
+ {
+ if (pixels[idx+3] != 0)
+ {
+ // If there is an alpha byte that is non-zero
+ // then set the alpha flag and stop checking
+ refData->m_hasAlpha = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ break;
+#endif // wxUSE_WXDIB
+
+ case wxBitmapTransparency_Always:
+ refData->m_hasAlpha = true;
+ break;
+ }
+
+ if ( !refData->m_hasAlpha )
+ {
+ // the mask returned by GetIconInfo() is inverted compared to the usual
+ // wxWin convention
+ refData->SetMask(wxInvertMask(iconInfo.hbmMask, w, h));
+ }
+
+ // delete the old one now as we don't need it any more
+ ::DeleteObject(iconInfo.hbmMask);
+
+ return true;
+#else // __WXMICROWIN__ || __WXWINCE__
+ wxUnusedVar(icon);
+ wxUnusedVar(transp);
+
+ return false;
+#endif // !__WXWINCE__/__WXWINCE__