📄 skinwindow.cpp
字号:
//
// SkinWindow.cpp
//
// Copyright (c) Shareaza Development Team, 2002-2004.
// This file is part of SHAREAZA (www.shareaza.com)
//
// Shareaza is free software; you can redistribute it
// and/or modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Shareaza is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Shareaza; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
#include "StdAfx.h"
#include "Shareaza.h"
#include "Settings.h"
#include "CoolInterface.h"
#include "SkinWindow.h"
#include "XML.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define BORDER_WIDTH GetSystemMetrics( SM_CXSIZEFRAME )
#define SIZEBOX_WIDTH GetSystemMetrics( SM_CXSIZE )
//////////////////////////////////////////////////////////////////////
// CSkinWindow construction
CSkinWindow::CSkinWindow()
{
m_bPart = new BOOL[ SKINPART_COUNT ];
m_rcPart = new CRect[ SKINPART_COUNT ];
m_nPart = new int[ SKINPART_COUNT ];
m_bAnchor = new BOOL[ SKINANCHOR_COUNT ];
m_rcAnchor = new CRect[ SKINANCHOR_COUNT ];
ZeroMemory( m_bPart, sizeof(BOOL) * SKINPART_COUNT );
ZeroMemory( m_nPart, sizeof(int) * SKINPART_COUNT );
ZeroMemory( m_bAnchor, sizeof(BOOL) * SKINANCHOR_COUNT );
m_szMinSize.cx = m_szMinSize.cy = 0;
m_rcMaximise.SetRect( -1, 0, -1, -1 );
m_rcResize.SetRect( BORDER_WIDTH, BORDER_WIDTH, BORDER_WIDTH, BORDER_WIDTH );
m_hoSkin = NULL;
m_bCaption = FALSE;
m_bCaptionCaps = FALSE;
m_crCaptionFill = CLR_NONE;
m_crCaptionText = RGB( 255, 255, 255 );
m_crCaptionInactive = RGB( 128, 128, 128 );
m_crCaptionShadow = CLR_NONE;
m_crCaptionOutline = CLR_NONE;
m_nCaptionAlign = 0;
m_pRegionXML = NULL;
m_nHoverAnchor = 0;
m_nDownAnchor = 0;
}
CSkinWindow::~CSkinWindow()
{
if ( m_dcSkin.m_hDC != NULL )
{
if ( m_hoSkin != NULL ) m_dcSkin.SelectObject( CBitmap::FromHandle( m_hoSkin ) );
m_dcSkin.DeleteDC();
}
if ( m_bmSkin.m_hObject != NULL ) m_bmSkin.DeleteObject();
if ( m_pRegionXML ) delete m_pRegionXML;
for ( POSITION pos = m_pPartList.GetStartPosition() ; pos ; )
{
CRect* pRect;
CString str;
m_pPartList.GetNextAssoc( pos, str, (void*&)pRect );
delete pRect;
}
for ( pos = m_pAnchorList.GetStartPosition() ; pos ; )
{
CRect* pRect;
CString str;
m_pAnchorList.GetNextAssoc( pos, str, (void*&)pRect );
delete pRect;
}
delete [] m_bPart;
delete [] m_rcPart;
delete [] m_nPart;
delete [] m_bAnchor;
delete [] m_rcAnchor;
}
//////////////////////////////////////////////////////////////////////
// CSkinWindow parse XML
BOOL CSkinWindow::Parse(CXMLElement* pBase, const CString& strPath)
{
static LPCTSTR pszPart[] =
{
_T("TopLeft"), _T("Top"), _T("TopRight"),
_T("TopLeftIA"), _T("TopIA"), _T("TopRightIA"),
_T("LeftTop"), _T("Left"), _T("LeftBottom"),
_T("RightTop"), _T("Right"), _T("RightBottom"),
_T("BottomLeft"), _T("Bottom"), _T("BottomRight"),
_T("System"), _T("SystemHover"), _T("SystemDown"),
_T("Minimise"), _T("MinimiseHover"), _T("MinimiseDown"),
_T("Maximise"), _T("MaximiseHover"), _T("MaximiseDown"),
_T("Close"), _T("CloseHover"), _T("CloseDown"),
NULL
};
static LPCTSTR pszAnchor[] =
{
_T("Icon"), _T("System"), _T("Minimise"), _T("Maximise"), _T("Close"),
NULL
};
if ( ! pBase->IsNamed( _T("windowSkin") ) ) return FALSE;
CString str;
CRect rc;
for ( POSITION pos = pBase->GetElementIterator() ; pos ; )
{
CXMLElement* pGroup = pBase->GetNextElement( pos );
if ( pGroup->IsNamed( _T("target") ) )
{
CString strTarget = pGroup->GetAttributeValue( _T("window") );
if ( strTarget == _T("CMainTabBarCtrl") )
strTarget = strTarget;
if ( strTarget.GetLength() )
{
m_sTargets += '|';
m_sTargets += strTarget;
m_sTargets += '|';
}
}
else if ( pGroup->IsNamed( _T("parts") ) )
{
for ( POSITION posInner = pGroup->GetElementIterator() ; posInner ; )
{
CXMLElement* pXML = pGroup->GetNextElement( posInner );
if ( ! pXML->IsNamed( _T("part") ) ) continue;
if ( ! ParseRect( pXML, &rc ) ) continue;
if ( ! rc.Width() ) rc.right++;
if ( ! rc.Height() ) rc.bottom++;
CString strMode = pXML->GetAttributeValue( _T("mode") );
int nMode = SKINPARTMODE_TILE;
if ( strMode.CompareNoCase( _T("tile") ) == 0 )
nMode = SKINPARTMODE_TILE;
else if ( strMode.CompareNoCase( _T("stretch") ) == 0 )
nMode = SKINPARTMODE_STRETCH;
CString strName = pXML->GetAttributeValue( _T("name") );
if ( strName.IsEmpty() ) continue;
for ( int nPart = 0 ; pszPart[ nPart ] ; nPart++ )
{
if ( _tcsicmp( strName, pszPart[ nPart ] ) == 0 )
{
m_bPart[ nPart ] = TRUE;
m_nPart[ nPart ] = nMode;
m_rcPart[ nPart ] = rc;
break;
}
}
if ( pszPart[ nPart ] == NULL )
{
CRect* pRect;
if ( m_pPartList.Lookup( strName, (void*&)pRect ) )
{
*pRect = rc;
}
else
{
pRect = new CRect( &rc );
m_pPartList.SetAt( strName, pRect );
}
}
}
}
else if ( pGroup->IsNamed( _T("anchors") ) )
{
for ( POSITION posInner = pGroup->GetElementIterator() ; posInner ; )
{
CXMLElement* pXML = pGroup->GetNextElement( posInner );
if ( ! pXML->IsNamed( _T("anchor") ) ) continue;
if ( ! ParseRect( pXML, &rc ) ) continue;
CString strName = pXML->GetAttributeValue( _T("name") );
for ( int nAnchor = 0 ; pszAnchor[ nAnchor ] ; nAnchor++ )
{
if ( _tcsicmp( strName, pszAnchor[ nAnchor ] ) == 0 )
{
m_bAnchor[ nAnchor ] = TRUE;
m_rcAnchor[ nAnchor ] = rc;
break;
}
}
if ( pszAnchor[ nAnchor ] == NULL )
{
CRect* pRect;
if ( m_pAnchorList.Lookup( strName, (void*&)pRect ) )
{
*pRect = rc;
}
else
{
pRect = new CRect( &rc );
m_pAnchorList.SetAt( strName, pRect );
}
}
}
}
else if ( pGroup->IsNamed( _T("region") ) )
{
if ( m_pRegionXML ) delete m_pRegionXML;
m_pRegionXML = pGroup->Detach();
}
else if ( pGroup->IsNamed( _T("caption") ) )
{
m_bCaption = ParseRect( pGroup, &m_rcCaption );
CString strFont = pGroup->GetAttributeValue( _T("fontFace") );
if ( strFont.GetLength() )
{
CString strSize = pGroup->GetAttributeValue( _T("fontSize") );
CString strBold = pGroup->GetAttributeValue( _T("fontWeight") );
if ( strBold.CompareNoCase( _T("bold") ) == 0 )
strBold = _T("700");
else if ( strBold.CompareNoCase( _T("normal") ) == 0 )
strBold = _T("400");
int nFontSize = 13, nFontWeight = FW_BOLD;
_stscanf( strSize, _T("%i"), &nFontSize );
_stscanf( strBold, _T("%i"), &nFontWeight );
LOGFONT lf;
ZeroMemory( &lf, sizeof(lf) );
lf.lfHeight = nFontSize;
lf.lfWeight = nFontWeight;
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfQuality = DEFAULT_QUALITY;
lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;
_tcscpy( lf.lfFaceName, strFont );
if ( _tcsistr( strSize, _T("pt") ) != NULL )
{
m_fnCaption.CreatePointFontIndirect( &lf );
}
else
{
lf.lfHeight = -lf.lfHeight;
m_fnCaption.CreateFontIndirect( &lf );
}
}
str = pGroup->GetAttributeValue( _T("colour") );
ParseColour( str, m_crCaptionText );
str = pGroup->GetAttributeValue( _T("inactiveColour") );
ParseColour( str, m_crCaptionInactive );
str = pGroup->GetAttributeValue( _T("fill") );
ParseColour( str, m_crCaptionFill );
str = pGroup->GetAttributeValue( _T("fillColour") );
ParseColour( str, m_crCaptionFill );
str = pGroup->GetAttributeValue( _T("shadowColour") );
ParseColour( str, m_crCaptionShadow );
str = pGroup->GetAttributeValue( _T("outlineColour") );
ParseColour( str, m_crCaptionOutline );
str = pGroup->GetAttributeValue( _T("caps") );
m_bCaptionCaps = str.GetLength() > 0;
str = pGroup->GetAttributeValue( _T("align") );
if ( str.CompareNoCase( _T("left") ) == 0 )
m_nCaptionAlign = 0;
else if ( str.CompareNoCase( _T("center") ) == 0 )
m_nCaptionAlign = 1;
else if ( str.CompareNoCase( _T("right") ) == 0 )
m_nCaptionAlign = 2;
if ( m_bCaption && m_fnCaption.m_hObject == NULL )
{
NONCLIENTMETRICS pMetrics;
pMetrics.cbSize = sizeof(pMetrics);
SystemParametersInfo( SPI_GETNONCLIENTMETRICS, pMetrics.cbSize, &pMetrics, 0 );
m_fnCaption.CreateFontIndirect( &pMetrics.lfCaptionFont );
}
}
else if ( pGroup->IsNamed( _T("image") ) )
{
str = pGroup->GetAttributeValue( _T("language") );
if ( str.GetLength() > 0 )
{
if ( str.CompareNoCase( Settings.General.Language ) != 0 ) continue;
m_sLanguage = str;
}
CString strRes = pGroup->GetAttributeValue( _T("res") );
CString strFile = pGroup->GetAttributeValue( _T("path") );
HBITMAP hBitmap = NULL;
if ( strFile.GetLength() > 0 )
{
strFile = strPath + strFile;
hBitmap = (HBITMAP)LoadImage( AfxGetInstanceHandle(), strFile,
IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
}
else if ( strRes.GetLength() > 0 )
{
UINT nResID = 0;
if ( _stscanf( strRes, _T("%lu"), &nResID ) != 1 ) return FALSE;
hBitmap = (HBITMAP)LoadImage( AfxGetInstanceHandle(),
MAKEINTRESOURCE(nResID), IMAGE_BITMAP, 0, 0, 0 );
}
if ( hBitmap == NULL ) return FALSE;
str = pGroup->GetAttributeValue( _T("type") );
str.MakeLower();
if ( str == _T("watermark") || str == _T("water") )
{
if ( m_bmWatermark.m_hObject != NULL ) m_bmWatermark.DeleteObject();
m_bmWatermark.Attach( hBitmap );
}
else if ( str == _T("alpha") )
{
if ( m_bmAlpha.m_hObject != NULL ) m_bmAlpha.DeleteObject();
m_bmAlpha.Attach( hBitmap );
}
else
{
if ( m_bmSkin.m_hObject != NULL ) m_bmSkin.DeleteObject();
m_bmSkin.Attach( hBitmap );
}
}
else if ( pGroup->IsNamed( _T("maximiseCrop") ) )
{
ParseRect( pGroup, &m_rcMaximise );
m_rcMaximise.right -= m_rcMaximise.left;
m_rcMaximise.bottom -= m_rcMaximise.top;
}
else if ( pGroup->IsNamed( _T("resizeBorder") ) )
{
ParseRect( pGroup, &m_rcResize );
m_rcResize.right -= m_rcResize.left;
m_rcResize.bottom -= m_rcResize.top;
}
else if ( pGroup->IsNamed( _T("minimumSize") ) )
{
CString str = pGroup->GetAttributeValue( _T("width") );
_stscanf( str, _T("%i"), &m_szMinSize.cx );
str = pGroup->GetAttributeValue( _T("height") );
_stscanf( str, _T("%i"), &m_szMinSize.cy );
}
}
return ( m_bmSkin.m_hObject != NULL );
}
//////////////////////////////////////////////////////////////////////
// CSkinWindow parse helpers
BOOL CSkinWindow::ParseRect(CXMLElement* pXML, CRect* pRect)
{
CString strValue = pXML->GetAttributeValue( _T("rect") );
if ( strValue.GetLength() )
{
_stscanf( strValue, _T("%i,%i,%i,%i"), &pRect->left, &pRect->top,
&pRect->right, &pRect->bottom );
pRect->right += pRect->left;
pRect->bottom += pRect->top;
return TRUE;
}
strValue = pXML->GetAttributeValue( _T("point") );
if ( strValue.GetLength() )
{
_stscanf( strValue, _T("%i,%i"), &pRect->left, &pRect->top );
pRect->right = pRect->bottom = 0;
return TRUE;
}
return FALSE;
}
BOOL CSkinWindow::ParseColour(const CString& str, COLORREF& cr)
{
if ( str.GetLength() != 6 ) return FALSE;
int nRed, nGreen, nBlue;
if ( _stscanf( str.Mid( 0, 2 ), _T("%x"), &nRed ) != 1 ) return FALSE;
if ( _stscanf( str.Mid( 2, 2 ), _T("%x"), &nGreen ) != 1 ) return FALSE;
if ( _stscanf( str.Mid( 4, 2 ), _T("%x"), &nBlue ) != 1 ) return FALSE;
cr = RGB( nRed, nGreen, nBlue );
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CSkinWindow window hooks
void CSkinWindow::CalcWindowRect(RECT* pRect, BOOL bToClient, BOOL bZoomed)
{
CRect rcAdjust( 0, 0, 0, 0 );
if ( m_bPart[ SKINPART_TOP_LEFT ] )
rcAdjust.top = max( rcAdjust.top, m_rcPart[ SKINPART_TOP_LEFT ].Height() );
if ( m_bPart[ SKINPART_TOP ] )
rcAdjust.top = max( rcAdjust.top, m_rcPart[ SKINPART_TOP ].Height() );
if ( m_bPart[ SKINPART_TOP_RIGHT ] )
rcAdjust.top = max( rcAdjust.top, m_rcPart[ SKINPART_TOP_RIGHT ].Height() );
if ( m_bPart[ SKINPART_LEFT ] )
rcAdjust.left = max( rcAdjust.left, m_rcPart[ SKINPART_LEFT ].Width() );
if ( m_bPart[ SKINPART_RIGHT ] )
rcAdjust.right = max( rcAdjust.right, m_rcPart[ SKINPART_RIGHT ].Width() );
if ( m_bPart[ SKINPART_BOTTOM_LEFT ] )
rcAdjust.bottom = max( rcAdjust.bottom, m_rcPart[ SKINPART_BOTTOM_LEFT ].Height() );
if ( m_bPart[ SKINPART_BOTTOM ] )
rcAdjust.bottom = max( rcAdjust.bottom, m_rcPart[ SKINPART_BOTTOM ].Height() );
if ( m_bPart[ SKINPART_BOTTOM_RIGHT ] )
rcAdjust.bottom = max( rcAdjust.bottom, m_rcPart[ SKINPART_BOTTOM_RIGHT ].Height() );
if ( bToClient )
{
pRect->left += rcAdjust.left;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -