// to invert the mask each time we pass one/get one to/from Windows
extern HBITMAP wxInvertMask(HBITMAP hbmpMask, int w = 0, int h = 0);
+// Creates an icon or cursor depending from a bitmap
+//
+// The bitmap must be valid and it should have a mask. If it doesn't, a default
+// mask is created using light grey as the transparent colour.
+extern HICON wxBitmapToHICON(const wxBitmap& bmp);
+
+// Same requirments as above apply and the bitmap must also have the correct
+// size.
+extern
+HCURSOR wxBitmapToHCURSOR(const wxBitmap& bmp, int hotSpotX, int hotSpotY);
+
// get (x, y) from DWORD - notice that HI/LOWORD can *not* be used because they
// will fail on system with multiple monitors where the coords may be negative
//
#endif
// ----------------------------------------------------------------------------
-// other helper functions
+// global helper functions implemented here
// ----------------------------------------------------------------------------
-extern HBITMAP wxInvertMask(HBITMAP hbmpMask, int w, int h)
+// helper of wxBitmapToHICON/HCURSOR
+static
+HICON wxBitmapToIconOrCursor(const wxBitmap& bmp,
+ bool iconWanted,
+ int hotSpotX,
+ int hotSpotY)
+{
+ if ( !bmp.Ok() )
+ {
+ // we can't create an icon/cursor form nothing
+ return 0;
+ }
+
+ wxMask *mask = bmp.GetMask();
+ if ( !mask )
+ {
+ // we must have a mask for an icon, so even if it's probably incorrect,
+ // do create it (grey is the "standard" transparent colour)
+ mask = new wxMask(bmp, *wxLIGHT_GREY);
+ }
+
+ ICONINFO iconInfo;
+ iconInfo.fIcon = iconWanted; // do we want an icon or a cursor?
+ if ( !iconWanted )
+ {
+ iconInfo.xHotspot = hotSpotX;
+ iconInfo.yHotspot = hotSpotY;
+ }
+
+ iconInfo.hbmMask = wxInvertMask((HBITMAP)mask->GetMaskBitmap());
+ 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(_T("BitBlt"));
+ }
+ }
+
+ HICON hicon = ::CreateIconIndirect(&iconInfo);
+
+ if ( !bmp.GetMask() )
+ {
+ // we created the mask, now delete it
+ delete mask;
+ }
+
+ // delete the inverted mask bitmap we created as well
+ ::DeleteObject(iconInfo.hbmMask);
+
+ return hicon;
+}
+
+HICON wxBitmapToHICON(const wxBitmap& bmp)
+{
+ return wxBitmapToIconOrCursor(bmp, TRUE, 0, 0);
+}
+
+HCURSOR wxBitmapToHCURSOR(const wxBitmap& bmp, int hotSpotX, int hotSpotY)
+{
+ return (HCURSOR)wxBitmapToIconOrCursor(bmp, FALSE, hotSpotX, hotSpotY);
+}
+
+HBITMAP wxInvertMask(HBITMAP hbmpMask, int w, int h)
{
#ifndef __WXMICROWIN__
wxCHECK_MSG( hbmpMask, 0, _T("invalid bitmap in wxInvertMask") );