CreateRegionFromBmp

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 ) 即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值