CreateRegionFromBmp

来源:互联网 发布:电脑软件开发 编辑:程序博客网 时间:2024/06/08 14:31
CDib m_dib ;
CRgn m_rgn ;
COLORREF m_dwColorKey = 0x0000ff; // 透明色, 纯蓝


BOOL CreateRegionFromBmp(LPCSTR lpsFName)
{
// 读入位图 
if( !m_dib.Open( lpsFName ) )
return FALSE ;

SIZE dibsize ;

// 获取位图尺寸
dibsize = m_dib.GetSize( ) ;

int i , j ;
BOOL bkey ;
int iCount = 0 ;




// 统计需要的矩形个数
for( i = 0 ; i < dibsize.cy ; i++)
{
bkey = TRUE ;
for( j = 0 ; j < dibsize.cx ; j ++)
{
if( m_dib.GetPixel( j , i ) == m_dwColorKey )
{
bkey = TRUE ;
}
else
{
if( bkey )
{
iCount ++;
}
bkey = FALSE ;
}
}
}
BYTE* pData ;
RGNDATA* pRgnData ;
RECT* pRect ;
int iIndex = 0 ;

pData = new BYTE[sizeof(RGNDATAHEADER) +sizeof(RECT)*iCount] ;
pRgnData = (RGNDATA *)pData ;
pRect = (RECT*)( pData +sizeof( RGNDATAHEADER));
pRgnData->rdh.dwSize =sizeo(RGNDATAHEADER ) ;
pRgnData->rdh.iType   =RDH_RECTANGLES ;
pRgnData->rdh.nCount  = iCount ;
pRgnData->rdh.nRgnSize = sizeof( RECT ) *iCount ;
pRgnData->rdh.rcBound.left     = 0 ;
pRgnData->rdh.rcBound.top     = 0 ;
pRgnData->rdh.rcBound.right    =dibsize.cx ;
pRgnData->rdh.rcBound.bottom = dibsize.cy ;


int iLeft = 0 ;
for( i = dibsize.cy -1 ; i >= 0 ; i --)
// 因为Bitmap 位图在Y 方向是颠倒的所以要从底部开始
{
bkey = TRUE ;
iLeft = -1 ;
for( j = 0 ; j < dibsize.cx ; j ++)
{
if( m_dib.GetPixel( j , i ) == m_dwColorKey )
{
if( !bkey )
{
pRect[ iIndex ].left = iLeft ;
pRect[ iIndex ].right = j ;
pRect[ iIndex ].top = dibsize.cy -i -1 ;
pRect[iIndex].bottom = dibsize.cy -i;
bkey = TRUE ;
iIndex ++;
iLeft = -1 ;
}
}
else
{
if( bkey )
{
iLeft = j ;
bkey = FALSE ;
}
}
}




if( iLeft >= 0 )
{
pRect[ iIndex ].left = iLeft ;
pRect[ iIndex ].right = dibsize.cx ;
pRect[ iIndex ].top = i ;
pRect[ iIndex ].bottom = i ;
iIndex ++;
}
}
BOOL br = m_rgn.CreateFromData
( NULL , sizeof( RGNDATAHEADER ) +sizeof
( RECT ) *iCount , pRgnData ) ;
return br ;
}
有了这个方法, 任意形状的窗口都可以被创建, 只要先画出想要的形状位图即可。



这里还要谈到一个问题, 任意形状的窗口没有标题栏, 那么用户如何拖动窗口呢? 其实只要在响应左键点击消息时调用SendMessage( WM_SYSCOMMAND , SC_MOVE | HTCLIENT , 0 ) 即可。
原创粉丝点击