根据位图创建区域Rgn--VC

界面编程

// 根据位图文件 创建 区域

 


HRGN BitmapToRegion (HBITMAP hBmp, COLORREF cTransparentColor 
=    0 , COLORREF cTolerance  =   0x101010 )
{
    HRGN hRgn 
= NULL;

    
if (hBmp)
    
{
        
// Create a memory DC inside which we will scan the bitmap content
        HDC hMemDC = CreateCompatibleDC(NULL);
        
if (hMemDC)
        
{
            
// Get bitmap size
            BITMAP bm;
            GetObject(hBmp, 
sizeof(bm), &bm);

            
// Create a 32 bits depth bitmap and select it into the memory DC 
            BITMAPINFOHEADER RGB32BITSBITMAPINFO = {    
                    
sizeof(BITMAPINFOHEADER),    // biSize 
                    bm.bmWidth,                    // biWidth; 
                    bm.bmHeight,                // biHeight; 
                    1,                            // biPlanes; 
                    32,                            // biBitCount 
                    BI_RGB,                        // biCompression; 
                    0,                            // biSizeImage; 
                    0,                            // biXPelsPerMeter; 
                    0,                            // biYPelsPerMeter; 
                    0,                            // biClrUsed; 
                    0                            // biClrImportant; 
            }
;
            VOID 
* pbits32; 
            HBITMAP hbm32 
= CreateDIBSection(hMemDC, (BITMAPINFO *)&RGB32BITSBITMAPINFO, DIB_RGB_COLORS, &pbits32, NULL, 0);
            
if (hbm32)
            
{
                HBITMAP holdBmp 
= (HBITMAP)SelectObject(hMemDC, hbm32);

                
// Create a DC just to copy the bitmap into the memory DC
                HDC hDC = CreateCompatibleDC(hMemDC);
                
if (hDC)
                
{
                    
// Get how many bytes per row we have for the bitmap bits (rounded up to 32 bits)
                    BITMAP bm32;
                    GetObject(hbm32, 
sizeof(bm32), &bm32);
                    
while (bm32.bmWidthBytes % 4)
                        bm32.bmWidthBytes
++;

                    
// Copy the bitmap into the memory DC
                    HBITMAP holdBmp = (HBITMAP)SelectObject(hDC, hBmp);
                    BitBlt(hMemDC, 
00, bm.bmWidth, bm.bmHeight, hDC, 00, SRCCOPY);

                    
// For better performances, we will use the ExtCreateRegion() function to create the
                    
// region. This function take a RGNDATA structure on entry. We will add rectangles by
                    
// amount of ALLOC_UNIT number in this structure.
                    #define ALLOC_UNIT    100
                    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, 00);

                    
// Keep on hand highest and lowest values for the "transparent" pixels
                    BYTE lr = GetRValue(cTransparentColor);
                    BYTE lg 
= GetGValue(cTransparentColor);
                    BYTE lb 
= GetBValue(cTransparentColor);
                    BYTE hr 
= min(0xff, lr + GetRValue(cTolerance));
                    BYTE hg 
= min(0xff, lg + GetGValue(cTolerance));
                    BYTE hb 
= min(0xff, lb + GetBValue(cTolerance));

                    
// Scan each bitmap row from bottom to top (the bitmap is inverted vertically)
                    BYTE *p32 = (BYTE *)bm32.bmBits + (bm32.bmHeight - 1* bm32.bmWidthBytes;
                    
for (int y = 0; y < bm.bmHeight; y++)
                    
{
                        
// Scan each bitmap pixel from left to right
                        for (int x = 0; x < bm.bmWidth; x++)
                        
{
                            
// Search for a continuous range of "non transparent pixels"
                            int x0 = x;
                            LONG 
*= (LONG *)p32 + x;
                            
while (x < bm.bmWidth)
                            
{
                                BYTE b 
= GetRValue(*p);
                                
if (b >= lr && b <= hr)
                                
{
                                    b 
= GetGValue(*p);
                                    
if (b >= lg && b <= hg)
                                    
{
                                        b 
= GetBValue(*p);
                                        
if (b >= lb && b <= hb)
                                            
// This pixel is "transparent"
                                            break;
                                    }

                                }

                                p
++;
                                x
++;
                            }


                            
if (x > x0)
                            
{
                                
// Add the pixels (x0, y) to (x, y+1) as a new rectangle in the region
                                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 
*pr = (RECT *)&pData->Buffer;
                                SetRect(
&pr[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++;

                                
// On Windows98, ExtCreateRegion() may fail if the number of rectangles is too
                                
// large (ie: > 4000). Therefore, we have to create the region by multiple steps.
                                if (pData->rdh.nCount == 2000)
                                
{
                                    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, 00);
                                }

                            }

                        }


                        
// Go to next row (remember, the bitmap is inverted vertically)
                        p32 -= bm32.bmWidthBytes;
                    }


                    
// Create or extend the region with the remaining rectangles
                    HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
                    
if (hRgn)
                    
{
                        CombineRgn(hRgn, hRgn, h, RGN_OR);
                        DeleteObject(h);
                    }

                    
else
                        hRgn 
= h;

                    
// Clean up
                    GlobalFree(hData);
                    SelectObject(hDC, holdBmp);
                    DeleteDC(hDC);
                }


                DeleteObject(SelectObject(hMemDC, holdBmp));
            }


            DeleteDC(hMemDC);
        }
    
    }


    
return hRgn;
}

   使用方法:
  CBitmap  m_bmpMask;
  //  IDB_BITMAP_MASK  应该是一张纯黑色的图片. 
  m_bmpMask.LoadBitmap(  IDB_BITMAP_MASK ) ;     
 
  //  根据位图创建 HRGN
  HRGN hRgn = BitmapToRegion ( m_bmMusicListMask, RGB( 255 , 255 , 255 ) );
 
  SetWindowRgn( hWnd /*窗口句柄*/,  hRgn , TRUE);
 
  // 必须要删除 HRGN 对象
  DeleteObject( hRgn );
 


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Blue_Dream_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值