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

📄 skin.cpp

📁 p2p软件
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// Skin.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 "CoolMenu.h"
#include "CtrlCoolBar.h"
#include "Skin.h"
#include "SkinWindow.h"
#include "ImageServices.h"
#include "ImageFile.h"
#include "Plugins.h"
#include "XML.h"
#include "WndChild.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

CSkin Skin;


//////////////////////////////////////////////////////////////////////
// CSkin construction

CSkin::CSkin()
{
}

CSkin::~CSkin()
{
	Clear();
}

//////////////////////////////////////////////////////////////////////
// CSkin apply

void CSkin::Apply()
{
	CreateDefault();
	ApplyRecursive( NULL );
	Finalise();
}

//////////////////////////////////////////////////////////////////////
// CSkin clear

void CSkin::Clear()
{
	CString strName;
	POSITION pos;
	
	for ( pos = m_pMenus.GetStartPosition() ; pos ; )
	{
		CMenu* pMenu;
		m_pMenus.GetNextAssoc( pos, strName, (void*&)pMenu );
		delete pMenu;
	}
	
	for ( pos = m_pToolbars.GetStartPosition() ; pos ; )
	{
		CCoolBarCtrl* pBar;
		m_pToolbars.GetNextAssoc( pos, strName, (void*&)pBar );
		delete pBar;
	}
	
	for ( pos = m_pDialogs.GetStartPosition() ; pos ; )
	{
		CXMLElement* pXML;
		m_pDialogs.GetNextAssoc( pos, strName, (void*&)pXML );
		delete pXML;
	}
	
	for ( pos = m_pDocuments.GetStartPosition() ; pos ; )
	{
		CXMLElement* pXML;
		m_pDocuments.GetNextAssoc( pos, strName, (void*&)pXML );
		delete pXML;
	}
	
	for ( pos = m_pSkins.GetHeadPosition() ; pos ; )
	{
		delete (CSkinWindow*)m_pSkins.GetNext( pos );
	}
	
	for ( pos = m_pFontPaths.GetHeadPosition() ; pos ; )
	{
		RemoveFontResource( m_pFontPaths.GetNext( pos ) );
	}
	
	m_pStrings.RemoveAll();
	m_pMenus.RemoveAll();
	m_pToolbars.RemoveAll();
	m_pDocuments.RemoveAll();
	m_pWatermarks.RemoveAll();
	m_pLists.RemoveAll();
	m_pDialogs.RemoveAll();
	m_pSkins.RemoveAll();
	m_pFontPaths.RemoveAll();
	
	if ( m_brDialog.m_hObject != NULL ) m_brDialog.DeleteObject();
	if ( m_bmPanelMark.m_hObject != NULL ) m_bmPanelMark.DeleteObject();
}

//////////////////////////////////////////////////////////////////////
// CSkin caption selector

BOOL CSkin::SelectCaption(CWnd* pWnd, int nIndex)
{
	CString strCaption;
	pWnd->GetWindowText( strCaption );
	
	if ( SelectCaption( strCaption, nIndex ) )
	{
		pWnd->SetWindowText( strCaption );
		return TRUE;
	}
	
	return FALSE;
}

BOOL CSkin::SelectCaption(CString& strCaption, int nIndex)
{
	for ( strCaption += '|' ; ; nIndex-- )
	{
		CString strSection = strCaption.SpanExcluding( _T("|") );
		strCaption = strCaption.Mid( strSection.GetLength() + 1 );
		if ( strSection.IsEmpty() ) break;

		if ( nIndex <= 0 )
		{
			strCaption = strSection;
			return TRUE;
		}
	}
	
	return FALSE;
}

//////////////////////////////////////////////////////////////////////
// CSkin recursive folder applicator

void CSkin::ApplyRecursive(LPCTSTR pszPath)
{
	WIN32_FIND_DATA pFind;
	CString strPath;
	HANDLE hSearch;

	strPath.Format( _T("%s\\Skins\\%s*.*"), (LPCTSTR)Settings.General.Path,
		pszPath ? pszPath : _T("") );

	hSearch = FindFirstFile( strPath, &pFind );

	if ( hSearch != INVALID_HANDLE_VALUE )
	{
		do
		{
			if ( pFind.cFileName[0] == '.' ) continue;

			if ( pFind.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
			{
				strPath.Format( _T("%s%s\\"),
					pszPath ? pszPath : _T(""), pFind.cFileName );

				ApplyRecursive( strPath );
			}
			else if (	_tcsistr( pFind.cFileName, _T(".xml") ) != NULL &&
						_tcsicmp( pFind.cFileName, _T("Definitions.xml") ) )
			{
				strPath.Format( _T("%s%s"),
					pszPath ? pszPath : _T(""), pFind.cFileName );

				if ( theApp.GetProfileInt( _T("Skins"), strPath, FALSE ) )
				{
					LoadFromFile( Settings.General.Path + _T("\\Skins\\") + strPath );
				}
			}
		}
		while ( FindNextFile( hSearch, &pFind ) );

		FindClose( hSearch );
	}
}

//////////////////////////////////////////////////////////////////////
// CSkin root load

BOOL CSkin::LoadFromFile(LPCTSTR pszFile)
{
	CXMLElement* pXML = CXMLElement::FromFile( pszFile );
	if ( pXML == NULL ) return FALSE;
	
	CString strPath = pszFile;
	int nSlash = strPath.ReverseFind( '\\' );
	if ( nSlash >= 0 ) strPath = strPath.Left( nSlash + 1 );
	
	BOOL bResult = LoadFromXML( pXML, strPath );
	
	delete pXML;
	
	return bResult;
}

BOOL CSkin::LoadFromResource(HINSTANCE hInstance, UINT nResourceID)
{
	HMODULE hModule = hInstance != NULL ? (HMODULE)hInstance : GetModuleHandle( NULL );
	HRSRC hRes = FindResource( hModule, MAKEINTRESOURCE( nResourceID ), MAKEINTRESOURCE( 23 ) );
	
	if ( hRes == NULL ) return FALSE;
	
	CString strBody;
	
	DWORD nSize			= SizeofResource( hModule, hRes );
	HGLOBAL hMemory		= ::LoadResource( hModule, hRes );
	LPTSTR pszOutput	= strBody.GetBuffer( nSize + 1 );
	LPCSTR pszInput		= (LPCSTR)LockResource( hMemory );
	
	while ( nSize-- ) *pszOutput++ = *pszInput++;
	*pszOutput++ = 0;
	
	strBody.ReleaseBuffer();

	CString strPath;
	strPath.Format( _T("%lu$"), (DWORD)hModule );
	
	return LoadFromString( strBody, strPath );
}

BOOL CSkin::LoadFromString(const CString& strXML, const CString& strPath)
{
	CXMLElement* pXML = CXMLElement::FromString( strXML, TRUE );
	if ( pXML == NULL ) return FALSE;

	BOOL bSuccess = LoadFromXML( pXML, strPath );

	delete pXML;
	return bSuccess;
}

BOOL CSkin::LoadFromXML(CXMLElement* pXML, const CString& strPath)
{
	if ( ! pXML->IsNamed( _T("skin") ) ) return FALSE;
	
	BOOL bSuccess = FALSE;
	
	for ( POSITION pos = pXML->GetElementIterator() ; pos ; )
	{
		CXMLElement* pSub = pXML->GetNextElement( pos );
		bSuccess = FALSE;
		
		if ( pSub->IsNamed( _T("commandImages") ) )
		{
			if ( ! LoadCommandImages( pSub, strPath ) ) break;
		}
		else if ( pSub->IsNamed( _T("watermarks" ) ) )
		{
			if ( ! LoadWatermarks( pSub, strPath ) ) break;
		}
		else if ( pSub->IsNamed( _T("windowSkins" ) ) )
		{
			if ( ! LoadWindowSkins( pSub, strPath ) ) break;
		}
		else if ( pSub->IsNamed( _T("menus") ) )
		{
			if ( ! LoadMenus( pSub ) ) break;
		}
		else if ( pSub->IsNamed( _T("toolbars") ) )
		{
			if ( ! LoadToolbars( pSub ) ) break;
		}
		else if ( pSub->IsNamed( _T("dialogs") ) )
		{
			if ( ! LoadDialogs( pSub ) ) break;
		}
		else if ( pSub->IsNamed( _T("strings") ) || pSub->IsNamed( _T("commandTips") ) )
		{
			if ( ! LoadStrings( pSub ) ) break;
		}
		else if ( pSub->IsNamed( _T("fonts" ) ) )
		{
			if ( ! LoadFonts( pSub, strPath ) ) break;
		}
		else if ( pSub->IsNamed( _T("colourScheme") ) )
		{
			if ( ! LoadColourScheme( pSub ) ) break;
		}
		else if ( pSub->IsNamed( _T("listColumns") ) )
		{
			if ( ! LoadListColumns( pSub ) ) break;
		}
		else if ( pSub->IsNamed( _T("commandMap") ) )
		{
			if ( ! LoadCommandMap( pSub ) ) break;
		}
		else if ( pSub->IsNamed( _T("documents" ) ) )
		{
			if ( ! LoadDocuments( pSub ) ) break;
		}
		else if ( pSub->IsNamed( _T("manifest") ) )
		{
			CString strType = pSub->GetAttributeValue( _T("type") );
			strType.MakeLower();
			
			if ( strType == _T("language") )
			{
				Settings.General.Language = pSub->GetAttributeValue( _T("language"), _T("en") );
			}
		}
		
		bSuccess = TRUE;
	}
	
	return bSuccess;
}

//////////////////////////////////////////////////////////////////////
// CSkin strings

BOOL CSkin::LoadString(CString& str, UINT nStringID)
{
	if ( m_pStrings.Lookup( nStringID, str ) ) return TRUE;
	if ( str.LoadString( nStringID ) ) return TRUE;
	str.Empty();
	return FALSE;
}

BOOL CSkin::LoadStrings(CXMLElement* pBase)
{
	for ( POSITION pos = pBase->GetElementIterator() ; pos ; )
	{
		CXMLElement* pXML = pBase->GetNextElement( pos );
		
		if ( pXML->IsNamed( _T("string") ) )
		{
			if ( UINT nID = LookupCommandID( pXML ) )
			{
				CString strValue = pXML->GetAttributeValue( _T("value") );
				
				while ( TRUE )
				{
					int nPos = strValue.Find( _T("\\n") );
					if ( nPos < 0 ) break;
					strValue = strValue.Left( nPos ) + _T("\n") + strValue.Mid( nPos + 2 );
				}
				
				// Hack for I64 compliance
				
				if ( nID == IDS_DOWNLOAD_FRAGMENT_REQUEST || nID == IDS_DOWNLOAD_USEFUL_RANGE ||
					 nID == IDS_UPLOAD_CONTENT || nID == IDS_UPLOAD_PARTIAL_CONTENT ||
					 nID == IDS_DOWNLOAD_VERIFY_DROP )
				{
					Replace( strValue, _T("%lu"), _T("%I64i") );
				}
				
				m_pStrings.SetAt( nID, strValue );
			}
		}
		else if ( pXML->IsNamed( _T("tip") ) )
		{
			if ( UINT nID = LookupCommandID( pXML ) )
			{
				CString strMessage = pXML->GetAttributeValue( _T("message") );
				CString strTip = pXML->GetAttributeValue( _T("tip") );
				if ( strTip.GetLength() ) strMessage += '\n' + strTip;
				m_pStrings.SetAt( nID, strMessage );
			}
		}
	}
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CSkin menus

CMenu* CSkin::GetMenu(LPCTSTR pszName)
{
	LPCTSTR* pszModeSuffix = m_pszModeSuffix[ Settings.General.GUIMode ];
	CString strName( pszName );
	CMenu* pMenu = NULL;
	
	for ( int nModeTry = 0 ; pszModeSuffix[ nModeTry ] ; nModeTry++ )
	{
		if ( m_pMenus.Lookup( strName + pszModeSuffix[ nModeTry ], (void*&)pMenu ) )
			return pMenu;
		
		for ( UINT nItem = 0 ; nItem < m_mnuDefault.GetMenuItemCount() ; nItem++ )
		{
			CString strItem;
			
			m_mnuDefault.GetMenuString( nItem, strItem, MF_BYPOSITION );
			
			if ( strItem.CompareNoCase( strName + pszModeSuffix[ nModeTry ] ) == 0 )
			{
				return m_mnuDefault.GetSubMenu( nItem );
			}
		}
	}
	
	return NULL;
}

BOOL CSkin::LoadMenus(CXMLElement* pBase)
{
	for ( POSITION pos = pBase->GetElementIterator() ; pos ; )
	{
		CXMLElement* pXML = pBase->GetNextElement( pos );
		if ( pXML->IsNamed( _T("menu") ) && ! LoadMenu( pXML ) ) return FALSE;
	}
	
	return TRUE;
}

BOOL CSkin::LoadMenu(CXMLElement* pXML)
{
	CString strName = pXML->GetAttributeValue( _T("name") );
	if ( strName.IsEmpty() ) return FALSE;
	
	CMenu* pMenu = NULL;
	
	if ( m_pMenus.Lookup( strName, (void*&)pMenu ) )
	{
		delete pMenu;
		m_pMenus.RemoveKey( strName );
	}
	
	pMenu = new CMenu();
	
	if ( pXML->GetAttributeValue( _T("type"), _T("popup") ).CompareNoCase( _T("bar") ) == 0 )
	{
		pMenu->CreateMenu();
	}
	else
	{
		pMenu->CreatePopupMenu();
	}
	
	if ( CreateMenu( pXML, pMenu->GetSafeHmenu() ) )
	{
		m_pMenus.SetAt( strName, pMenu );
		return TRUE;
	}
	else
	{
		delete pMenu;
		return FALSE;
	}
}

BOOL CSkin::CreateMenu(CXMLElement* pRoot, HMENU hMenu)
{
	for ( POSITION pos = pRoot->GetElementIterator() ; pos ; )
	{
		CXMLElement* pXML	= pRoot->GetNextElement( pos );
		CString strText		= pXML->GetAttributeValue( _T("text") );
		
		int nAmp = strText.Find( '_' );
		if ( nAmp >= 0 ) strText.SetAt( nAmp, '&' );
		
		if ( pXML->IsNamed( _T("item") ) )
		{
			if ( UINT nID = LookupCommandID( pXML ) )
			{
				CString strKeys = pXML->GetAttributeValue( _T("shortcut") );
				
				if ( strKeys.GetLength() ) strText += '\t' + strKeys;
				
				AppendMenu( hMenu, MF_STRING, nID, strText );
			}
		}
		else if ( pXML->IsNamed( _T("menu") ) )
		{
			HMENU hSubMenu = CreatePopupMenu();
			
			if ( ! CreateMenu( pXML, hSubMenu ) )
			{
				DestroyMenu( hSubMenu );
				return FALSE;
			}
			
			AppendMenu( hMenu, MF_STRING|MF_POPUP, (UINT)hSubMenu, strText );
		}
		else if ( pXML->IsNamed( _T("separator") ) )
		{
			AppendMenu( hMenu, MF_SEPARATOR, ID_SEPARATOR, NULL );
		}
	}

	return TRUE;
}

⌨️ 快捷键说明

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