i have my own region class:
class region
{
private:
BYTE* Get24BitPixels(HBITMAP pBitmap, WORD *pwWidth, WORD *pwHeight)
{
// a bitmap object just to get bitmap width and height
BITMAP bmpBmp;
// pointer to original bitmap info
LPBITMAPINFO pbmiInfo;
// bitmap info will hold the new 24bit bitmap info
BITMAPINFO bmiInfo;
// width and height of the bitmap
WORD wBmpWidth, wBmpHeight;
// ---------------------------------------------------------
// get some info from the bitmap
// ---------------------------------------------------------
GetObject(pBitmap, sizeof(bmpBmp),&bmpBmp);
pbmiInfo = (LPBITMAPINFO)&bmpBmp;
// get width and height
wBmpWidth = (WORD)pbmiInfo->bmiHeader.biWidth;
wBmpWidth -= (wBmpWidth%4); // width is 4 byte boundary aligned.
wBmpHeight = (WORD)pbmiInfo->bmiHeader.biHeight;
// copy to caller width and height parms
*pwWidth = wBmpWidth;
*pwHeight = wBmpHeight;
// ---------------------------------------------------------
// allocate width * height * 24bits pixels
//BYTE *pPixels = new BYTE[wBmpWidth*wBmpHeight*3];
BYTE *pPixels = new (std::nothrow) BYTE[wBmpWidth*wBmpHeight*3];
if (pPixels==0)
return NULL;
// get user desktop device context to get pixels from
HDC hDC = GetWindowDC(NULL);
// fill desired structure
bmiInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmiInfo.bmiHeader.biWidth = wBmpWidth;
bmiInfo.bmiHeader.biHeight = -wBmpHeight;
bmiInfo.bmiHeader.biPlanes = 1;
bmiInfo.bmiHeader.biBitCount = 24;
bmiInfo.bmiHeader.biCompression = BI_RGB;
bmiInfo.bmiHeader.biSizeImage = wBmpWidth*wBmpHeight*3;
bmiInfo.bmiHeader.biXPelsPerMeter = 0;
bmiInfo.bmiHeader.biYPelsPerMeter = 0;
bmiInfo.bmiHeader.biClrUsed = 0;
bmiInfo.bmiHeader.biClrImportant = 0;
// get pixels from the original bitmap converted to 24bits
int iRes = GetDIBits(hDC,pBitmap,0,wBmpHeight,(LPVOID)pPixels,&bmiInfo,DIB_RGB_COLORS);
// release the device context
ReleaseDC(NULL,hDC);
// if failed, cancel the operation.
if (!iRes)
{
delete[] pPixels;
return NULL;
};
// return the pixel array
return pPixels;
}
HRGN RegionbyBitmap(HBITMAP pBitmap,COLORREF clrTransparent=-1 )
{
// bitmap width and height
WORD wBmpWidth,wBmpHeight;
// the final region and a temporary region
HRGN hRgn, hTmpRgn;
// 24bit pixels from the bitmap
BYTE *pPixels = Get24BitPixels(pBitmap, &wBmpWidth, &wBmpHeight);
if (!pPixels) return NULL;
// create our working region
hRgn = CreateRectRgn(0,0,wBmpWidth,wBmpHeight);
if (!hRgn)
{
delete[] pPixels;
return NULL;
}
// ---------------------------------------------------------
// scan the bitmap
// ---------------------------------------------------------
if(clrTransparent==-1)
clrTransparent=RGB(pPixels[0 + 2],pPixels[0 + 1],pPixels[0 + 0]);
BYTE jTranspR = GetRValue(clrTransparent), jTranspG=GetGValue(clrTransparent), jTranspB=GetBValue(clrTransparent);
DWORD p = 0;
int xStart = 0;
bool bTransp(false);
hTmpRgn = CreateRectRgn(0, 0, 1, 1);
for (WORD y = 0; y<wBmpHeight; y++)
{
for (WORD x = 0; x<wBmpWidth; x++)
{
BYTE jRed = pPixels[p + 2];
BYTE jGreen = pPixels[p + 1];
BYTE jBlue = pPixels[p + 0];
if(x==0 && y==0)
{
if ((jRed == jTranspR && jGreen == jTranspG && jBlue == jTranspB))
DebugText("pixel zero transparent");
}
if ((jRed == jTranspR && jGreen == jTranspG && jBlue == jTranspB))
{
if (!bTransp)
{
xStart = x;
bTransp = true;
}
}
else
{
if (bTransp)
{
SetRectRgn(hTmpRgn, xStart, y, x, y + 1);
CombineRgn(hRgn, hRgn, hTmpRgn, RGN_XOR);
bTransp = false;
}
}
// next pixel
p += 3;
}
if (bTransp)
{
SetRectRgn(hTmpRgn, xStart, y, wBmpWidth, y + 1);
if(CombineRgn(hRgn, hRgn, hTmpRgn, RGN_XOR)==ERROR)
DebugText("error");
bTransp = false;
}
}
DeleteObject(hTmpRgn);
delete [] pPixels;
return hRgn;
}
HRGN hregion=NULL;
public:
region(HBITMAP hbitmapregion,COLORREF clrbackcolor=-1)
{
hregion=RegionbyBitmap(hbitmapregion,clrbackcolor);
}
~region()
{
DeleteObject(hregion);
}
void frombitmap(HBITMAP hbitmapregion,COLORREF clrbackcolor)
{
hregion=RegionbyBitmap(hbitmapregion, clrbackcolor);
}
void fromrgn(HRGN fromregion)
{
hregion=fromregion;
}
operator HRGN()
{
return hregion;
}
};
and now heres my paint label message:
case WM_CTLCOLOR:
case WM_CTLCOLORBTN:
case WM_CTLCOLORDLG:
case WM_ERASEBKGND:
{
return TRUE;
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(inst->hwnd, &ps);
image imgLabel(inst->intWidth+1,inst->intHeight+1);
SetTextColor(ps.hdc,inst->clrTextColor);
//back color
pen penTransparent;
imgLabel.Pen(penTransparent);
/*if(inst->blnTransparent==true)
{
if(inst->clrTextColor!=RGB(0,0,0))
imgLabel.Brush(RGB(0,0,0));
else
imgLabel.Brush(RGB(50,50,50));
}
else
{
imgLabel.Brush(inst->clrBackColor);
}*/
imgLabel.Brush(inst->clrBackColor);
imgLabel.DrawRectangle(0,0,imgLabel.width()+2,imgLabel.height()+2);
//draw image
if(inst->imgtest!=NULL)
DrawHICONtoHDC( imgLabel, inst->imgtest);
imgLabel.Font(inst->chFont);
imgLabel.DrawText(inst->strCaption.c_str());
//NULL the window region
SetWindowRgn(inst->hwnd,NULL,TRUE);
if(inst->blnTransparent==true)
{
DebugText("transparent");
region lblRegion(imgLabel);
if(SetWindowRgn(inst->hwnd,lblRegion,TRUE)==0)
DebugText("error on creating the shaped control");
//TransparentBlt(ps.hdc,0,0,imgLabel.width(), imgLabel.height(), imgLabel,0,0,imgLabel.width(), imgLabel.height(),GetPixel(ps.hdc,0,0));
BitBlt(ps.hdc,0,0,imgLabel.width(), imgLabel.height(), imgLabel,0,0,SRCCOPY);
}
else
{
BitBlt(ps.hdc,0,0,imgLabel.width(), imgLabel.height(), imgLabel,0,0,SRCCOPY);
}
EndPaint(inst->hwnd, &ps);
return 0;
}
break;
- inst it's label class pointer instance;
- imgLabel is my image class object.
i know that my image can return the HBITMAP without problems(i had tested).
but why the region isn't atached to label? have something to do with window styles flags?