00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00047
00048 CSkin::CSkin()
00049 {
00050 }
00051
00052 CSkin::~CSkin()
00053 {
00054 Clear();
00055 }
00056
00058
00059
00060 void CSkin::Apply()
00061 {
00062 CreateDefault();
00063 ApplyRecursive( NULL );
00064 Finalise();
00065 }
00066
00068
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
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
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
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
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
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
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
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
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
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
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
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
00836
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
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
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(""") );
00906 pFile.Write( "\t<control caption=\"", 19 );
00907
00908
00909
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
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
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
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
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
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
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
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
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
01436
01437 void CSkin::CreateDefault()
01438 {
01439
01440
01441 Clear();
01442
01443 Settings.General.Language = _T("en");
01444
01445
01446
01447 CoolInterface.Clear();
01448 CoolInterface.CreateFonts();
01449 CoolInterface.CalculateColours( FALSE );
01450
01451
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
01463
01464 HICON hIcon = theApp.LoadIcon( IDI_CHECKMARK );
01465 CoolInterface.AddIcon( ID_CHECKMARK, theApp.m_bRTL ? CreateMirroredIcon( hIcon ) : hIcon );
01466
01467
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
01475
01476 LoadFromResource( NULL, IDR_XML_DEFINITIONS );
01477 LoadFromResource( NULL, IDR_XML_DEFAULT );
01478
01479
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
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
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
01537
01538
01539
01540
01541
01542
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
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
01613
01614 if ( pszText == NULL ) return;
01615 if ( ptStart.x == 0 && ptStart.y == 0 ) ptStart = pBox->TopLeft();
01616
01617 UINT nAlignOptionsOld = pDC->GetTextAlign();
01618 UINT nFlags = ETO_CLIPPED | ( bExclude ? ETO_OPAQUE : 0 );
01619
01620 unsigned short nLenFull = _tcslen( pszText );
01621
01622
01623 BOOL bIsRTLStart, bNormalFlow;
01624 int nTestStart = GetTextFlowChange( pszText, &bIsRTLStart );
01625
01626
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
01636 pszSource = new TCHAR[ nTestStart + 1 ];
01637 _tcsncpy( pszSource, pszText, nTestStart );
01638 pszSource[ nTestStart ] = 0;
01639 if ( !bNormalFlow )
01640 {
01641
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
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
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
01738 pDC->SetTextAlign( nAlignOptionsOld );
01739 if ( nTestStart ) DrawWrappedText( pDC, pBox, pszText, ptStart, bExclude );
01740 }
01741
01743
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
01779
01780 LPCTSTR CSkin::m_pszModeSuffix[3][4] =
01781 {
01782 { _T(".Windowed"), _T(""), NULL, NULL },
01783 { _T(".Tabbed"), _T(""), NULL, NULL },
01784 { _T(".Basic"), _T(".Tabbed"), _T(""), NULL }
01785 };