User defiend windows
http://kevincg.wordpress.com/2008/02/14/不規則視窗-part-ii/
// ==================== 建立形狀 =====================
// Step 1: 載入影像
HBITMAP hBmp = (HBITMAP) LoadImage( AfxGetInstanceHandle(), "Rgn.bmp",IMAGE_BITMAP, 0, 0,LR_LOADFROMFILE );
// Step 2:建立一個 Region, 令紅色為透明色 (transparent)
HRGN hRgn = CreateRgnFromFile( hBmp, RGB(255,0,0) );
// Step 3:設定視窗大小與影像大小相同
SetWindowPos( NULL, 0, 0, m_dwWidth, m_dwHeight, SWP_NOZORDER | SWP_NOMOVE );
// Step 4:設定視窗的形狀
SetWindowRgn( hRgn, TRUE );
// ==================== End =====================
HRGN CreateRgnFromFile( HBITMAP hBmp, COLORREF color )
{
// get image properties
BITMAP bmp = { 0 };
GetObject( hBmp, sizeof(BITMAP), &bmp ); // 取出 hBMP 相關的資訊
// allocate memory for extended image information
LPBITMAPINFO bi = (LPBITMAPINFO) new BYTE[ sizeof(BITMAPINFO) + 8 ];
memset( bi, 0, sizeof(BITMAPINFO) + 8 );
bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
// set window size
m_dwWidth = bmp.bmWidth; // bitmap width
m_dwHeight = bmp.bmHeight; // bitmap height
// create temporary dc
HDC dc = CreateDC( "DISPLAY",NULL,NULL,NULL );
// get extended information about image (length, compression, length of color table if exist, ...)
DWORD res = GetDIBits( dc, hBmp, 0, bmp.bmHeight, 0, bi, DIB_RGB_COLORS );
// allocate memory for image data (colors)
LPBYTE pBits = new BYTE[ bi->bmiHeader.biSizeImage + 4 ];
// allocate memory for color table
if ( bi->bmiHeader.biBitCount == 8 )
{
// actually color table should be appended to this header(BITMAPINFO),
// so we have to reallocate and copy it
LPBITMAPINFO old_bi = bi;
// 255 - because there is one in BITMAPINFOHEADER
bi = (LPBITMAPINFO)new char[ sizeof(BITMAPINFO) + 255 * sizeof(RGBQUAD) ];
memcpy( bi, old_bi, sizeof(BITMAPINFO) );
// release old header
delete old_bi;
}
// get bitmap info header
BITMAPINFOHEADER& bih = bi->bmiHeader;
// get color table (for 256 color mode contains 256 entries of RGBQUAD(=DWORD))
LPDWORD clr_tbl = (LPDWORD)&bi->bmiColors;
// fill bits buffer
res = GetDIBits( dc, hBmp, 0, bih.biHeight, pBits, bi, DIB_RGB_COLORS );
DeleteDC( dc );
// shift bits and byte per pixel (for comparing colors)
LPBYTE pClr = (LPBYTE)&color;
// swap red and blue components
BYTE tmp = pClr[0]; pClr[0] = pClr[2]; pClr[2] = tmp;
// convert color if curent DC is 16-bit (5:6:5) or 15-bit (5:5:5)
if ( bih.biBitCount == 16 )
{
color = ((DWORD)(pClr[0] & 0xf8) >> 3) | // 3
((DWORD)(pClr[1] & 0xf8) << rgndataheader_size =" sizeof(RGNDATAHEADER);" add_rects_count =" 40;" bpp =" bih.biBitCount">> 3; // bytes per pixel
// DIB image is flipped that's why we scan it from the last line
LPBYTE pColor = pBits + (bih.biHeight - 1) * (bih.biWidth * Bpp);
DWORD dwLineBackLen = 2 * bih.biWidth * Bpp; // offset of previous scan line
// (after processing of current)
DWORD dwRectsCount = bih.biHeight; // number of rects in allocated buffer
INT i, j; // current position in mask image
INT first = 0; // left position of current scan line
// where mask was found
bool wasfirst = false; // set when mask has been found in current scan line
bool ismask; // set when current color is mask color
// allocate memory for region data
// region data here is set of regions that are rectangles with height 1 pixel (scan line)
// that's why first allocation is RECTs - number of scan lines in image
RGNDATAHEADER* pRgnData =
(RGNDATAHEADER*)new BYTE[ RGNDATAHEADER_SIZE + dwRectsCount * sizeof(RECT) ];
// get pointer to RECT table
LPRECT pRects = (LPRECT)((LPBYTE)pRgnData + RGNDATAHEADER_SIZE);
// zero region data header memory (header part only)
memset( pRgnData, 0, RGNDATAHEADER_SIZE + dwRectsCount * sizeof(RECT) );
// fill it by default
pRgnData->dwSize = RGNDATAHEADER_SIZE;
pRgnData->iType = RDH_RECTANGLES;
for ( i = 0; i < j =" 0;" ismask =" (clr_tbl[" ismask =" (*(LPWORD)pColor" ismask =" ((*(LPDWORD)pColor" ismask =" (*(LPDWORD)pColor">nCount++ ] = CRect( first, i, j, i + 1 );
// if buffer full reallocate it with more room
if ( pRgnData->nCount >= dwRectsCount )
{
dwRectsCount += ADD_RECTS_COUNT;
// allocate new buffer
LPBYTE pRgnDataNew = new BYTE[ RGNDATAHEADER_SIZE + dwRectsCount * sizeof(RECT) ];
// copy current region data to it
memcpy( pRgnDataNew, pRgnData, RGNDATAHEADER_SIZE + pRgnData- >nCount * sizeof(RECT) );
// delte old region data buffer
delete pRgnData;
// set pointer to new regiondata buffer to current
pRgnData = (RGNDATAHEADER*)pRgnDataNew;
// correct pointer to RECT table
pRects = (LPRECT)((LPBYTE)pRgnData + RGNDATAHEADER_SIZE);
}
wasfirst = false;
}
else if ( !wasfirst && ismask ) // set wasfirst when mask is found
{
first = j;
wasfirst = true;
}
}
pColor -= dwLineBackLen;
}
// release image data
delete pBits;
delete bi;
// create region
HRGN hRgn = ExtCreateRegion( NULL, RGNDATAHEADER_SIZE + pRgnData->nCount * sizeof(RECT), (LPRGNDATA)pRgnData );
// release region data
delete pRgnData;
return hRgn;
}
(from : http://kghost-tips.blogspot.com/2008/08/step-1-hbitmap-hbmp-hbitmap-loadimage.html)
留言列表