Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

Skin.cpp

Go to the documentation of this file.
00001 //
00002 // Skin.cpp
00003 //
00004 // Copyright (c) Shareaza Development Team, 2002-2005.
00005 // This file is part of SHAREAZA (www.shareaza.com)
00006 //
00007 // Shareaza is free software; you can redistribute it
00008 // and/or modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2 of
00010 // the License, or (at your option) any later version.
00011 //
00012 // Shareaza is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with Shareaza; if not, write to the Free Software
00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 //
00021 
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "Settings.h"
00025 #include "CoolInterface.h"
00026 #include "CoolMenu.h"
00027 #include "CtrlCoolBar.h"
00028 #include "Skin.h"
00029 #include "SkinWindow.h"
00030 #include "ImageServices.h"
00031 #include "ImageFile.h"
00032 #include "Plugins.h"
00033 #include "XML.h"
00034 #include "WndChild.h"
00035 
00036 #ifdef _DEBUG
00037 #undef THIS_FILE
00038 static char THIS_FILE[]=__FILE__;
00039 #define new DEBUG_NEW
00040 #endif
00041 
00042 CSkin Skin;
00043 
00044 
00046 // CSkin construction
00047 
00048 CSkin::CSkin()
00049 {
00050 }
00051 
00052 CSkin::~CSkin()
00053 {
00054         Clear();
00055 }
00056 
00058 // CSkin apply
00059 
00060 void CSkin::Apply()
00061 {
00062         CreateDefault();
00063         ApplyRecursive( NULL );
00064         Finalise();
00065 }
00066 
00068 // CSkin clear
00069 
00070 void CSkin::Clear()
00071 {
00072         CString strName;
00073         POSITION pos;
00074         
00075         for ( pos = m_pMenus.GetStartPosition() ; pos ; )
00076         {
00077                 CMenu* pMenu;
00078                 m_pMenus.GetNextAssoc( pos, strName, (void*&)pMenu );
00079                 delete pMenu;
00080         }
00081         
00082         for ( pos = m_pToolbars.GetStartPosition() ; pos ; )
00083         {
00084                 CCoolBarCtrl* pBar;
00085                 m_pToolbars.GetNextAssoc( pos, strName, (void*&)pBar );
00086                 delete pBar;
00087         }
00088         
00089         for ( pos = m_pDialogs.GetStartPosition() ; pos ; )
00090         {
00091                 CXMLElement* pXML;
00092                 m_pDialogs.GetNextAssoc( pos, strName, (void*&)pXML );
00093                 delete pXML;
00094         }
00095         
00096         for ( pos = m_pDocuments.GetStartPosition() ; pos ; )
00097         {
00098                 CXMLElement* pXML;
00099                 m_pDocuments.GetNextAssoc( pos, strName, (void*&)pXML );
00100                 delete pXML;
00101         }
00102         
00103         for ( pos = m_pSkins.GetHeadPosition() ; pos ; )
00104         {
00105                 delete (CSkinWindow*)m_pSkins.GetNext( pos );
00106         }
00107         
00108         for ( pos = m_pFontPaths.GetHeadPosition() ; pos ; )
00109         {
00110                 RemoveFontResource( m_pFontPaths.GetNext( pos ) );
00111         }
00112         
00113         m_pStrings.RemoveAll();
00114         m_pMenus.RemoveAll();
00115         m_pToolbars.RemoveAll();
00116         m_pDocuments.RemoveAll();
00117         m_pWatermarks.RemoveAll();
00118         m_pLists.RemoveAll();
00119         m_pDialogs.RemoveAll();
00120         m_pSkins.RemoveAll();
00121         m_pFontPaths.RemoveAll();
00122         
00123         if ( m_brDialog.m_hObject != NULL ) m_brDialog.DeleteObject();
00124         if ( m_bmPanelMark.m_hObject != NULL ) m_bmPanelMark.DeleteObject();
00125 }
00126 
00128 // CSkin caption selector
00129 
00130 BOOL CSkin::SelectCaption(CWnd* pWnd, int nIndex)
00131 {
00132         CString strCaption;
00133         pWnd->GetWindowText( strCaption );
00134         
00135         if ( SelectCaption( strCaption, nIndex ) )
00136         {
00137                 pWnd->SetWindowText( strCaption );
00138                 return TRUE;
00139         }
00140         
00141         return FALSE;
00142 }
00143 
00144 BOOL CSkin::SelectCaption(CString& strCaption, int nIndex)
00145 {
00146         for ( strCaption += '|' ; ; nIndex-- )
00147         {
00148                 CString strSection = strCaption.SpanExcluding( _T("|") );
00149                 strCaption = strCaption.Mid( strSection.GetLength() + 1 );
00150                 if ( strSection.IsEmpty() ) break;
00151 
00152                 if ( nIndex <= 0 )
00153                 {
00154                         strCaption = strSection;
00155                         return TRUE;
00156                 }
00157         }
00158         
00159         return FALSE;
00160 }
00161 
00163 // CSkin recursive folder applicator
00164 
00165 void CSkin::ApplyRecursive(LPCTSTR pszPath)
00166 {
00167         WIN32_FIND_DATA pFind;
00168         CString strPath;
00169         HANDLE hSearch;
00170 
00171         strPath.Format( _T("%s\\Skins\\%s*.*"), (LPCTSTR)Settings.General.Path,
00172                 pszPath ? pszPath : _T("") );
00173 
00174         hSearch = FindFirstFile( strPath, &pFind );
00175 
00176         if ( hSearch != INVALID_HANDLE_VALUE )
00177         {
00178                 do
00179                 {
00180                         if ( pFind.cFileName[0] == '.' ) continue;
00181 
00182                         if ( pFind.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
00183                         {
00184                                 strPath.Format( _T("%s%s\\"),
00185                                         pszPath ? pszPath : _T(""), pFind.cFileName );
00186 
00187                                 ApplyRecursive( strPath );
00188                         }
00189                         else if (       _tcsistr( pFind.cFileName, _T(".xml") ) != NULL &&
00190                                                 _tcsicmp( pFind.cFileName, _T("Definitions.xml") ) )
00191                         {
00192                                 strPath.Format( _T("%s%s"),
00193                                         pszPath ? pszPath : _T(""), pFind.cFileName );
00194 
00195                                 if ( theApp.GetProfileInt( _T("Skins"), strPath, FALSE ) )
00196                                 {
00197                                         LoadFromFile( Settings.General.Path + _T("\\Skins\\") + strPath );
00198                                 }
00199                         }
00200                 }
00201                 while ( FindNextFile( hSearch, &pFind ) );
00202 
00203                 FindClose( hSearch );
00204         }
00205 }
00206 
00208 // CSkin root load
00209 
00210 BOOL CSkin::LoadFromFile(LPCTSTR pszFile)
00211 {
00212         CXMLElement* pXML = CXMLElement::FromFile( pszFile );
00213         if ( pXML == NULL ) return FALSE;
00214         
00215         CString strPath = pszFile;
00216         int nSlash = strPath.ReverseFind( '\\' );
00217         if ( nSlash >= 0 ) strPath = strPath.Left( nSlash + 1 );
00218         
00219         BOOL bResult = LoadFromXML( pXML, strPath );
00220         
00221         delete pXML;
00222         
00223         return bResult;
00224 }
00225 
00226 BOOL CSkin::LoadFromResource(HINSTANCE hInstance, UINT nResourceID)
00227 {
00228         HMODULE hModule = hInstance != NULL ? (HMODULE)hInstance : GetModuleHandle( NULL );
00229         HRSRC hRes = FindResource( hModule, MAKEINTRESOURCE( nResourceID ), MAKEINTRESOURCE( 23 ) );
00230         
00231         if ( hRes == NULL ) return FALSE;
00232         
00233         CString strBody;
00234         
00235         DWORD nSize                     = SizeofResource( hModule, hRes );
00236         HGLOBAL hMemory         = ::LoadResource( hModule, hRes );
00237         LPTSTR pszOutput        = strBody.GetBuffer( nSize + 1 );
00238         LPCSTR pszInput         = (LPCSTR)LockResource( hMemory );
00239         
00240         while ( nSize-- ) *pszOutput++ = *pszInput++;
00241         *pszOutput++ = 0;
00242         
00243         strBody.ReleaseBuffer();
00244 
00245         CString strPath;
00246         strPath.Format( _T("%lu$"), (DWORD)hModule );
00247         
00248         return LoadFromString( strBody, strPath );
00249 }
00250 
00251 BOOL CSkin::LoadFromString(const CString& strXML, const CString& strPath)
00252 {
00253         CXMLElement* pXML = CXMLElement::FromString( strXML, TRUE );
00254         if ( pXML == NULL ) return FALSE;
00255 
00256         BOOL bSuccess = LoadFromXML( pXML, strPath );
00257 
00258         delete pXML;
00259         return bSuccess;
00260 }
00261 
00262 BOOL CSkin::LoadFromXML(CXMLElement* pXML, const CString& strPath)
00263 {
00264         if ( ! pXML->IsNamed( _T("skin") ) ) return FALSE;
00265         
00266         BOOL bSuccess = FALSE;
00267         
00268         for ( POSITION pos = pXML->GetElementIterator() ; pos ; )
00269         {
00270                 CXMLElement* pSub = pXML->GetNextElement( pos );
00271                 bSuccess = FALSE;
00272                 
00273                 if ( pSub->IsNamed( _T("commandImages") ) )
00274                 {
00275                         if ( ! LoadCommandImages( pSub, strPath ) ) break;
00276                 }
00277                 else if ( pSub->IsNamed( _T("watermarks" ) ) )
00278                 {
00279                         if ( ! LoadWatermarks( pSub, strPath ) ) break;
00280                 }
00281                 else if ( pSub->IsNamed( _T("windowSkins" ) ) )
00282                 {
00283                         if ( ! LoadWindowSkins( pSub, strPath ) ) break;
00284                 }
00285                 else if ( pSub->IsNamed( _T("menus") ) )
00286                 {
00287                         if ( ! LoadMenus( pSub ) ) break;
00288                 }
00289                 else if ( pSub->IsNamed( _T("toolbars") ) )
00290                 {
00291                         if ( ! LoadToolbars( pSub ) ) break;
00292                 }
00293                 else if ( pSub->IsNamed( _T("dialogs") ) )
00294                 {
00295                         if ( ! LoadDialogs( pSub ) ) break;
00296                 }
00297                 else if ( pSub->IsNamed( _T("strings") ) || pSub->IsNamed( _T("commandTips") ) )
00298                 {
00299                         if ( ! LoadStrings( pSub ) ) break;
00300                 }
00301                 else if ( pSub->IsNamed( _T("fonts" ) ) )
00302                 {
00303                         if ( ! LoadFonts( pSub, strPath ) ) break;
00304                 }
00305                 else if ( pSub->IsNamed( _T("colourScheme") ) )
00306                 {
00307                         if ( ! LoadColourScheme( pSub ) ) break;
00308                 }
00309                 else if ( pSub->IsNamed( _T("listColumns") ) )
00310                 {
00311                         if ( ! LoadListColumns( pSub ) ) break;
00312                 }
00313                 else if ( pSub->IsNamed( _T("commandMap") ) )
00314                 {
00315                         if ( ! LoadCommandMap( pSub ) ) break;
00316                 }
00317                 else if ( pSub->IsNamed( _T("documents" ) ) )
00318                 {
00319                         if ( ! LoadDocuments( pSub ) ) break;
00320                 }
00321                 else if ( pSub->IsNamed( _T("manifest") ) )
00322                 {
00323                         CString strType = pSub->GetAttributeValue( _T("type") );
00324                         CharLower( strType.GetBuffer() );
00325                         strType.ReleaseBuffer();
00326                         
00327                         if ( strType == _T("language") )
00328                         {
00329                                 Settings.General.Language = pSub->GetAttributeValue( _T("language"), _T("en") );
00330                                 theApp.m_bRTL = ( pSub->GetAttributeValue( _T("dir"), _T("ltr") ) == "rtl" );
00331                                 theApp.WriteProfileInt( _T("Settings"), _T("LanguageRTL"), theApp.m_bRTL );
00332                         }
00333                         
00334                 }
00335                 
00336                 bSuccess = TRUE;
00337         }
00338         
00339         return bSuccess;
00340 }
00341 
00343 // CSkin strings
00344 
00345 BOOL CSkin::LoadString(CString& str, UINT nStringID)
00346 {
00347         if ( m_pStrings.Lookup( nStringID, str ) ) return TRUE;
00348         if ( str.LoadString( nStringID ) ) return TRUE;
00349         str.Empty();
00350         return FALSE;
00351 }
00352 
00353 BOOL CSkin::LoadStrings(CXMLElement* pBase)
00354 {
00355         for ( POSITION pos = pBase->GetElementIterator() ; pos ; )
00356         {
00357                 CXMLElement* pXML = pBase->GetNextElement( pos );
00358                 
00359                 if ( pXML->IsNamed( _T("string") ) )
00360                 {
00361                         if ( UINT nID = LookupCommandID( pXML ) )
00362                         {
00363                                 CString strValue = pXML->GetAttributeValue( _T("value") );
00364                                 
00365                                 while ( TRUE )
00366                                 {
00367                                         int nPos = strValue.Find( _T("\\n") );
00368                                         if ( nPos < 0 ) break;
00369                                         strValue = strValue.Left( nPos ) + _T("\n") + strValue.Mid( nPos + 2 );
00370                                 }
00371                                 
00372                                 // Hack for I64 compliance
00373                                 
00374                                 if ( nID == IDS_DOWNLOAD_FRAGMENT_REQUEST || nID == IDS_DOWNLOAD_USEFUL_RANGE ||
00375                                          nID == IDS_UPLOAD_CONTENT || nID == IDS_UPLOAD_PARTIAL_CONTENT ||
00376                                          nID == IDS_DOWNLOAD_VERIFY_DROP )
00377                                 {
00378                                         Replace( strValue, _T("%lu"), _T("%I64i") );
00379                                 }
00380                                 
00381                                 m_pStrings.SetAt( nID, strValue );
00382                         }
00383                 }
00384                 else if ( pXML->IsNamed( _T("tip") ) )
00385                 {
00386                         if ( UINT nID = LookupCommandID( pXML ) )
00387                         {
00388                                 CString strMessage = pXML->GetAttributeValue( _T("message") );
00389                                 CString strTip = pXML->GetAttributeValue( _T("tip") );
00390                                 if ( strTip.GetLength() ) strMessage += '\n' + strTip;
00391                                 m_pStrings.SetAt( nID, strMessage );
00392                         }
00393                 }
00394         }
00395         
00396         return TRUE;
00397 }
00398 
00400 // CSkin menus
00401 
00402 CMenu* CSkin::GetMenu(LPCTSTR pszName)
00403 {
00404         LPCTSTR* pszModeSuffix = m_pszModeSuffix[ Settings.General.GUIMode ];
00405         CString strName( pszName );
00406         CMenu* pMenu = NULL;
00407         
00408         for ( int nModeTry = 0 ; pszModeSuffix[ nModeTry ] ; nModeTry++ )
00409         {
00410                 if ( m_pMenus.Lookup( strName + pszModeSuffix[ nModeTry ], (void*&)pMenu ) )
00411                         return pMenu;
00412                 
00413                 for ( UINT nItem = 0 ; nItem < m_mnuDefault.GetMenuItemCount() ; nItem++ )
00414                 {
00415                         CString strItem;
00416                         
00417                         m_mnuDefault.GetMenuString( nItem, strItem, MF_BYPOSITION );
00418                         
00419                         if ( strItem.CompareNoCase( strName + pszModeSuffix[ nModeTry ] ) == 0 )
00420                         {
00421                                 return m_mnuDefault.GetSubMenu( nItem );
00422                         }
00423                 }
00424         }
00425         
00426         return NULL;
00427 }
00428 
00429 BOOL CSkin::LoadMenus(CXMLElement* pBase)
00430 {
00431         for ( POSITION pos = pBase->GetElementIterator() ; pos ; )
00432         {
00433                 CXMLElement* pXML = pBase->GetNextElement( pos );
00434                 if ( pXML->IsNamed( _T("menu") ) && ! LoadMenu( pXML ) ) return FALSE;
00435         }
00436         
00437         return TRUE;
00438 }
00439 
00440 BOOL CSkin::LoadMenu(CXMLElement* pXML)
00441 {
00442         CString strName = pXML->GetAttributeValue( _T("name") );
00443         if ( strName.IsEmpty() ) return FALSE;
00444         
00445         CMenu* pMenu = NULL;
00446         
00447         if ( m_pMenus.Lookup( strName, (void*&)pMenu ) )
00448         {
00449                 delete pMenu;
00450                 m_pMenus.RemoveKey( strName );
00451         }
00452         
00453         pMenu = new CMenu();
00454         
00455         if ( pXML->GetAttributeValue( _T("type"), _T("popup") ).CompareNoCase( _T("bar") ) == 0 )
00456         {
00457                 pMenu->CreateMenu();
00458         }
00459         else
00460         {
00461                 pMenu->CreatePopupMenu();
00462         }
00463         
00464         if ( CreateMenu( pXML, pMenu->GetSafeHmenu() ) )
00465         {
00466                 m_pMenus.SetAt( strName, pMenu );
00467                 return TRUE;
00468         }
00469         else
00470         {
00471                 delete pMenu;
00472                 return FALSE;
00473         }
00474 }
00475 
00476 BOOL CSkin::CreateMenu(CXMLElement* pRoot, HMENU hMenu)
00477 {
00478         for ( POSITION pos = pRoot->GetElementIterator() ; pos ; )
00479         {
00480                 CXMLElement* pXML       = pRoot->GetNextElement( pos );
00481                 CString strText         = pXML->GetAttributeValue( _T("text") );
00482                 
00483                 int nAmp = strText.Find( '_' );
00484                 if ( nAmp >= 0 ) strText.SetAt( nAmp, '&' );
00485                 
00486                 if ( pXML->IsNamed( _T("item") ) )
00487                 {
00488                         if ( UINT nID = LookupCommandID( pXML ) )
00489                         {
00490                                 CString strKeys = pXML->GetAttributeValue( _T("shortcut") );
00491                                 
00492                                 if ( strKeys.GetLength() ) strText += '\t' + strKeys;
00493                                 
00494                                 AppendMenu( hMenu, MF_STRING, nID, strText );
00495                         }
00496                 }
00497                 else if ( pXML->IsNamed( _T("menu") ) )
00498                 {
00499                         HMENU hSubMenu = CreatePopupMenu();
00500                         
00501                         if ( ! CreateMenu( pXML, hSubMenu ) )
00502                         {
00503                                 DestroyMenu( hSubMenu );
00504                                 return FALSE;
00505                         }
00506                         
00507                         AppendMenu( hMenu, MF_STRING|MF_POPUP, (UINT)hSubMenu, strText );
00508                 }
00509                 else if ( pXML->IsNamed( _T("separator") ) )
00510                 {
00511                         AppendMenu( hMenu, MF_SEPARATOR, ID_SEPARATOR, NULL );
00512                 }
00513         }
00514 
00515         return TRUE;
00516 }
00517 
00519 // CSkin toolbars
00520 
00521 BOOL CSkin::CreateToolBar(LPCTSTR pszName, CCoolBarCtrl* pBar)
00522 {
00523         if ( pszName == NULL ) return FALSE;
00524         
00525         if (pBar->m_hWnd)
00526         for ( CWnd* pChild = pBar->GetWindow( GW_CHILD ) ; pChild ; pChild = pChild->GetNextWindow() )
00527         {
00528                 pChild->ShowWindow( SW_HIDE );
00529         }
00530         
00531         CString strPath = pszName;
00532         strPath += _T(".Toolbar");
00533         
00534         if ( m_pWatermarks.Lookup( strPath, strPath ) )
00535         {
00536                 HBITMAP hBitmap = LoadBitmap( strPath );
00537                 pBar->SetWatermark( hBitmap );
00538         }
00539         else
00540         {
00541                 pBar->SetWatermark( NULL );
00542         }
00543         
00544         pBar->Clear();
00545         
00546         LPCTSTR* pszModeSuffix = m_pszModeSuffix[ Settings.General.GUIMode ];
00547         CCoolBarCtrl* pBase = NULL;
00548         CString strName( pszName );
00549         
00550         for ( int nModeTry = 0 ; pszModeSuffix[ nModeTry ] ; nModeTry++ )
00551         {
00552                 if ( m_pToolbars.Lookup( strName + pszModeSuffix[ nModeTry ], (void*&)pBase ) ) break;
00553         }
00554         
00555         if ( pBase != NULL )
00556         {
00557                 pBar->Copy( pBase );
00558                 return TRUE;
00559         }
00560         else
00561         {
00562                 return FALSE;
00563         }
00564 }
00565 
00566 BOOL CSkin::LoadToolbars(CXMLElement* pBase)
00567 {
00568         for ( POSITION pos = pBase->GetElementIterator() ; pos ; )
00569         {
00570                 CXMLElement* pXML = pBase->GetNextElement( pos );
00571                 if ( pXML->IsNamed( _T("toolbar") ) && ! CreateToolBar( pXML ) ) return FALSE;
00572         }
00573 
00574         return TRUE;
00575 }
00576 
00577 BOOL CSkin::CreateToolBar(CXMLElement* pBase)
00578 {
00579         CCoolBarCtrl* pBar = new CCoolBarCtrl();
00580         
00581         for ( POSITION pos = pBase->GetElementIterator() ; pos ; )
00582         {
00583                 CXMLElement* pXML = pBase->GetNextElement( pos );
00584                 
00585                 if ( pXML->IsNamed( _T("button") ) )
00586                 {
00587                         if ( UINT nID = LookupCommandID( pXML ) )
00588                         {
00589                                 CCoolBarItem* pItem = pBar->Add( nID, pXML->GetAttributeValue( _T("text") ) );
00590                                 CString strTemp = pXML->GetAttributeValue( _T("colour") );
00591                                 
00592                                 if ( strTemp.GetLength() == 6 )
00593                                 {
00594                                         int nRed, nGreen, nBlue;
00595                                         _stscanf( strTemp.Mid( 0, 2 ), _T("%x"), &nRed );
00596                                         _stscanf( strTemp.Mid( 2, 2 ), _T("%x"), &nGreen );
00597                                         _stscanf( strTemp.Mid( 4, 2 ), _T("%x"), &nBlue );
00598                                         pItem->m_crText = RGB( nRed, nGreen, nBlue );
00599                                 }
00600                                 
00601                                 strTemp = pXML->GetAttributeValue( _T("tip") );
00602                                 if ( strTemp.GetLength() ) pItem->SetTip( strTemp );
00603                                 
00604                                 strTemp = pXML->GetAttributeValue( _T("visible") );
00605                                 if ( strTemp.GetLength() ) pItem->Show( FALSE );
00606                         }
00607                 }
00608                 else if ( pXML->IsNamed( _T("separator") ) )
00609                 {
00610                         pBar->Add( ID_SEPARATOR );
00611                 }
00612                 else if ( pXML->IsNamed( _T("rightalign") ) )
00613                 {
00614                         pBar->Add( ID_RIGHTALIGN );
00615                 }
00616                 else if ( pXML->IsNamed( _T("control") ) )
00617                 {
00618                         UINT nID, nWidth, nHeight = 0;
00619                         CString strTemp;
00620                         
00621                         strTemp = pXML->GetAttributeValue( _T("id") );
00622                         if ( _stscanf( strTemp, _T("%lu"), &nID ) == 1 )
00623                         {
00624                                 strTemp = pXML->GetAttributeValue( _T("width") );
00625                                 
00626                                 if ( _stscanf( strTemp, _T("%lu"), &nWidth ) == 1 )
00627                                 {
00628                                         strTemp = pXML->GetAttributeValue( _T("height") );
00629                                         _stscanf( strTemp, _T("%lu"), &nHeight );
00630                                         pBar->Add( nID, nWidth, nHeight );
00631                                 }
00632                         }
00633                 }
00634                 else if ( pXML->IsNamed( _T("label") ) )
00635                 {
00636                         CCoolBarItem* pItem = pBar->Add( 1, pXML->GetAttributeValue( _T("text") ) );
00637                         pItem->m_crText = 0;
00638                         pItem->SetTip( pXML->GetAttributeValue( _T("tip") ) );
00639                 }
00640         }
00641         
00642         CString strName = pBase->GetAttributeValue( _T("name") );
00643         
00644         CCoolBarCtrl* pOld = NULL;
00645         if ( m_pToolbars.Lookup( strName, (void*&)pOld ) && pOld ) delete pOld;
00646         
00647         m_pToolbars.SetAt( strName, pBar );
00648         
00649         return TRUE;
00650 }
00651 
00653 // CSkin documents
00654 
00655 BOOL CSkin::LoadDocuments(CXMLElement* pBase)
00656 {
00657         for ( POSITION posDoc = pBase->GetElementIterator() ; posDoc ; )
00658         {
00659                 CXMLElement* pDoc = pBase->GetNextElement( posDoc );
00660                 if ( ! pDoc->IsNamed( _T("document") ) ) continue;
00661                 
00662                 CString strName = pDoc->GetAttributeValue( _T("name") );
00663                 
00664                 CXMLElement* pOld = NULL;
00665                 if ( m_pDocuments.Lookup( strName, (void*&)pOld ) ) delete pOld;
00666                 
00667                 m_pDocuments.SetAt( strName, pDoc->Detach() );
00668         }
00669         
00670         return TRUE;
00671 }
00672 
00673 CXMLElement* CSkin::GetDocument(LPCTSTR pszName)
00674 {
00675         CXMLElement* pXML = NULL;
00676 
00677         if ( m_pDocuments.Lookup( pszName, (void*&)pXML ) ) return pXML;
00678         
00679         return NULL;
00680 }
00681 
00683 // CSkin watermarks
00684 
00685 HBITMAP CSkin::GetWatermark(LPCTSTR pszName)
00686 {
00687         CString strPath;
00688         if ( m_pWatermarks.Lookup( pszName, strPath ) ) return LoadBitmap( strPath );
00689         return NULL;
00690 }
00691 
00692 BOOL CSkin::GetWatermark(CBitmap* pBitmap, LPCTSTR pszName)
00693 {
00694         ASSERT( pBitmap != NULL );
00695         if ( pBitmap->m_hObject != NULL ) pBitmap->DeleteObject();
00696         HBITMAP hBitmap = GetWatermark( pszName );
00697         if ( hBitmap != NULL ) pBitmap->Attach( hBitmap );
00698         return ( hBitmap != NULL );
00699 }
00700 
00701 BOOL CSkin::LoadWatermarks(CXMLElement* pSub, const CString& strPath)
00702 {
00703         for ( POSITION posMark = pSub->GetElementIterator() ; posMark ; )
00704         {
00705                 CXMLElement* pMark = pSub->GetNextElement( posMark );
00706         
00707                 if ( pMark->IsNamed( _T("watermark") ) )
00708                 {
00709                         CString strName = pMark->GetAttributeValue( _T("target") );
00710                         CString strFile = pMark->GetAttributeValue( _T("path") );
00711                         
00712                         if ( strName.GetLength() && strFile.GetLength() )
00713                         {
00714                                 strFile = strPath + strFile;
00715                                 m_pWatermarks.SetAt( strName, strFile );
00716                         }
00717                 }
00718         }
00719 
00720         return TRUE;
00721 }
00722 
00724 // CSkin list column translations
00725 
00726 BOOL CSkin::Translate(LPCTSTR pszName, CHeaderCtrl* pCtrl)
00727 {
00728         CString strEdit;
00729 
00730         if ( ! m_pLists.Lookup( pszName, strEdit ) ) return FALSE;
00731 
00732         TCHAR szColumn[128];
00733         HD_ITEM pColumn;
00734         
00735         if ( theApp.m_bRTL ) 
00736                 pCtrl->ModifyStyleEx( 0, WS_EX_LAYOUTRTL, 0 );
00737         pColumn.mask            = HDI_TEXT;
00738         pColumn.pszText         = szColumn;
00739         pColumn.cchTextMax      = 126;
00740 
00741         for ( int nItem = 0 ; nItem < pCtrl->GetItemCount() ; nItem++ )
00742         {
00743                 pCtrl->GetItem( nItem, &pColumn );
00744 
00745                 _tcscat( szColumn, _T("=") );
00746 
00747                 LPCTSTR pszFind = _tcsistr( strEdit, szColumn );
00748 
00749                 if ( pszFind )
00750                 {
00751                         pszFind += _tcslen( szColumn );
00752 
00753                         CString strNew = pszFind;
00754                         strNew = strNew.SpanExcluding( _T("|") );
00755 
00756                         _tcscpy( szColumn, strNew );
00757                         pCtrl->SetItem( nItem, &pColumn );
00758                 }
00759         }
00760 
00761         return TRUE;
00762 }
00763 
00764 BOOL CSkin::LoadListColumns(CXMLElement* pBase)
00765 {
00766         for ( POSITION pos = pBase->GetElementIterator() ; pos ; )
00767         {
00768                 CXMLElement* pXML = pBase->GetNextElement( pos );
00769                 if ( ! pXML->IsNamed( _T("list") ) ) continue;
00770 
00771                 CString strName = pXML->GetAttributeValue( _T("name") );
00772                 if ( strName.IsEmpty() ) continue;
00773 
00774                 CString strEdit;
00775 
00776                 for ( POSITION posCol = pXML->GetElementIterator() ; posCol ; )
00777                 {
00778                         CXMLElement* pCol = pXML->GetNextElement( posCol );
00779                         if ( ! pCol->IsNamed( _T("column") ) ) continue;
00780                         
00781                         CString strFrom = pCol->GetAttributeValue( _T("from") );
00782                         CString strTo   = pCol->GetAttributeValue( _T("to") );
00783 
00784                         if ( strFrom.IsEmpty() || strTo.IsEmpty() ) continue;
00785                         
00786                         if ( strEdit.GetLength() ) strEdit += '|';
00787                         strEdit += strFrom;
00788                         strEdit += '=';
00789                         strEdit += strTo;
00790                 }
00791 
00792                 m_pLists.SetAt( strName, strEdit );
00793         }
00794 
00795         return TRUE;
00796 }
00797 
00799 // CSkin dialogs
00800 
00801 BOOL CSkin::Apply(LPCTSTR pszName, CDialog* pDialog, UINT nIconID)
00802 {
00803         if ( nIconID )
00804         {
00805                 HICON hIcon = CoolInterface.ExtractIcon( nIconID );
00806                 
00807                 if ( hIcon == NULL )
00808                 {
00809                         hIcon = (HICON)LoadImage( AfxGetInstanceHandle(),
00810                                 MAKEINTRESOURCE( nIconID ), IMAGE_ICON, 16, 16, 0 );
00811                 }
00812                 
00813                 if ( hIcon != NULL ) pDialog->SetIcon( hIcon, FALSE );
00814         }
00815         
00816         CString strName;
00817 
00818         if ( pszName == NULL )
00819                 strName = pDialog->GetRuntimeClass()->m_lpszClassName;
00820         else
00821                 strName = pszName;
00822         
00823         CWnd* pWnd = pDialog->GetWindow( GW_CHILD );
00824         CString strCaption;
00825         
00826         for ( int nCount = 0 ; pWnd ; nCount++, pWnd = pWnd->GetNextWindow() )
00827         {
00828                 TCHAR szClass[3] = { 0, 0, 0 };
00829                 GetClassName( pWnd->GetSafeHwnd(), szClass, 3 );
00830                 strCaption += szClass;
00831         }
00832         
00833         if ( theApp.GetProfileInt( _T(""), _T("DialogScan"), FALSE ) )
00834         {
00835                 //USES_CONVERSION;
00836                 //LPCSTR pszOutput;
00837                 CFile pFile;
00838                 
00839                 if ( pFile.Open( _T("\\Dialog.xml"), CFile::modeReadWrite ) )
00840                 {
00841                         pFile.Seek( 0, CFile::end );
00842                 }
00843                 else if ( ! pFile.Open( _T("\\Dialog.xml"), CFile::modeWrite|CFile::modeCreate ) )
00844                 {
00845                         return FALSE;
00846                 }
00847 
00848                 pFile.Write( "<dialog name=\"", 14 );
00849 
00850                 int nBytes = WideCharToMultiByte( CP_ACP, 0, strName, strName.GetLength(), NULL, 0, NULL, NULL );
00851                 LPSTR pBytes = new CHAR[nBytes];
00852                 WideCharToMultiByte( CP_ACP, 0, strName, strName.GetLength(), pBytes, nBytes, NULL, NULL );
00853                 pFile.Write( pBytes, nBytes );
00854                 delete [] pBytes;
00855 
00856                 pFile.Write( "\" cookie=\"", 10 );
00857 
00858                 nBytes = WideCharToMultiByte( CP_ACP, 0, strCaption, strCaption.GetLength(), NULL, 0, NULL, NULL );
00859                 pBytes = new CHAR[nBytes];
00860                 WideCharToMultiByte( CP_ACP, 0, strCaption, strCaption.GetLength(), pBytes, nBytes, NULL, NULL );
00861                 pFile.Write( pBytes, nBytes );
00862                 delete [] pBytes;
00863 
00864                 pFile.Write( "\" caption=\"", 11 );
00865                 pDialog->GetWindowText( strCaption );
00866 
00867                 nBytes = WideCharToMultiByte( CP_ACP, 0, strCaption, strCaption.GetLength(), NULL, 0, NULL, NULL );
00868                 pBytes = new CHAR[nBytes];
00869                 WideCharToMultiByte( CP_ACP, 0, strCaption, strCaption.GetLength(), pBytes, nBytes, NULL, NULL );
00870                 pFile.Write( pBytes, nBytes );
00871                 delete [] pBytes;
00872 
00873                 pFile.Write( "\">\r\n", 4 );
00874 
00875                 /*
00876                 pFile.Write( "<dialog name=\"", 14 );
00877                 pszOutput = T2A(strName);
00878                 pFile.Write( pszOutput, strlen(pszOutput) );
00879                 pFile.Write( "\" cookie=\"", 10 );
00880                 pszOutput = T2A(strCaption);
00881                 pFile.Write( pszOutput, strlen(pszOutput) );
00882                 pFile.Write( "\" caption=\"", 11 );
00883                 pDialog->GetWindowText( strCaption );
00884                 pszOutput = T2A(strCaption);
00885                 pFile.Write( pszOutput, strlen(pszOutput) );
00886                 pFile.Write( "\">\r\n", 4 );
00887                 */
00888                 
00889                 for ( pWnd = pDialog->GetWindow( GW_CHILD ) ; pWnd ; pWnd = pWnd->GetNextWindow() )
00890                 {
00891                         TCHAR szClass[64];
00892                         
00893                         GetClassName( pWnd->GetSafeHwnd(), szClass, 64 );
00894                         strCaption.Empty();
00895                         
00896                         if ( _tcsistr( szClass, _T("Static") ) ||
00897                                  _tcsistr( szClass, _T("Button") ) )
00898                         {
00899                                 pWnd->GetWindowText( strCaption );
00900                         }
00901                         
00902                         if ( strCaption.GetLength() )
00903                         {
00904                                 Replace( strCaption, _T("&"), _T("_") );
00905                                 Replace( strCaption, _T("\""), _T("&quot;") );
00906                                 pFile.Write( "\t<control caption=\"", 19 );
00907 
00908                                 //pszOutput = T2A(strCaption);
00909                                 //pFile.Write( pszOutput, strlen(pszOutput) );
00910                                 int nBytes = WideCharToMultiByte( CP_ACP, 0, strCaption, strCaption.GetLength(), NULL, 0, NULL, NULL );
00911                                 LPSTR pBytes = new CHAR[nBytes];
00912                                 WideCharToMultiByte( CP_ACP, 0, strCaption, strCaption.GetLength(), pBytes, nBytes, NULL, NULL );
00913                                 pFile.Write( pBytes, nBytes );
00914                                 delete [] pBytes;
00915 
00916                         pFile.Write( "\"/>\r\n", 5 );
00917                         }
00918                         else
00919                         {
00920                                 pFile.Write( "\t<control/>\r\n", 10+3 );
00921                         }
00922                 }
00923                 
00924                 pFile.Write( "</dialog>\r\n\r\n", 13 );
00925                 pFile.Close();
00926                 
00927                 return TRUE;
00928         }
00929         
00930         CXMLElement* pBase = NULL;
00931         if ( ! m_pDialogs.Lookup( strName, (void*&)pBase ) ) return FALSE;
00932         
00933         if ( strCaption != pBase->GetAttributeValue( _T("cookie") ) ) return FALSE;
00934         
00935         strCaption = pBase->GetAttributeValue( _T("caption") );
00936         if ( strCaption.GetLength() ) pDialog->SetWindowText( strCaption );
00937         
00938         pWnd = pDialog->GetWindow( GW_CHILD );
00939         
00940         for ( POSITION pos = pBase->GetElementIterator() ; pos && pWnd ; )
00941         {
00942                 CXMLElement* pXML = pBase->GetNextElement( pos );
00943 
00944                 TCHAR szClass[3] = { 0, 0, 0 };
00945                 GetClassName( pWnd->GetSafeHwnd(), szClass, 3 );
00946 
00947                 // Needed for some controls like Schema combo box
00948                 if ( theApp.m_bRTL && (CString)szClass != "Ed" ) 
00949                         pWnd->ModifyStyleEx( 0, WS_EX_LAYOUTRTL|WS_EX_RTLREADING, 0 );
00950 
00951                 if ( pXML->IsNamed( _T("control") ) )
00952                 {
00953                         strCaption = pXML->GetAttributeValue( _T("caption") );
00954                         Replace( strCaption, _T("{n}"), _T("\r\n") );
00955                         
00956                         if ( strCaption.GetLength() )
00957                         {       
00958                                 if ( (CString) szClass != "Co" )
00959                                 {
00960                                         int nPos = strCaption.Find( '_' );
00961                                         if ( nPos >= 0 ) strCaption.SetAt( nPos, '&' );
00962                                         pWnd->SetWindowText( strCaption );
00963                                 }
00964                                 else
00965                                 {
00966                                         CStringArray pItems;
00967                                         CString strTemp;
00968                                         int nNum;
00969 
00970                                         Split( strCaption, _T("|"), pItems, TRUE );
00971                                         CComboBox* pCombo = (CComboBox*) pWnd;
00972                                         nNum = pCombo->GetCount();
00973                                         if ( nNum == pItems.GetSize() ) 
00974                                         {
00975                                                 for ( int nCount = 0; nCount < nNum; nCount++ )
00976                                                 {
00977                                                         pCombo->DeleteString( 0 );
00978                                                         strTemp = pItems.GetAt( nCount );
00979                                                         pCombo->AddString( (LPCTSTR) strTemp );
00980                                                 }
00981                                         }
00982                                 }
00983                         }
00984                         
00985                         pWnd = pWnd->GetNextWindow();
00986                 }
00987         }
00988         
00989         return TRUE;
00990 }
00991 
00992 CString CSkin::GetDialogCaption(LPCTSTR pszName)
00993 {
00994         CXMLElement* pBase = NULL;
00995         CString strCaption;
00996         
00997         if ( m_pDialogs.Lookup( pszName, (void*&)pBase ) )
00998         {
00999                 strCaption = pBase->GetAttributeValue( _T("caption") );
01000         }
01001         
01002         return strCaption;
01003 }
01004 
01005 BOOL CSkin::LoadDialogs(CXMLElement* pBase)
01006 {
01007         for ( POSITION pos = pBase->GetElementIterator() ; pos ; )
01008         {
01009                 CXMLElement* pXML = pBase->GetNextElement( pos );
01010 
01011                 if ( pXML->IsNamed( _T("dialog") ) )
01012                 {
01013                         CString strName = pXML->GetAttributeValue( _T("name") );
01014                         CXMLElement* pOld;
01015 
01016                         if ( m_pDialogs.Lookup( strName, (void*&)pOld ) ) delete pOld;
01017 
01018                         pXML->Detach();
01019                         m_pDialogs.SetAt( strName, pXML );
01020                 }
01021         }
01022 
01023         return TRUE;
01024 }
01025 
01027 // CSkin window skins
01028 
01029 CSkinWindow* CSkin::GetWindowSkin(LPCTSTR pszWindow, LPCTSTR pszAppend)
01030 {
01031         CString strWindow;
01032         strWindow.Format( _T("|%s%s|"), pszWindow, pszAppend ? pszAppend : _T("") );
01033         
01034         for ( POSITION pos = m_pSkins.GetHeadPosition() ; pos ; )
01035         {
01036                 CSkinWindow* pSkin = (CSkinWindow*)m_pSkins.GetNext( pos );
01037                 if ( pSkin->m_sTargets.Find( strWindow ) >= 0 ) return pSkin;
01038         }
01039         
01040         return NULL;
01041 }
01042 
01043 CSkinWindow* CSkin::GetWindowSkin(CWnd* pWnd)
01044 {
01045         LPCTSTR* pszModeSuffix = m_pszModeSuffix[ Settings.General.GUIMode ];
01046         BOOL bPanel = FALSE;
01047         
01048         ASSERT(pWnd != NULL);
01049 
01050         if ( pWnd->IsKindOf( RUNTIME_CLASS(CChildWnd) ) )
01051         {
01052                 CChildWnd* pChild = (CChildWnd*)pWnd;
01053                 bPanel = pChild->m_bPanelMode;
01054         }
01055         #ifdef _AFXDLL
01056         for ( CRuntimeClass* pClass = pWnd->GetRuntimeClass() ; pClass && pClass->m_pfnGetBaseClass ; pClass = pClass->m_pfnGetBaseClass() )
01057         #else
01058         for ( CRuntimeClass* pClass = pWnd->GetRuntimeClass() ; pClass ; pClass = pClass->m_pBaseClass )
01059         #endif
01060         {
01061                 if ( bPanel )
01062                 {
01063                         CSkinWindow* pSkin = GetWindowSkin( CString( pClass->m_lpszClassName ), _T(".Panel") );
01064                         if ( pSkin != NULL ) return pSkin;
01065                 }
01066                 
01067                 for ( int nSuffix = 0 ; pszModeSuffix[ nSuffix ] != NULL ; nSuffix ++ )
01068                 {
01069                         if ( pszModeSuffix[ nSuffix ][0] != 0 || ! bPanel )
01070                         {
01071                                 CSkinWindow* pSkin = GetWindowSkin(
01072                                         CString( pClass->m_lpszClassName ), pszModeSuffix[ nSuffix ] );
01073                                 if ( pSkin != NULL ) return pSkin;
01074                         }
01075                 }
01076         }
01077         
01078         return NULL;
01079 }
01080 
01081 BOOL CSkin::LoadWindowSkins(CXMLElement* pSub, const CString& strPath)
01082 {
01083         for ( POSITION posSkin = pSub->GetElementIterator() ; posSkin ; )
01084         {
01085                 CXMLElement* pSkinElement = pSub->GetNextElement( posSkin );
01086                 
01087                 if ( pSkinElement->IsNamed( _T("windowSkin") ) )
01088                 {
01089                         CSkinWindow* pSkin = new CSkinWindow();
01090                         
01091                         if ( pSkin->Parse( pSkinElement, strPath ) )
01092                         {
01093                                 m_pSkins.AddHead( pSkin );
01094                         }
01095                         else
01096                         {
01097                                 delete pSkin;
01098                         }
01099                 }
01100         }
01101         
01102         return TRUE;
01103 }
01104 
01106 // CSkin colour scheme
01107 
01108 BOOL CSkin::LoadColourScheme(CXMLElement* pBase)
01109 {
01110         CMapStringToPtr pColours;
01111 
01112         pColours.SetAt( _T("system.base.window"), &CoolInterface.m_crWindow );
01113         pColours.SetAt( _T("system.base.midtone"), &CoolInterface.m_crMidtone );
01114         pColours.SetAt( _T("system.base.highlight"), &CoolInterface.m_crHighlight );
01115         pColours.SetAt( _T("system.base.text"), &CoolInterface.m_crText );
01116         pColours.SetAt( _T("system.base.hitext"), &CoolInterface.m_crHiText );
01117 
01118         pColours.SetAt( _T("system.back.normal"), &CoolInterface.m_crBackNormal );
01119         pColours.SetAt( _T("system.back.selected"), &CoolInterface.m_crBackSel );
01120         pColours.SetAt( _T("system.back.checked"), &CoolInterface.m_crBackCheck );
01121         pColours.SetAt( _T("system.back.checked.selected"), &CoolInterface.m_crBackCheckSel );
01122         pColours.SetAt( _T("system.margin"), &CoolInterface.m_crMargin );
01123         pColours.SetAt( _T("system.border"), &CoolInterface.m_crBorder );
01124         pColours.SetAt( _T("system.shadow"), &CoolInterface.m_crShadow );
01125         pColours.SetAt( _T("system.text"), &CoolInterface.m_crCmdText );
01126         pColours.SetAt( _T("system.text.selected"), &CoolInterface.m_crCmdTextSel );
01127         pColours.SetAt( _T("system.disabled"), &CoolInterface.m_crDisabled );
01128         pColours.SetAt( _T("tooltip.back"), &CoolInterface.m_crTipBack );
01129         pColours.SetAt( _T("tooltip.text"), &CoolInterface.m_crTipText );
01130         pColours.SetAt( _T("tooltip.border"), &CoolInterface.m_crTipBorder );
01131         pColours.SetAt( _T("tooltip.warnings"), &CoolInterface.m_crTipWarnings );
01132         
01133         pColours.SetAt( _T("taskpanel.back"), &CoolInterface.m_crTaskPanelBack );
01134         pColours.SetAt( _T("taskbox.caption.back"), &CoolInterface.m_crTaskBoxCaptionBack );
01135         pColours.SetAt( _T("taskbox.caption.text"), &CoolInterface.m_crTaskBoxCaptionText );
01136         pColours.SetAt( _T("taskbox.primary.back"), &CoolInterface.m_crTaskBoxPrimaryBack );
01137         pColours.SetAt( _T("taskbox.primary.text"), &CoolInterface.m_crTaskBoxPrimaryText );
01138         pColours.SetAt( _T("taskbox.caption.hover"), &CoolInterface.m_crTaskBoxCaptionHover );
01139         pColours.SetAt( _T("taskbox.client"), &CoolInterface.m_crTaskBoxClient );
01140         
01141         pColours.SetAt( _T("dialog.back"), &m_crDialog );
01142         pColours.SetAt( _T("panel.caption.back"), &m_crPanelBack );
01143         pColours.SetAt( _T("panel.caption.text"), &m_crPanelText );
01144         pColours.SetAt( _T("panel.caption.border"), &m_crPanelBorder );
01145         pColours.SetAt( _T("banner.back"), &m_crBannerBack );
01146         pColours.SetAt( _T("banner.text"), &m_crBannerText );
01147         pColours.SetAt( _T("schema.row1"), &m_crSchemaRow[0] );
01148         pColours.SetAt( _T("schema.row2"), &m_crSchemaRow[1] );
01149         
01150         BOOL bSystem = FALSE, bNonBase = FALSE;
01151         
01152         for ( POSITION pos = pBase->GetElementIterator() ; pos ; )
01153         {
01154                 CXMLElement* pXML = pBase->GetNextElement( pos );
01155                 if ( ! pXML->IsNamed( _T("colour") ) ) continue;
01156 
01157                 CString strName         = pXML->GetAttributeValue( _T("name") );
01158                 CString strValue        = pXML->GetAttributeValue( _T("value") );
01159                 CharLower( strName.GetBuffer() );
01160                 strName.ReleaseBuffer();
01161 
01162                 COLORREF* pColour;
01163 
01164                 if ( pColours.Lookup( strName, (void*&)pColour ) && strValue.GetLength() == 6 )
01165                 {
01166                         int nRed, nGreen, nBlue;
01167 
01168                         _stscanf( strValue.Mid( 0, 2 ), _T("%x"), &nRed );
01169                         _stscanf( strValue.Mid( 2, 2 ), _T("%x"), &nGreen );
01170                         _stscanf( strValue.Mid( 4, 2 ), _T("%x"), &nBlue );
01171 
01172                         if ( strName.Find( _T("system.") ) >= 0 )
01173                         {
01174                                 bSystem = TRUE;
01175 
01176                                 if ( ! bNonBase && strName.Find( _T(".base.") ) < 0 )
01177                                 {
01178                                         bNonBase = TRUE;
01179                                         CoolInterface.CalculateColours( TRUE );
01180                                 }
01181                         }
01182 
01183                         *pColour = RGB( nRed, nGreen, nBlue );
01184                 }
01185         }
01186 
01187         if ( bSystem && ! bNonBase ) CoolInterface.CalculateColours( TRUE );
01188 
01189         return TRUE;
01190 }
01191 
01193 // CSkin command lookup helper
01194 
01195 UINT CSkin::LookupCommandID(CXMLElement* pXML, LPCTSTR pszName)
01196 {
01197         CString strID = pXML->GetAttributeValue( pszName ? pszName : _T("id") );
01198         UINT nID = 0;
01199         
01200         if ( _istdigit( *(LPCTSTR)strID ) )
01201         {
01202                 _stscanf( strID, _T("%lu"), &nID );
01203         }
01204         else
01205         {
01206                 nID = CoolInterface.NameToID( strID );
01207         }
01208         
01209         return nID;
01210 }
01211 
01213 // CSkin command map
01214 
01215 BOOL CSkin::LoadCommandMap(CXMLElement* pBase)
01216 {
01217         for ( POSITION pos = pBase->GetElementIterator() ; pos ; )
01218         {
01219                 CXMLElement* pXML = pBase->GetNextElement( pos );
01220 
01221                 if (  pXML->IsNamed( _T("command") ) )
01222                 {
01223                         CString strTemp = pXML->GetAttributeValue( _T("code") );
01224                         UINT nID;
01225 
01226                         if ( _stscanf( strTemp, _T("%lu"), &nID ) != 1 )
01227                                 return FALSE;
01228 
01229                         strTemp = pXML->GetAttributeValue( _T("id") );
01230 
01231                         CoolInterface.NameCommand( nID, strTemp );
01232                 }
01233         }
01234 
01235         return TRUE;
01236 }
01237 
01239 // CSkin fonts
01240 
01241 BOOL CSkin::LoadFonts(CXMLElement* pBase, const CString& strPath)
01242 {
01243         for ( POSITION pos = pBase->GetElementIterator() ; pos ; )
01244         {
01245                 CXMLElement* pXML = pBase->GetNextElement( pos );
01246                 
01247                 if ( pXML->IsNamed( _T("font") ) )
01248                 {
01249                         CString strName         = pXML->GetAttributeValue( _T("name") );
01250                         CString strFace         = pXML->GetAttributeValue( _T("face") );
01251                         CString strSize         = pXML->GetAttributeValue( _T("size") );
01252                         CString strWeight       = pXML->GetAttributeValue( _T("weight") );
01253                         
01254                         CFont* pFont = NULL;
01255 
01256                         if ( strName.CompareNoCase( _T("system.plain") ) == 0 )
01257                         {
01258                                 pFont = &CoolInterface.m_fntNormal;
01259                         }
01260                         else if ( strName.CompareNoCase( _T("system.bold") ) == 0 )
01261                         {
01262                                 pFont = &CoolInterface.m_fntBold;
01263                         }
01264                         else if ( strName.CompareNoCase( _T("panel.caption") ) == 0 )
01265                         {
01266                                 pFont = &CoolInterface.m_fntCaption;
01267                         }
01268                         else
01269                         {
01270                                 continue;
01271                         }
01272                         
01273                         if ( pFont->m_hObject ) pFont->DeleteObject();
01274 
01275                         if ( strWeight.CompareNoCase( _T("bold") ) == 0 )
01276                                 strWeight = _T("700");
01277                         else if ( strWeight.CompareNoCase( _T("normal") ) == 0 )
01278                                 strWeight = _T("400");
01279 
01280                         int nFontSize = 11, nFontWeight = FW_NORMAL;
01281 
01282                         _stscanf( strSize, _T("%i"), &nFontSize );
01283                         _stscanf( strWeight, _T("%i"), &nFontWeight );
01284 
01285                         pFont->CreateFont( -nFontSize, 0, 0, 0, nFontWeight, FALSE, FALSE, FALSE,
01286                                 DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
01287                                 DEFAULT_PITCH|FF_DONTCARE, strFace );
01288                 }
01289                 else if ( pXML->IsNamed( _T("import") ) )
01290                 {
01291                         CString strFile = strPath + pXML->GetAttributeValue( _T("path") );
01292                         BOOL bSuccess = FALSE;
01293                         
01294                         if ( HINSTANCE hGDI = LoadLibrary( _T("gdi32") ) )
01295                         {
01296                                 int (WINAPI *pfnAddFontResourceEx)(LPCTSTR, DWORD, PVOID);
01297                                 
01298                                 (FARPROC&)pfnAddFontResourceEx = GetProcAddress( hGDI, "AddFontResourceExW" );
01299                                 
01300                                 if ( pfnAddFontResourceEx != NULL )
01301                                 {
01302                                         bSuccess = (*pfnAddFontResourceEx)( strFile, FR_PRIVATE, NULL );
01303                                 }
01304                                 
01305                                 FreeLibrary( hGDI );
01306                         }
01307                         
01308                         if ( ! bSuccess )
01309                         {
01310                                 bSuccess = AddFontResource( strFile );
01311                         }
01312                         
01313                         if ( bSuccess ) m_pFontPaths.AddTail( strFile );
01314                 }
01315         }
01316         
01317         return TRUE;
01318 }
01319 
01321 // CSkin command images
01322 
01323 BOOL CSkin::LoadCommandImages(CXMLElement* pBase, const CString& strPath)
01324 {
01325         for ( POSITION pos = pBase->GetElementIterator() ; pos ; )
01326         {
01327                 CXMLElement* pXML = pBase->GetNextElement( pos );
01328                 
01329                 if ( pXML->IsNamed( _T("icon") ) )
01330                 {
01331                         UINT nID = LookupCommandID( pXML );
01332                         if ( nID == 0 ) continue;
01333                         
01334                         CString strFile = strPath;
01335                         strFile += pXML->GetAttributeValue( _T("res") );
01336                         strFile += pXML->GetAttributeValue( _T("path") );
01337                         
01338                         int nPos = strFile.Find( '$' );
01339                         HICON hIcon = NULL;
01340                         
01341                         if ( nPos < 0 )
01342                         {
01343                                 if ( ExtractIconEx( strFile, 0, NULL, &hIcon, 1 ) != NULL && hIcon != NULL )
01344                                 {
01345                                         if ( theApp.m_bRTL ) hIcon = CreateMirroredIcon( hIcon );
01346                                         CoolInterface.AddIcon( nID, hIcon );
01347                                 }
01348                         }
01349                         else
01350                         {
01351                                 HINSTANCE hInstance = NULL;
01352                                 UINT nIconID = 0;
01353                                 
01354                                 if ( _stscanf( strFile.Left( nPos ), _T("%lu"), &hInstance ) != 1 ) return TRUE;
01355                                 if ( _stscanf( strFile.Mid( nPos + 1 ), _T("%lu"), &nIconID ) != 1 ) return TRUE;
01356                                 
01357                                 hIcon = (HICON)LoadImage( hInstance, MAKEINTRESOURCE(nIconID), IMAGE_ICON, 16, 16, 0 );
01358                                 if ( hIcon != NULL ) 
01359                                         CoolInterface.AddIcon( nID, theApp.m_bRTL ? CreateMirroredIcon( hIcon ) : hIcon );
01360                         }
01361                 }
01362                 else if ( pXML->IsNamed( _T("bitmap") ) )
01363                 {
01364                         if ( ! LoadCommandBitmap( pXML, strPath ) ) return FALSE;
01365                 }
01366         }
01367         
01368         return TRUE;
01369 }
01370 
01371 BOOL CSkin::LoadCommandBitmap(CXMLElement* pBase, const CString& strPath)
01372 {
01373         static LPCTSTR pszNames[] = { _T("id"), _T("id1"), _T("id2"), _T("id3"), _T("id4"), _T("id5"), _T("id6"), _T("id7"), _T("id8"), _T("id9"), NULL };
01374         
01375         CString strFile = strPath;
01376         strFile += pBase->GetAttributeValue( _T("id") );
01377         strFile += pBase->GetAttributeValue( _T("path") );
01378         
01379         HBITMAP hBitmap = LoadBitmap( strFile );
01380         if ( hBitmap == NULL ) return TRUE;
01381         if ( theApp.m_bRTL ) hBitmap = CreateMirroredBitmap( hBitmap );
01382 
01383         strFile = pBase->GetAttributeValue( _T("mask") );
01384         COLORREF crMask = RGB( 0, 255, 0 );
01385         
01386         if ( strFile.GetLength() == 6 )
01387         {
01388                 int nRed, nGreen, nBlue;
01389                 _stscanf( strFile.Mid( 0, 2 ), _T("%x"), &nRed );
01390                 _stscanf( strFile.Mid( 2, 2 ), _T("%x"), &nGreen );
01391                 _stscanf( strFile.Mid( 4, 2 ), _T("%x"), &nBlue );
01392                 crMask = RGB( nRed, nGreen, nBlue );
01393         }
01394         
01395         CoolInterface.ConfirmImageList();
01396         int nBase = ImageList_AddMasked( CoolInterface.m_pImages.m_hImageList, hBitmap, crMask );
01397         
01398         if ( nBase < 0 )
01399         {
01400                 DeleteObject( hBitmap );
01401                 return FALSE;
01402         }
01403         
01404         int nIndex = 0;
01405         // Total number of images
01406         int nIndexRev = CoolInterface.m_pImages.GetImageCount() - 1;
01407         
01408         for ( POSITION pos = pBase->GetElementIterator() ; pos ; )
01409         {
01410                 CXMLElement* pXML = pBase->GetNextElement( pos );
01411                 if ( ! pXML->IsNamed( _T("image") ) ) continue;
01412                 
01413                 strFile = pXML->GetAttributeValue( _T("index") );
01414                 if ( strFile.GetLength() ) _stscanf( strFile, _T("%i"), &nIndex );
01415                 nIndex += nBase;
01416 
01417                 for ( int nName = 0 ; pszNames[ nName ] ; nName++ )
01418                 {
01419                         UINT nID = LookupCommandID( pXML, pszNames[ nName ] );
01420                         if ( nID ) CoolInterface.m_pImageMap.SetAt( (LPVOID)nID, 
01421                                 theApp.m_bRTL ? (LPVOID)nIndexRev : (LPVOID)nIndex );
01422                         if ( nName && ! nID ) break;
01423                 }
01424                 nIndexRev--;    
01425                 nIndex -= nBase;
01426                 nIndex ++;
01427         }
01428         
01429         DeleteObject( hBitmap );
01430         
01431         return TRUE;
01432 }
01433 
01435 // CSkin default skin
01436 
01437 void CSkin::CreateDefault()
01438 {
01439         // Clear
01440         
01441         Clear();
01442         
01443         Settings.General.Language = _T("en");
01444         
01445         // Base UI
01446         
01447         CoolInterface.Clear();
01448         CoolInterface.CreateFonts();
01449         CoolInterface.CalculateColours( FALSE );
01450         
01451         // Colour Scheme
01452         
01453         m_crDialog                                      = CoolInterface.GetDialogBkColor();
01454         m_crPanelBack                           = RGB( 60, 60, 60 );
01455         m_crPanelText                           = RGB( 255, 255, 255 );
01456         m_crPanelBorder                         = RGB( 0, 0, 0 );
01457         m_crBannerBack                          = RGB( 122, 161, 230 );
01458         m_crBannerText                          = RGB( 250, 250, 255 );
01459         m_crSchemaRow[0]                        = RGB( 245, 245, 255 );
01460         m_crSchemaRow[1]                        = RGB( 214, 223, 247 );
01461         
01462         // Command Icons
01463         
01464         HICON hIcon = theApp.LoadIcon( IDI_CHECKMARK );
01465         CoolInterface.AddIcon( ID_CHECKMARK, theApp.m_bRTL ? CreateMirroredIcon( hIcon ) : hIcon );
01466         
01467         // Default Menu
01468         
01469         CMenu* pMenuBar = new CMenu();
01470         pMenuBar->LoadMenu( IDR_MAINFRAME );
01471         m_pMenus.SetAt( _T("CMainWnd"), pMenuBar );
01472         if ( m_mnuDefault.m_hMenu == NULL ) m_mnuDefault.LoadMenu( IDR_POPUPS );
01473         
01474         // Load Definitions
01475         
01476         LoadFromResource( NULL, IDR_XML_DEFINITIONS );
01477         LoadFromResource( NULL, IDR_XML_DEFAULT );
01478         
01479         // Copying
01480         CoolInterface.CopyIcon( ID_HELP_FAQ, ID_HELP_GUIDE );
01481         CoolInterface.CopyIcon( ID_HELP_FAQ, ID_HELP_UPDATE );
01482         
01483         CoolInterface.CopyIcon( ID_HELP_FAQ, ID_HELP_WEB_1 );
01484         CoolInterface.CopyIcon( ID_HELP_FAQ, ID_HELP_WEB_2 );
01485         CoolInterface.CopyIcon( ID_HELP_FAQ, ID_HELP_WEB_3 );
01486         CoolInterface.CopyIcon( ID_HELP_FAQ, ID_HELP_WEB_4 );
01487         CoolInterface.CopyIcon( ID_HELP_FAQ, ID_HELP_WEB_5 );
01488         CoolInterface.CopyIcon( ID_HELP_FAQ, ID_HELP_WEB_6 );
01489         
01490         // Plugins
01491         
01492         Plugins.RegisterCommands();
01493 }
01494 
01495 void CSkin::Finalise()
01496 {
01497         m_brDialog.CreateSolidBrush( m_crDialog );
01498         
01499         if ( HBITMAP hPanelMark = GetWatermark( _T("CPanelWnd.Caption") ) )
01500         {
01501                 m_bmPanelMark.Attach( hPanelMark );
01502         }
01503         else if ( m_crPanelBack == RGB( 60, 60, 60 ) )
01504         {
01505                 m_bmPanelMark.LoadBitmap( IDB_PANEL_MARK );
01506         }
01507         
01508         CoolMenu.SetWatermark( GetWatermark( _T("CCoolMenu") ) );
01509         
01510         Plugins.OnSkinChanged();
01511 }
01512 
01514 // CSkin popup menu helper
01515 
01516 UINT CSkin::TrackPopupMenu(LPCTSTR pszMenu, const CPoint& point, UINT nDefaultID, UINT nFlags)
01517 {
01518         CMenu* pPopup = GetMenu( pszMenu );
01519         if ( pPopup == NULL ) return 0;
01520         
01521         if ( nDefaultID != 0 )
01522         {
01523                 MENUITEMINFO pInfo;
01524                 pInfo.cbSize    = sizeof(pInfo);
01525                 pInfo.fMask             = MIIM_STATE;
01526                 GetMenuItemInfo( pPopup->GetSafeHmenu(), nDefaultID, FALSE, &pInfo );
01527                 pInfo.fState    |= MFS_DEFAULT;
01528                 SetMenuItemInfo( pPopup->GetSafeHmenu(), nDefaultID, FALSE, &pInfo );
01529         }
01530         
01531         return pPopup->TrackPopupMenu( TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON|nFlags,
01532                 point.x, point.y, AfxGetMainWnd() );
01533 }
01534 
01536 // CSkin draw wrapped text
01537 
01538 // GetTextFlowChange determines the direction of text and its change 
01539 // at word boundaries.
01540 // Returns the direction of the first "words iceland" and the position
01541 // where the next "iceland" starts at the word boundary.
01542 // If there is no change in direction it returns 0.
01543 
01544 int CSkin::GetTextFlowChange(LPCTSTR pszText, BOOL* bIsRTL)
01545 {
01546         TRISTATE bTextIsRTL = TS_UNKNOWN;
01547         BOOL bChangeFound   = FALSE;
01548         unsigned short nLength = _tcslen( pszText );
01549         LPCTSTR pszWord = pszText;
01550         LPCTSTR pszScan = pszText;
01551 
01552         int nPos;
01553         for ( nPos = 0; ; pszScan++, nPos++ )
01554         {
01555                 // get the first word with punctuation marks and whitespaces
01556                 if ( (unsigned short)*pszScan > 32 && (unsigned short)*pszScan != 160 ) continue;
01557 
01558                 if ( pszWord < pszScan )
01559                 {
01560                         int nLen = pszScan - pszWord;
01561                         WORD* nCharType = new WORD[ nLen + 1 ];
01562 
01563                         TCHAR* pszTestWord = new TCHAR[ nLen + 1 ];
01564                         _tcsncpy( pszTestWord, pszWord, nLen );
01565                         pszTestWord[ nLen ] = 0;
01566 
01567                         GetStringTypeEx( LOCALE_NEUTRAL, CT_CTYPE2, pszTestWord, nLen + 1, (LPWORD)nCharType );
01568                         delete [] pszTestWord;
01569 
01570                         for ( int i = 0 ; i < nLen ; i++ )
01571                         {
01572                                 if ( nCharType[ i ] == C2_LEFTTORIGHT )
01573                                 {
01574                                         if ( bTextIsRTL == TS_UNKNOWN )
01575                                         {
01576                                                 bTextIsRTL = TS_FALSE;
01577                                                 *bIsRTL = FALSE;
01578                                         }
01579                                         else if ( bTextIsRTL == TS_TRUE )
01580                                         {
01581                                                 bChangeFound = TRUE;
01582                                                 break;
01583                                         }
01584                                 }
01585                                 else if ( nCharType[ i ] == C2_RIGHTTOLEFT )
01586                                 {
01587                                         if ( bTextIsRTL == TS_UNKNOWN )
01588                                         {
01589                                                 bTextIsRTL = TS_TRUE;
01590                                                 *bIsRTL = TRUE;
01591                                         }
01592                                         else if ( bTextIsRTL == TS_FALSE )
01593                                         {
01594                                                 bChangeFound = TRUE;
01595                                                 break;
01596                                         }
01597                                 }
01598                         }
01599                         BOOL bLeadingWhiteSpace = ( nCharType[ 0 ] == C2_WHITESPACE );
01600                         delete [] nCharType;
01601 
01602                         if ( bChangeFound ) return nPos - nLen + ( bLeadingWhiteSpace ? 1 : 0 );
01603                         pszWord = pszScan;
01604                 }
01605                 if ( ! *pszScan ) break;
01606         }
01607         return 0;
01608 }
01609 
01610 void CSkin::DrawWrappedText(CDC* pDC, CRect* pBox, LPCTSTR pszText, CPoint ptStart, BOOL bExclude)
01611 {
01612         // TODO: Wrap mixed text in RTL and LTR layouts correctly
01613 
01614         if ( pszText == NULL ) return;
01615         if ( ptStart.x == 0 && ptStart.y == 0 ) ptStart = pBox->TopLeft();
01616 
01617         UINT nAlignOptionsOld = pDC->GetTextAlign(); // backup settings
01618         UINT nFlags = ETO_CLIPPED | ( bExclude ? ETO_OPAQUE : 0 );
01619 
01620         unsigned short nLenFull = _tcslen( pszText );
01621 
01622         // Collect stats about the text from the start
01623         BOOL bIsRTLStart, bNormalFlow;
01624         int nTestStart  = GetTextFlowChange( pszText, &bIsRTLStart );
01625 
01626         // Guess text direction ( not always works )
01627         bNormalFlow = theApp.m_bRTL ? bIsRTLStart : !bIsRTLStart;
01628 
01629         TCHAR* pszSource = NULL;
01630         LPCTSTR pszWord  = NULL;
01631         LPCTSTR pszScan  = NULL;
01632 
01633         if ( nTestStart )
01634         {
01635                 // Get the source string to draw and truncate initial string to pass it recursively
01636                 pszSource = new TCHAR[ nTestStart + 1 ];
01637                 _tcsncpy( pszSource, pszText, nTestStart );
01638                 pszSource[ nTestStart ] = 0;
01639                 if ( !bNormalFlow )
01640                 {
01641                         // swap whitespaces
01642                         CString str = pszSource;
01643                         if ( pszSource[ 0 ] == ' ' || (unsigned short)pszSource[ 0 ] == 160 )
01644                         {
01645                                 str = str + _T(" ");
01646                                 str = str.Right( nTestStart );
01647                         }
01648                         else if ( pszSource[ nTestStart - 1 ] == ' ' || 
01649                                           (unsigned short)pszSource[ nTestStart - 1 ] == 160 )
01650                         {
01651                                 str = _T(" ") + str;
01652                                 str = str.Left( nTestStart );
01653                         }
01654                         _tcsncpy( pszSource, str.GetBuffer( nTestStart ), nTestStart );
01655                 }
01656                 nLenFull = nTestStart;
01657                 pszText += nTestStart;
01658         }
01659         else 
01660                 pszSource = (TCHAR*)pszText;
01661 
01662         pszWord = pszSource;
01663         pszScan = pszSource;
01664 
01665         if ( ! bNormalFlow ) 
01666         {
01667                 if ( bIsRTLStart != theApp.m_bRTL ) pDC->SetTextAlign( TA_RTLREADING );
01668                 pszScan += nLenFull - 1;
01669                 pszWord += nLenFull;
01670                 for ( int nEnd = nLenFull - 1; nEnd >= 0 ; nEnd-- )
01671                 {
01672                         if ( nEnd ) pszScan--;
01673                         if ( nEnd && (unsigned short)*pszScan > 32 && (unsigned short)*pszScan != 160 ) continue;
01674 
01675                         if ( pszWord >= pszScan )
01676                         {
01677                                 int nLen = pszWord - pszScan;
01678                                 CSize sz;
01679                                 GetTextExtentPoint32( pDC->m_hAttribDC, pszScan, nLen, &sz );
01680 
01681                                 if ( ptStart.x > pBox->left && ptStart.x + sz.cx > pBox->right )
01682                                 {
01683                                         ptStart.x = pBox->left;
01684                                         ptStart.y += sz.cy;
01685                                 }
01686 
01687                                 // Add extra point in x-axis; it cuts off the 1st word character otherwise
01688                                 const short nExtraPoint = ( theApp.m_bRTL ) ? 1 : 0;
01689                                 CRect rc( ptStart.x, ptStart.y, ptStart.x + sz.cx + nExtraPoint, ptStart.y + sz.cy );
01690                                 
01691                                 pDC->ExtTextOut( ptStart.x, ptStart.y, nFlags, &rc,
01692                                         pszScan, nLen, NULL );
01693                                 if ( bExclude ) pDC->ExcludeClipRect( &rc );
01694                                 
01695                                 ptStart.x += sz.cx + nExtraPoint;
01696                                 pBox->top = ptStart.y + sz.cy;
01697                         }
01698                         pszWord = pszScan;
01699                 }
01700         }
01701         else
01702         {
01703                 for ( ; ; pszScan++ )
01704                 {
01705                         if ( *pszScan != NULL && (unsigned short)*pszScan > 32 &&
01706                                  (unsigned short)*pszScan != 160 ) continue;
01707                         
01708                         if ( pszWord <= pszScan )
01709                         {
01710                                 int nLen = pszScan - pszWord + ( *pszScan ? 1 : 0 );
01711                                 CSize sz = pDC->GetTextExtent( pszWord, nLen );
01712 
01713                                 if ( ptStart.x > pBox->left && ptStart.x + sz.cx > pBox->right )
01714                                 {
01715                                         ptStart.x = pBox->left;
01716                                         ptStart.y += sz.cy;
01717                                 }
01718 
01719                                 // Add extra point in x-axis; it cuts off the 1st word character otherwise
01720                                 const short nExtraPoint = ( theApp.m_bRTL ) ? 1 : 0;
01721 
01722                                 CRect rc( ptStart.x, ptStart.y, ptStart.x + sz.cx + nExtraPoint, ptStart.y + sz.cy );
01723 
01724                                 pDC->ExtTextOut( ptStart.x, ptStart.y, nFlags, &rc,
01725                                         pszWord, nLen, NULL );
01726                                 if ( bExclude ) pDC->ExcludeClipRect( &rc );
01727                                 
01728                                 ptStart.x += sz.cx + nExtraPoint;
01729                                 pBox->top = ptStart.y + sz.cy;
01730                         }
01731 
01732                         pszWord = pszScan + 1;
01733                         if ( ! *pszScan ) break;
01734                 }
01735         }
01736         if ( nTestStart ) delete [] pszSource;
01737         // reset align options back
01738         pDC->SetTextAlign( nAlignOptionsOld );
01739         if ( nTestStart ) DrawWrappedText( pDC, pBox, pszText, ptStart, bExclude );
01740 }
01741 
01743 // CSkin load bitmap helper
01744 
01745 HBITMAP CSkin::LoadBitmap(CString& strName)
01746 {
01747         CImageServices pServices;
01748         CImageFile pFile( &pServices );
01749         int nPos = strName.Find( '$' );
01750         
01751         if ( nPos < 0 )
01752         {
01753                 pFile.LoadFromFile( strName );
01754         }
01755         else
01756         {
01757                 HINSTANCE hInstance = NULL;
01758                 UINT nID = 0;
01759                 
01760                 if ( _stscanf( strName.Left( nPos ), _T("%lu"), &hInstance ) != 1 ) return NULL;
01761                 if ( _stscanf( strName.Mid( nPos + 1 ), _T("%lu"), &nID ) != 1 ) return NULL;
01762                 
01763                 if ( LPCTSTR pszType = _tcsrchr( strName, '.' ) )
01764                 {
01765                         pszType ++;
01766                         pFile.LoadFromResource( hInstance, nID, pszType );
01767                 }
01768                 else
01769                 {
01770                         return (HBITMAP)LoadImage( hInstance, MAKEINTRESOURCE(nID), IMAGE_BITMAP, 0, 0, 0 );
01771                 }
01772         }
01773         
01774         return pFile.EnsureRGB() ? pFile.CreateBitmap() : NULL;
01775 }
01776 
01778 // CSkin mode suffixes
01779 
01780 LPCTSTR CSkin::m_pszModeSuffix[3][4] =
01781 {
01782         { _T(".Windowed"), _T(""), NULL, NULL },                        // Windowed
01783         { _T(".Tabbed"), _T(""), NULL, NULL },                          // Tabbed
01784         { _T(".Basic"), _T(".Tabbed"), _T(""), NULL }           // Basic
01785 };

Generated on Thu Dec 15 10:39:50 2005 for Shareaza 2.2.1.0 by  doxygen 1.4.2