创 建 任 意 形 状 的 窗 口
转载请注明来源:https://www.cnblogs.com/hookjc/
圆 号 形 状 的 窗 口。
—-创 建 这 样 的 一 个 区 域 是 调 用 SDK 的 ExtCreateRegion 来 实 现( MFC 中 的 对 应 函 数 为CRgn::CreateFromData)。 这 个 函 数 是 通 过 提 供 一 个 矩 形 数 组, 来 创 建 一 个 由 这 些 矩 形 组 成 的 区 域。 而 创 建 圆 号 区 域 的 过 程 就 是 由 一 个 圆 号 的 位 图 生 成 矩 形 数 组, 再 由 这 个 矩 形 数 组 生 成 区 域 的 过 程。
—-下 面 是 由 圆 号 位 图 创 建 区 域 的 函 数 代 码。
CDib m_dib ;
CRgn m_rgn ;
COLORREF m_dwColorKey = 0x0000ff; // 透 明 色, 纯 蓝
BOOL CAswDlg::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 ) 即 可。
http://blog.donews.com/darkhawk/archive/2004/08/06/61637.aspx