void SetBackgroundMaskImage(LPCTSTR lpszImageName)
{
COLORREF crAlpha = RGB(255, 0, 0);
Gdiplus::Bitmap* pBkgrMaskBitmap = CImageFactory::getSingletonPtr()->GetSkinItemImage(lpszImageName);
struct PixelData
{
BYTE B;
BYTE G;
BYTE R;
BYTE A;
};
HRGN hRgn = NULL;
if (pBkgrMaskBitmap)
{
//if (Gdiplus::IsAlphaPixelFormat((Gdiplus::PixelFormat)pBkgrMaskBitmap->GetPixelFormat()))
{
Gdiplus::BitmapData bitmapData;
Gdiplus::Rect rcBitmap(0, 0, pBkgrMaskBitmap->GetWidth(), pBkgrMaskBitmap->GetHeight());
Gdiplus::Status status = pBkgrMaskBitmap->LockBits(&rcBitmap, Gdiplus::ImageLockModeRead, pBkgrMaskBitmap->GetPixelFormat(), &bitmapData);
if (status == Gdiplus::Ok)
{
#define ALLOC_UNIT 200
DWORD maxRects = ALLOC_UNIT;
HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects));
RGNDATA *pData = (RGNDATA *)GlobalLock(hData);
pData->rdh.dwSize = sizeof(RGNDATAHEADER);
pData->rdh.iType = RDH_RECTANGLES;
pData->rdh.nCount = pData->rdh.nRgnSize = 0;
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
int nBitsPixel = GetPixelFormatSize(pBkgrMaskBitmap->GetPixelFormat()) >> 3;
int nLinesize = pBkgrMaskBitmap->GetWidth() * nBitsPixel;
int nOffset = bitmapData.Stride - bitmapData.Width * nBitsPixel;
PixelData* pPixel = (PixelData*)bitmapData.Scan0;
for (int y = 0; y < bitmapData.Height; y++)
{
for (int x = 0; x < bitmapData.Width; x++)
{
int x0 = x;
while (x < bitmapData.Width)
{
//if (pPixel->R==GetRValue(crAlpha) && pPixel->G == GetGValue(crAlpha) && pPixel->B == GetBValue(crAlpha))
if (pPixel->R != GetRValue(crAlpha) || pPixel->G != GetGValue(crAlpha) || pPixel->B != GetBValue(crAlpha))
//if (pPixel->A == 0)
break;
x++;
pPixel++;
if (!Gdiplus::IsAlphaPixelFormat((Gdiplus::PixelFormat)pBkgrMaskBitmap->GetPixelFormat()))
pPixel -= 1;
}
if (x < bitmapData.Width)
{
pPixel++;
if (!Gdiplus::IsAlphaPixelFormat((Gdiplus::PixelFormat)pBkgrMaskBitmap->GetPixelFormat()))
pPixel -= 1;
}
if (x > x0)
{
if (pData->rdh.nCount >= maxRects)
{
GlobalUnlock(hData);
maxRects += ALLOC_UNIT;
hData = GlobalReAlloc(hData, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), GMEM_MOVEABLE);
pData = (RGNDATA *)GlobalLock(hData);
}
RECT *pRc = (RECT *)&pData->Buffer;
SetRect(&pRc[pData->rdh.nCount], x0, y, x, y + 1);
if (x0 < pData->rdh.rcBound.left)
pData->rdh.rcBound.left = x0;
if (y < pData->rdh.rcBound.top)
pData->rdh.rcBound.top = y;
if (x > pData->rdh.rcBound.right)
pData->rdh.rcBound.right = x;
if (y + 1 > pData->rdh.rcBound.bottom)
pData->rdh.rcBound.bottom = y + 1;
pData->rdh.nCount++;
if (pData->rdh.nCount == 500)
{
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
if (hRgn)
{
CombineRgn(hRgn, hRgn, h, RGN_OR);
DeleteObject(h);
}
else
hRgn = h;
pData->rdh.nCount = 0;
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
}
}
}
pPixel += bitmapData.Stride - (bitmapData.Width * nBitsPixel);
}
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
if (hRgn)
{
CombineRgn(hRgn, hRgn, h, RGN_OR);
DeleteObject(h);
}
else
hRgn = h;
pData->rdh.nCount = 0;
GlobalUnlock(hData);
GlobalFree(hData);
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
pBkgrMaskBitmap->UnlockBits(&bitmapData);
}
}
}
::SetWindowRgn(m_hWnd, hRgn, TRUE);
}