⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 skinwindow.cpp

📁 著名的下载软件核心Shareaza
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	}
	
	if ( m_bPart[ SKINPART_RIGHT_TOP ] && ! bCaption )
	{
		dc.BitBlt( rcRight.right - m_rcPart[ SKINPART_RIGHT_TOP ].Width(),
			rcRight.top, m_rcPart[ SKINPART_RIGHT_TOP ].Width(),
			m_rcPart[ SKINPART_RIGHT_TOP ].Height(), &m_dcSkin,
			m_rcPart[ SKINPART_RIGHT_TOP ].left,
			m_rcPart[ SKINPART_RIGHT_TOP ].top, SRCCOPY );
		rcRight.top += m_rcPart[ SKINPART_RIGHT_TOP ].Height();
	}
	
	if ( m_bPart[ SKINPART_RIGHT_BOTTOM ] && ! bCaption )
	{
		dc.BitBlt( rcRight.right - m_rcPart[ SKINPART_RIGHT_BOTTOM ].Width(),
			rcRight.bottom - m_rcPart[ SKINPART_RIGHT_BOTTOM ].Height(),
			m_rcPart[ SKINPART_RIGHT_BOTTOM ].Width(),
			m_rcPart[ SKINPART_RIGHT_BOTTOM ].Height(), &m_dcSkin,
			m_rcPart[ SKINPART_RIGHT_BOTTOM ].left,
			m_rcPart[ SKINPART_RIGHT_BOTTOM ].top, SRCCOPY );
		rcRight.bottom -= m_rcPart[ SKINPART_RIGHT_BOTTOM ].Height();
	}
	
	if ( m_bPart[ SKINPART_LEFT ] && rcLeft.top < rcLeft.bottom && ! bCaption )
	{
		CRect* pRect = &m_rcPart[ SKINPART_LEFT ];
		
		if ( m_nPart[ SKINPART_LEFT ] == SKINPARTMODE_STRETCH )
		{
			dc.SetStretchBltMode( STRETCH_DELETESCANS );
			dc.StretchBlt( 0, rcLeft.top, pRect->Width(), rcLeft.Height(),
				&m_dcSkin, pRect->left, pRect->top,
				pRect->Width(), pRect->Height(), SRCCOPY );
		}
		else
		{
			for ( int nY = rcLeft.top ; nY < rcLeft.bottom ; nY += pRect->Height() )
			{
				dc.BitBlt( 0, nY, pRect->Width(), min( pRect->Height(), rcLeft.bottom - nY ),
					&m_dcSkin, pRect->left, pRect->top, SRCCOPY );
			}
		}
	}
	
	if ( bActive == TS_FALSE && m_bPart[ SKINPART_IA_TOP ] && rcTop.left < rcTop.right )
	{
		CRect* pRect = &m_rcPart[ SKINPART_IA_TOP ];
		
		if ( m_nPart[ SKINPART_IA_TOP ] == SKINPARTMODE_STRETCH )
		{
			pDC->SetStretchBltMode( STRETCH_DELETESCANS );
			pDC->StretchBlt( rcTop.left, 0, rcTop.Width(), pRect->Height(),
				&m_dcSkin, pRect->left, pRect->top,
				pRect->Width(), pRect->Height(), SRCCOPY );
		}
		else
		{
			for ( int nX = rcTop.left ; nX < rcTop.right ; nX += pRect->Width() )
			{
				pDC->BitBlt( nX, 0, min( pRect->Width(), rcTop.right - nX ),
					pRect->Height(), &m_dcSkin, pRect->left, pRect->top, SRCCOPY );
			}
		}
	}
	else if ( m_bPart[ SKINPART_TOP ] && rcTop.left < rcTop.right )
	{
		CRect* pRect = &m_rcPart[ SKINPART_TOP ];

		if ( m_nPart[ SKINPART_TOP ] == SKINPARTMODE_STRETCH )
		{
			pDC->SetStretchBltMode( STRETCH_DELETESCANS );
			pDC->StretchBlt( rcTop.left, 0, rcTop.Width(), pRect->Height(),
				&m_dcSkin, pRect->left, pRect->top,
				pRect->Width(), pRect->Height(), SRCCOPY );
		}
		else
		{
			for ( int nX = rcTop.left ; nX < rcTop.right ; nX += pRect->Width() )
			{
				pDC->BitBlt( nX, 0, min( pRect->Width(), rcTop.right - nX ),
					pRect->Height(), &m_dcSkin, pRect->left, pRect->top, SRCCOPY );
			}
		}
	}
	
	if ( m_bPart[ SKINPART_RIGHT ] && rcRight.top < rcRight.bottom && ! bCaption )
	{
		CRect* pRect = &m_rcPart[ SKINPART_RIGHT ];
		
		if ( m_nPart[ SKINPART_RIGHT ] == SKINPARTMODE_STRETCH )
		{
			dc.SetStretchBltMode( STRETCH_DELETESCANS );
			dc.StretchBlt( rc.right - pRect->Width(), rcRight.top, pRect->Width(),
				rcRight.Height(), &m_dcSkin, pRect->left, pRect->top,
				pRect->Width(), pRect->Height(), SRCCOPY );
		}
		else
		{
			for ( int nY = rcRight.top ; nY < rcRight.bottom ; nY += pRect->Height() )
			{
				dc.BitBlt( rc.right - pRect->Width(), nY, pRect->Width(),
					min( pRect->Height(), rcRight.bottom - nY ),
					&m_dcSkin, 	pRect->left, pRect->top, SRCCOPY );
			}
		}
	}
	
	if ( m_bPart[ SKINPART_BOTTOM ] && rcTop.left < rcTop.right && ! bCaption )
	{
		CRect* pRect = &m_rcPart[ SKINPART_BOTTOM ];
		
		if ( m_nPart[ SKINPART_TOP ] == SKINPARTMODE_STRETCH )
		{
			dc.SetStretchBltMode( STRETCH_DELETESCANS );
			dc.StretchBlt( rcBottom.left, rc.bottom - pRect->Height(),
				rcBottom.Width(), pRect->Height(),
				&m_dcSkin, pRect->left, pRect->top,
				pRect->Width(), pRect->Height(), SRCCOPY );
		}
		else
		{
			for ( int nX = rcBottom.left ; nX < rcBottom.right ; nX += pRect->Width() )
			{
				dc.BitBlt( nX, rc.bottom - pRect->Height(),
					min( pRect->Width(), rcBottom.right - nX ), pRect->Height(),
					&m_dcSkin, pRect->left, pRect->top, SRCCOPY );
			}
		}
	}
	
	if ( hIcon != NULL )
	{
		ResolveAnchor( rc, rcItem, SKINANCHOR_ICON );
		DrawIconEx( pDC->GetSafeHdc(), rcItem.left, rcItem.top, hIcon, 16, 16, 0, NULL, DI_NORMAL );
	}
	
	if ( m_bCaption && strCaption.GetLength() )
	{
		CFont* pOldFont	= (CFont*)pDC->SelectObject( &m_fnCaption );
		CSize sz		= pDC->GetTextExtent( strCaption );
		CPoint ptCap;
		
		rcItem.left		= m_rcCaption.left + ( m_rcCaption.left >= 0 ? rc.left : rc.right );
		rcItem.right	= m_rcCaption.Width() + ( m_rcCaption.Width() >= 0 ? rc.left : rc.right );
		rcItem.top		= rc.top + m_rcCaption.top;
		rcItem.bottom	= rc.top + m_rcCaption.bottom;
		
		switch ( m_nCaptionAlign )
		{
		case 0:
			ptCap.x = rcItem.left + 1;
			break;
		case 1:
			ptCap.x = ( rcItem.left + rcItem.right ) / 2 - sz.cx / 2;
			ptCap.x = max( ptCap.x, rcItem.left + 1 );
			break;
		case 2:
			ptCap.x = rcItem.right - sz.cx - 1;
			ptCap.x = max( ptCap.x, rcItem.left + 1 );
			break;
		}
		
		ptCap.y = ( rcItem.top + rcItem.bottom ) / 2 - sz.cy / 2;
		
		pDC->SetBkMode( TRANSPARENT );
		
		if ( m_crCaptionShadow != CLR_NONE )
		{
			pDC->SetTextColor( m_crCaptionShadow );
			pDC->ExtTextOut( ptCap.x + 1, ptCap.y + 1, ETO_CLIPPED, &rcItem, strCaption, NULL );
		}
		else if ( m_crCaptionOutline != CLR_NONE )
		{
			pDC->SetTextColor( m_crCaptionOutline );
			pDC->ExtTextOut( ptCap.x - 1, ptCap.y - 1, ETO_CLIPPED, &rcItem, strCaption, NULL );
			pDC->ExtTextOut( ptCap.x, ptCap.y - 1, ETO_CLIPPED, &rcItem, strCaption, NULL );
			pDC->ExtTextOut( ptCap.x + 1, ptCap.y - 1, ETO_CLIPPED, &rcItem, strCaption, NULL );
			pDC->ExtTextOut( ptCap.x - 1, ptCap.y, ETO_CLIPPED, &rcItem, strCaption, NULL );
			pDC->ExtTextOut( ptCap.x + 1, ptCap.y, ETO_CLIPPED, &rcItem, strCaption, NULL );
			pDC->ExtTextOut( ptCap.x - 1, ptCap.y + 1, ETO_CLIPPED, &rcItem, strCaption, NULL );
			pDC->ExtTextOut( ptCap.x, ptCap.y + 1, ETO_CLIPPED, &rcItem, strCaption, NULL );
			pDC->ExtTextOut( ptCap.x + 1, ptCap.y + 1, ETO_CLIPPED, &rcItem, strCaption, NULL );
		}
		
		pDC->SetTextColor( bActive == TS_TRUE ? m_crCaptionText : m_crCaptionInactive );
		pDC->ExtTextOut( ptCap.x, ptCap.y, ETO_CLIPPED, &rcItem, strCaption, NULL );
		pDC->SelectObject( pOldFont );
	}
	
	dc.BitBlt( 0, 0, rc.Width(), nCaptionHeight, pDC, 0, 0, SRCCOPY );
	pDC->SelectClipRgn( NULL );
	
	dc.SetTextColor( 0 );
}

//////////////////////////////////////////////////////////////////////
// CSkinWindow part and anchor access

BOOL CSkinWindow::GetPart(LPCTSTR pszName, CRect& rcPart)
{
	CRect* pRect;
	if ( ! m_pPartList.Lookup( pszName, (void*&)pRect ) ) return FALSE;
	rcPart = *pRect;
	return TRUE;
}

BOOL CSkinWindow::GetAnchor(LPCTSTR pszName, CRect& rcAnchor)
{
	CRect* pRect;
	if ( ! m_pAnchorList.Lookup( pszName, (void*&)pRect ) ) return FALSE;
	rcAnchor = *pRect;
	return TRUE;
}

BOOL CSkinWindow::GetAnchor(LPCTSTR pszName, const CRect& rcClient, CRect& rcAnchor)
{
	CRect* pRect;
	if ( ! m_pAnchorList.Lookup( pszName, (void*&)pRect ) ) return FALSE;
	rcAnchor = *pRect;
	rcAnchor.OffsetRect( rcAnchor.left < 0 ? rcClient.right : rcClient.left, 0 );
	rcAnchor.OffsetRect( 0, rcAnchor.top < 0 ? rcClient.bottom : rcClient.top );
	return TRUE;
}

BOOL CSkinWindow::PaintPartOnAnchor(CDC* pDC, const CRect& rcClient, LPCTSTR pszPart, LPCTSTR pszAnchor)
{
	CRect rcPart, rcAnchor;
	
	if ( ! GetPart( pszPart, rcPart ) ) return FALSE;
	if ( ! GetAnchor( pszAnchor, rcClient, rcAnchor ) ) return FALSE;
	if ( m_dcSkin.m_hDC == NULL ) Prepare( pDC );
	
	pDC->BitBlt( rcAnchor.left, rcAnchor.top, rcPart.Width(), rcPart.Height(),
		&m_dcSkin, rcPart.left, rcPart.top, SRCCOPY );
	pDC->ExcludeClipRect( &rcAnchor );
	
	return TRUE;
}

void CSkinWindow::ResolveAnchor(const CRect& rcClient, CRect& rcAnchor, int nAnchor)
{
	rcAnchor = m_rcAnchor[ nAnchor ];
	rcAnchor.OffsetRect( rcAnchor.left < 0 ? rcClient.right : rcClient.left, 0 );
	rcAnchor.OffsetRect( 0, rcAnchor.top < 0 ? rcClient.bottom : rcClient.top );
}

//////////////////////////////////////////////////////////////////////
// CSkinWindow region builder

void CSkinWindow::SelectRegion(CWnd* pWnd)
{
	CRect rcWnd, rcPart;
	HRGN hRgn = NULL;

	pWnd->GetWindowRect( &rcWnd );
	rcWnd.OffsetRect( -rcWnd.left, -rcWnd.top );
	rcWnd.right++; rcWnd.bottom++;

	for ( POSITION pos = m_pRegionXML->GetElementIterator() ; pos ; )
	{
		CXMLElement* pXML = m_pRegionXML->GetNextElement( pos );
		if ( ! pXML->IsNamed( _T("shape") ) ) continue;

		if ( ParseRect( pXML, &rcPart ) )
		{
			rcPart.right	-= rcPart.left;
			rcPart.bottom	-= rcPart.top;
			rcPart.left		+= rcPart.left >= 0 ? rcWnd.left : rcWnd.right + 1;
			rcPart.top		+= rcPart.top >= 0 ? rcWnd.top : rcWnd.bottom + 1;
			rcPart.right	+= rcPart.right >= 0 ? rcWnd.left : rcWnd.right + 1;
			rcPart.bottom	+= rcPart.bottom >= 0 ? rcWnd.top : rcWnd.bottom + 1;
		}
		else
		{
			rcPart.CopyRect( &rcWnd );
		}
		
		CString strType = pXML->GetAttributeValue( _T("type") );
		HRGN hPart = NULL;

		if ( strType.CompareNoCase( _T("rectangle") ) == 0 )
		{
			hPart = CreateRectRgnIndirect( &rcPart );
		}
		else if ( strType.CompareNoCase( _T("ellipse") ) == 0 )
		{
			hPart = CreateEllipticRgnIndirect( &rcPart );
		}
		else if ( strType.CompareNoCase( _T("roundRect") ) == 0 )
		{
			int nWidth, nHeight;
			_stscanf( pXML->GetAttributeValue( _T("size") ), _T("%i,%i"), &nWidth, &nHeight );
			hPart = CreateRoundRectRgn( rcPart.left, rcPart.top, rcPart.right, rcPart.bottom,
				nWidth, nHeight );
		}
		else
		{
			continue;
		}

		if ( hPart == NULL )
		{
			if ( hRgn ) DeleteObject( hRgn );
			pWnd->SetWindowRgn( NULL, TRUE );
			return;
		}

		if ( hRgn )
		{
			strType = pXML->GetAttributeValue( _T("combine") );

			if ( strType.CompareNoCase( _T("and") ) == 0 )
			{
				CombineRgn( hRgn, hPart, hRgn, RGN_AND );
			}
			else if ( strType.CompareNoCase( _T("copy") ) == 0 )
			{
				CombineRgn( hRgn, hPart, hRgn, RGN_COPY );
			}
			else if ( strType.CompareNoCase( _T("diff") ) == 0 )
			{
				CombineRgn( hRgn, hRgn, hPart, RGN_DIFF );
			}
			else if ( strType.CompareNoCase( _T("or") ) == 0 )
			{
				CombineRgn( hRgn, hPart, hRgn, RGN_OR );
			}
			else if ( strType.CompareNoCase( _T("xor") ) == 0 )
			{
				CombineRgn( hRgn, hPart, hRgn, RGN_XOR );
			}

			DeleteObject( hPart );
		}
		else
		{
			hRgn = hPart;
		}
	}

	if ( hRgn ) pWnd->SetWindowRgn( hRgn, TRUE );
}

CSize CSkinWindow::GetRegionSize()
{
	if ( ! m_pRegionXML ) return CSize( 0, 0 );

	CRect rcTotal( 0, 0, 0, 0 );

	for ( POSITION pos = m_pRegionXML->GetElementIterator() ; pos ; )
	{
		CXMLElement* pXML = m_pRegionXML->GetNextElement( pos );
		CRect rcPart;

		if ( pXML->IsNamed( _T("shape") ) && ParseRect( pXML, &rcPart ) )
		{
			rcTotal.UnionRect( &rcTotal, &rcPart );
		}
	}

	return rcTotal.Size();
}

//////////////////////////////////////////////////////////////////////
// CSkinWindow pre-blend

BOOL CSkinWindow::PreBlend(CBitmap* pbmTarget, const CRect& rcTarget, const CRect& rcSource)
{
	BITMAPINFO pTargeInfo, pImageInfo, pAlphaInfo;
	
	ZeroMemory( &pTargeInfo, sizeof(pTargeInfo) );
	ZeroMemory( &pImageInfo, sizeof(pImageInfo) );
	ZeroMemory( &pAlphaInfo, sizeof(pAlphaInfo) );
	
	pTargeInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	pImageInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	pAlphaInfo.bmiHeader.biSize	= sizeof(BITMAPINFOHEADER);
	
	HDC hDC = ::GetDC( 0 );
	
	if ( 0 == GetDIBits( hDC, m_bmSkin, 0, 0, NULL, &pImageInfo, DIB_RGB_COLORS ) ||
		 0 == GetDIBits( hDC, *pbmTarget, 0, 0, NULL, &pTargeInfo, DIB_RGB_COLORS ) )
	{
		::ReleaseDC( 0, hDC );
		return FALSE;
	}
	
	BOOL bAlpha = ( 0 != GetDIBits( hDC, m_bmAlpha, 0, 0, NULL, &pAlphaInfo, DIB_RGB_COLORS ) );
	if ( ! bAlpha ) CopyMemory( &pAlphaInfo, &pImageInfo, sizeof(pAlphaInfo) );
	
	int nTargePitch = ( ( pTargeInfo.bmiHeader.biWidth * 3 ) + 3 ) & ~3;
	int nImagePitch = ( ( pImageInfo.bmiHeader.biWidth * 3 ) + 3 ) & ~3;
	int nAlphaPitch = ( ( pAlphaInfo.bmiHeader.biWidth * 3 ) + 3 ) & ~3;
	
	pTargeInfo.bmiHeader.biHeight		= -abs( pTargeInfo.bmiHeader.biHeight );
	pTargeInfo.bmiHeader.biBitCount		= 24;
	pTargeInfo.bmiHeader.biCompression	= BI_RGB;
	pTargeInfo.bmiHeader.biSizeImage	= -pTargeInfo.bmiHeader.biHeight * nTargePitch;
	pImageInfo.bmiHeader.biHeight		= -abs( pImageInfo.bmiHeader.biHeight );
	pImageInfo.bmiHeader.biBitCount		= 24;
	pImageInfo.bmiHeader.biCompression	= BI_RGB;
	pImageInfo.bmiHeader.biSizeImage	= -pImageInfo.bmiHeader.biHeight * nImagePitch;
	pAlphaInfo.bmiHeader.biHeight		= -abs( pAlphaInfo.bmiHeader.biHeight );
	pAlphaInfo.bmiHeader.biBitCount		= 24;
	pAlphaInfo.bmiHeader.biCompression	= BI_RGB;
	pAlphaInfo.bmiHeader.biSizeImage	= -pAlphaInfo.bmiHeader.biHeight * nAlphaPitch;
	
	BYTE* pTargeData = new BYTE[ pTargeInfo.bmiHeader.biSizeImage ];
	BYTE* pImageData = new BYTE[ pImageInfo.bmiHeader.biSizeImage ];
	BYTE* pAlphaData = bAlpha ? new BYTE[ pAlphaInfo.bmiHeader.biSizeImage ] : NULL;
	
	GetDIBits( hDC, *pbmTarget, 0, -pTargeInfo.bmiHeader.biHeight, pTargeData, &pTargeInfo, DIB_RGB_COLORS );
	GetDIBits( hDC, m_bmSkin, 0, -pImageInfo.bmiHeader.biHeight, pImageData, &pImageInfo, DIB_RGB_COLORS );
	if ( bAlpha ) GetDIBits( hDC, m_bmAlpha, 0, -pAlphaInfo.bmiHeader.biHeight, pAlphaData, &pAlphaInfo, DIB_RGB_COLORS );
	
	int nSrcY = rcSource.top, nSrcLeft = rcSource.left * 3;
	int nDstY = rcTarget.top, nDstLeft = rcTarget.left * 3;
	
	int nWidth = min( rcSource.Width(), rcTarget.Width() );
	nWidth = min( nWidth, pTargeInfo.bmiHeader.biWidth - rcTarget.left );
	nWidth = min( nWidth, pImageInfo.bmiHeader.biWidth - rcSource.left );
	nWidth = min( nWidth, pAlphaInfo.bmiHeader.biWidth - rcSource.left );
	
	for ( int nY = min( rcTarget.Height(), rcSource.Height() ) ; nY ; nY--, nSrcY++, nDstY++ )
	{
		BYTE* pTargePtr = pTargeData + nDstY * nTargePitch + nDstLeft;
		BYTE* pImagePtr = pImageData + nSrcY * nImagePitch + nSrcLeft;
		BYTE* pAlphaPtr = pAlphaData + nSrcY * nAlphaPitch + nSrcLeft;
		
		if ( nDstY < 0 || nDstY >= -pTargeInfo.bmiHeader.biHeight )
		{
			// Out of bounds on destination
		}
		else if ( nSrcY < 0 || nSrcY >= -pImageInfo.bmiHeader.biHeight )
		{
			// Out of bounds on source
		}
		else if ( bAlpha && nSrcY < -pAlphaInfo.bmiHeader.biHeight )
		{
			for ( int nX = nWidth ; nX ; nX-- )
			{
				register BYTE nAlpha = *pAlphaPtr; pAlphaPtr += 3;
				*pTargePtr = (BYTE)( ( (DWORD)(*pTargePtr) * ( 255 - nAlpha ) + (*pImagePtr) * nAlpha ) / 255 );
				pTargePtr++; pImagePtr++;
				*pTargePtr = (BYTE)( ( (DWORD)(*pTargePtr) * ( 255 - nAlpha ) + (*pImagePtr) * nAlpha ) / 255 );
				pTargePtr++; pImagePtr++;
				*pTargePtr = (BYTE)( ( (DWORD)(*pTargePtr) * ( 255 - nAlpha ) + (*pImagePtr) * nAlpha ) / 255 );
				pTargePtr++; pImagePtr++;
			}
		}
		else
		{
			CopyMemory( pTargePtr, pImagePtr, nWidth * 3 );
		}
	}
	
	SetDIBits( hDC, *pbmTarget, 0, -pTargeInfo.bmiHeader.biHeight, pTargeData,
		&pTargeInfo, DIB_RGB_COLORS );
	
	if ( bAlpha ) delete [] pAlphaData;
	delete [] pImageData;
	delete [] pTargeData;
	
	::ReleaseDC( 0, hDC );
	
	return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -