hxresmg.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:18k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include "hxcom.h"
  36. #include "hlxclib/stdio.h"
  37. #include "hlxclib/stdlib.h"
  38. #ifdef _WINDOWS
  39. #include <windows.h>
  40. #endif
  41. #if defined(_MACINTOSH) && !defined(_MAC_MACHO)
  42. #include <stat.h>
  43. #else
  44. #include "hlxclib/sys/stat.h"
  45. #endif
  46. #include "hxxrsmg.h"
  47. #include "hxplugn.h"
  48. #include "hxfiles.h"
  49. #include "hxcomm.h"
  50. #include "hxxres.h"
  51. #include "hxengin.h"
  52. #include "ihxpckts.h"
  53. #include "hxprefs.h"
  54. #include "hxmon.h"
  55. #include "hxslist.h"
  56. #include "hxstrutl.h"
  57. #include "chxpckts.h"
  58. #include "md5.h"
  59. #include "findfile.h"
  60. #include "hxresmg.h"
  61. #include "dllpath.h"
  62. #include "hxheap.h"
  63. #ifdef _DEBUG
  64. #undef HX_THIS_FILE
  65. static const char HX_THIS_FILE[] = __FILE__;
  66. #endif
  67. // IHXPreferences key defines
  68. #define EXT_RES_DIR "ExtResources"
  69. #define EXT_RES_DATA_KEY "ExternalResourcesData"
  70. #define FILE_INFO_KEY "FileInfo"
  71. #define CHECKSUM_KEY "XRSCheckSum"
  72. #define LANGUAGE_KEY "Language"
  73. #define LANG_ID_KEY "LangID"
  74. // for OS_SEPARATOR_CHAR and OS_SEPARATOR_STRING
  75. #include "hxdir.h"
  76. // static initializations
  77. #if !defined(HELIX_CONFIG_NOSTATICS)
  78. HXExternalResourceManager* HXExternalResourceManager::m_pResourceManager = NULL;
  79. #else
  80. #include "globals/hxglobals.h"
  81. const HXExternalResourceManager* const HXExternalResourceManager::m_pResourceManager = NULL;
  82. #endif
  83. // HXExternalResourceManager methods
  84. HXExternalResourceManager::HXExternalResourceManager(IUnknown* pContext):
  85.      m_lRefCount(0)
  86.     ,m_pResourceList(NULL)
  87.     ,m_pContext(pContext)
  88.     ,m_pHXXResPlugin(NULL)
  89.     ,m_ulLanguageID(0x0409)
  90.     ,m_pExternalResDir(NULL)
  91.     ,m_pPrefs(NULL)
  92.     ,m_pRegistry(NULL)
  93. {
  94.     if(m_pContext)
  95.     {
  96. m_pContext->AddRef();
  97.     }
  98.     Init();
  99. }
  100. HXExternalResourceManager::~HXExternalResourceManager()
  101. {
  102.     delete[] m_pExternalResDir;
  103.     if(m_pResourceList)
  104.     {
  105. CHXSimpleList::Iterator i = m_pResourceList->Begin();
  106. for (; i != m_pResourceList->End(); ++i)
  107. {
  108.     IHXXResFile* pRes = (IHXXResFile*)(*i);
  109.     pRes->Close();
  110.     pRes->Release();
  111. }
  112.     }
  113.     HX_DELETE(m_pResourceList);
  114.     HX_RELEASE(m_pPrefs);
  115.     HX_RELEASE(m_pRegistry);
  116.     HX_RELEASE(m_pContext);
  117.     HX_RELEASE(m_pHXXResPlugin);
  118. #if defined(HELIX_CONFIG_NOSTATICS)
  119.     HXExternalResourceManager*& m_pResourceManager =
  120. (HXExternalResourceManager*&)HXGlobalPtr::Get(
  121.     &HXExternalResourceManager::m_pResourceManager);
  122. #endif
  123.     m_pResourceManager = NULL;
  124. }
  125. HXExternalResourceManager*
  126. HXExternalResourceManager::Instance(IUnknown* pContext)
  127. {
  128. #if defined(HELIX_CONFIG_NOSTATICS)
  129.     HXExternalResourceManager*& m_pResourceManager =
  130. (HXExternalResourceManager*&)HXGlobalPtr::Get(
  131.     &HXExternalResourceManager::m_pResourceManager);
  132. #endif
  133.     if(!m_pResourceManager)
  134.     {
  135. m_pResourceManager = new HXExternalResourceManager(pContext);
  136.     }
  137.     if (m_pResourceManager)
  138.     {
  139. m_pResourceManager->AddRef();
  140.     }
  141.     return m_pResourceManager;
  142. }
  143. // IUnknown methods
  144. STDMETHODIMP 
  145. HXExternalResourceManager::QueryInterface(REFIID riid, void** ppvObj)
  146. {
  147.     QInterfaceList qiList[] =
  148.         {
  149.             { GET_IIDHANDLE(IID_IHXExternalResourceManager), (IHXExternalResourceManager*)this },
  150.             { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXExternalResourceManager*)this },
  151.         };
  152.     
  153.     return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  154. }
  155. STDMETHODIMP_(ULONG32) 
  156. HXExternalResourceManager::AddRef()
  157. {
  158.     return InterlockedIncrement(&m_lRefCount);
  159. }
  160. STDMETHODIMP_(ULONG32) 
  161. HXExternalResourceManager::Release()
  162. {
  163.     if (InterlockedDecrement(&m_lRefCount) > 0)
  164.     {
  165. return m_lRefCount;
  166.     }
  167.     delete this;
  168.     return 0;
  169. }
  170. // IHXExternalResourceManager methods
  171. STDMETHODIMP
  172. HXExternalResourceManager::Init()
  173. {
  174.     HX_RESULT rc = GetHXXResPlugin();
  175.     if(HXR_OK == rc)
  176.     {
  177. // get language and res directory preferences/reg entries
  178. if (HXR_OK == m_pContext->QueryInterface(IID_IHXPreferences,
  179. (void**)&m_pPrefs) &&
  180.     HXR_OK == m_pContext->QueryInterface(IID_IHXRegistry, 
  181. (void**)&m_pRegistry))
  182. {
  183.     IHXBuffer* pBuffer = NULL;
  184.     CHXString strTemp;
  185.     strTemp.Format("%s.%s",HXREGISTRY_PREFPROPNAME, "LangID");
  186.     if(HXR_OK == m_pRegistry->GetStrByName(strTemp, pBuffer))
  187.     {
  188. const char* pActualLangID = (const char*)pBuffer->GetBuffer();
  189. m_ulLanguageID = strtol(pActualLangID, NULL, 10);
  190. HX_RELEASE(pBuffer);
  191.     }
  192.             const char* pPath = NULL;
  193.             // Get the plugin directory from the Dll Access Paths
  194.             if (GetDLLAccessPath() &&
  195.                 (pPath = GetDLLAccessPath()->GetPath(DLLTYPE_PLUGIN)) &&
  196.                 *pPath)
  197.             {
  198.                 UINT32 ulBufLen = strlen(pPath) + 1 + strlen(EXT_RES_DIR) + 1;
  199.                 m_pExternalResDir = new char[ulBufLen];
  200.                 SafeStrCpy(m_pExternalResDir, pPath, ulBufLen);
  201.                 if (m_pExternalResDir[strlen(m_pExternalResDir)-1] != OS_SEPARATOR_CHAR)
  202.                 {
  203.                     SafeStrCat(m_pExternalResDir, OS_SEPARATOR_STRING, ulBufLen);
  204.                 }
  205.                 SafeStrCat(m_pExternalResDir, EXT_RES_DIR, ulBufLen);
  206.                 rc = LoadResourceFiles();
  207.             }
  208. }
  209.     }
  210.     return rc;
  211. }
  212. STDMETHODIMP
  213. HXExternalResourceManager::CreateExternalResourceReader(
  214.     const char* pShortName,
  215.     REF(IHXExternalResourceReader*) pReader)
  216. {
  217.     HX_RESULT rc = HXR_OK;
  218.     HXExternalResourceReader* pHXReader = new HXExternalResourceReader(this);
  219.     if(!pHXReader)
  220.     {
  221. return HXR_OUTOFMEMORY;
  222.     }
  223.     pHXReader->AddRef();
  224.     pHXReader->Init(pShortName, m_pResourceList);
  225.     pReader = pHXReader;
  226.     return rc;
  227. }
  228. // HXExternalResourceManager private methods
  229. HX_RESULT
  230. HXExternalResourceManager::GetHXXResPlugin()
  231. {
  232.     HX_RESULT rc = HXR_FAILED;
  233.     IUnknown* pUnk = NULL;
  234.     IUnknown* pUnknownInstance = NULL;
  235.     IHXCommonClassFactory* pCommonClassFactory = NULL;
  236.     IHXPluginGroupEnumerator* pGroupEnumerator = NULL;
  237.     UINT32 ulNumPlugins = 0;
  238.     // enumerate the plugins
  239.     if (HXR_OK != m_pContext->QueryInterface(
  240. IID_IHXCommonClassFactory,
  241. (void**)&pCommonClassFactory))
  242.     {
  243. goto cleanup;
  244.     }
  245.     if (HXR_OK != pCommonClassFactory->CreateInstance(
  246. CLSID_IHXPluginGroupEnumerator,
  247. (void**)&pUnk))
  248.     {
  249. goto cleanup;
  250.     }
  251.     if (HXR_OK != pUnk->QueryInterface(IID_IHXPluginGroupEnumerator,
  252.     (void**)&pGroupEnumerator))
  253.     {
  254. goto cleanup;
  255.     }
  256.     if (HXR_OK != pGroupEnumerator->Init(IID_IHXXResFile))
  257.     {
  258. goto cleanup;
  259.     }
  260.     ulNumPlugins = pGroupEnumerator->GetNumOfPlugins();
  261.     if(ulNumPlugins > 0)
  262.     {
  263. if (HXR_OK == pGroupEnumerator->GetPlugin(0, pUnknownInstance))
  264. {
  265.     m_pHXXResPlugin = pUnknownInstance;
  266.     m_pHXXResPlugin->AddRef();
  267.     rc = HXR_OK;
  268. }
  269.     }
  270. cleanup:
  271.     HX_RELEASE(pUnk);
  272.     HX_RELEASE(pUnknownInstance);
  273.     HX_RELEASE(pCommonClassFactory);
  274.     HX_RELEASE(pGroupEnumerator);
  275.     return rc;
  276. }
  277. BOOL
  278. HXExternalResourceManager::ContainsCurrentLanguage(IHXXResFile* pResFile)
  279. {
  280.     BOOL rc = FALSE;
  281.     if(!pResFile)
  282.     {
  283. return rc;
  284.     }
  285.     UINT32 ulLangID = 0;
  286.     BOOL bFound = FALSE;
  287.     rc = pResFile->GetFirstResourceLanguage(ulLangID);
  288.     while(HXR_OK == rc)
  289.     {
  290. if(m_ulLanguageID == ulLangID)
  291. {
  292.     rc = TRUE;
  293.     break;
  294. }
  295. rc = pResFile->GetNextResourceLanguage(ulLangID);
  296.     };
  297.     return rc;
  298. }
  299. IHXXResFile*
  300. HXExternalResourceManager::MakeResFileObject(const char* pPath)
  301. {
  302.     IHXXResFile* pResFile = NULL;
  303.     if(m_pHXXResPlugin &&
  304. HXR_OK == m_pHXXResPlugin->QueryInterface(IID_IHXXResFile, 
  305. (void**)&pResFile))
  306.     {
  307. HX_RESULT rc = HXR_OK;
  308. // open res file and see if it contains any resources with the
  309. // current language ID
  310. pResFile->Open(pPath);
  311. if(ContainsCurrentLanguage(pResFile))
  312. {
  313.     pResFile->SetLanguage(m_ulLanguageID);
  314. }
  315. else
  316. {
  317.     HX_RELEASE(pResFile);   // don't want this one
  318. }
  319.     }
  320.     return pResFile;
  321. }
  322. HX_RESULT
  323. HXExternalResourceManager::Stat(const char* pPath, struct stat* pStatBuffer)
  324. {
  325.     HX_RESULT rc = HXR_OK;
  326.     memset(pStatBuffer,0,sizeof(*pStatBuffer));
  327.     if(stat((const char*)pPath, pStatBuffer) < 0)
  328.     {
  329. rc = HXR_FAIL;
  330.     }
  331.     return rc;
  332. }
  333. IHXBuffer* 
  334. HXExternalResourceManager::ConvertToAsciiString(char* pBuffer, UINT32 nBuffLen)
  335. {
  336.     char* pOut = new char[nBuffLen*2+1];
  337.     char* pStartOut = pOut;
  338.     char Nibble;
  339.     IHXBuffer* pOutBuffer = new CHXBuffer;
  340.     pOutBuffer->AddRef();
  341.     for (int i = 0; i < (int)nBuffLen; i++)
  342.     {
  343. Nibble = (*pBuffer >> 4) & 15;
  344. *pOut= (Nibble > 9 ) ? Nibble + 55 : Nibble + 48;
  345. pOut++;
  346. Nibble = *pBuffer & 15;
  347. *pOut= (Nibble > 9 ) ? Nibble + 55 : Nibble + 48;
  348. pOut++;
  349. pBuffer++;
  350.     }
  351.     *pOut = 0;
  352.     pOutBuffer->Set((UCHAR*)pStartOut, strlen(pStartOut)+1);
  353.     delete[] pStartOut;
  354.     return pOutBuffer;
  355. }
  356. IHXBuffer* 
  357. HXExternalResourceManager::ChecksumFile(const char* pPath)
  358. {
  359.     struct stat     stat_struct;
  360.     md5_state_t     MD5_data;
  361.     UCHAR     tempbuf[16];
  362.     md5_init(&MD5_data);
  363.     if (HXR_OK != Stat(pPath, &stat_struct))
  364.     {
  365.         md5_finish(tempbuf, &MD5_data);
  366. return NULL;
  367.     } 
  368.     md5_append(&MD5_data,(UCHAR*)&(stat_struct),sizeof(stat_struct)); 
  369.     md5_finish(tempbuf, &MD5_data);
  370.     return ConvertToAsciiString((char*)tempbuf, sizeof(tempbuf));
  371. }
  372. HX_RESULT
  373. HXExternalResourceManager::SaveFileInfo(const char* pFileName,
  374.          const char* pPath)
  375. {
  376.     HX_RESULT rc = HXR_OK;
  377.    // set/reset cache info
  378.     if(!m_pPrefs)
  379.     {
  380. return HXR_FAIL;
  381.     }
  382.     IHXBuffer* pStatInfo = ChecksumFile(pPath);
  383.     if(pStatInfo)
  384.     {
  385. CHXString prefString;
  386. prefString.Format("%s\%s\%s\%s",
  387.     EXT_RES_DATA_KEY,
  388.     FILE_INFO_KEY,
  389.     pFileName,
  390.     CHECKSUM_KEY);
  391. m_pPrefs->WritePref(prefString, pStatInfo);
  392. HX_RELEASE(pStatInfo);
  393.     }
  394.     // now write out the langages supported in the resource file
  395.     IHXXResFile* pResFile;
  396.     if(HXR_OK == m_pHXXResPlugin->QueryInterface(IID_IHXXResFile, 
  397. (void**)&pResFile))
  398.     {
  399. HX_RESULT rc = HXR_OK;
  400. // open res file and iterate through all of the languages
  401. // it supports
  402. pResFile->Open(pPath);
  403. UINT32 ulLangID = 0;
  404. rc = pResFile->GetFirstResourceLanguage(ulLangID);
  405. while(HXR_OK == rc)
  406. {
  407.     CHXString prefString;
  408.     IHXBuffer* pBuffer = new CHXBuffer;
  409.     prefString.Format("%s\%s\%s\%s\%ld",
  410. EXT_RES_DATA_KEY,
  411. FILE_INFO_KEY,
  412. pFileName,
  413. LANGUAGE_KEY,
  414. ulLangID);
  415.     pBuffer->Set((BYTE*)"", 1);
  416.     m_pPrefs->WritePref(prefString, pBuffer);
  417.     HX_RELEASE(pBuffer);
  418.     rc = pResFile->GetNextResourceLanguage(ulLangID);
  419. };
  420. HX_RELEASE(pResFile);
  421.     }
  422.     return rc;
  423. }
  424. HX_RESULT
  425. HXExternalResourceManager::LoadResourceFile(const char* pPath)
  426. {
  427.     HX_RESULT rc = HXR_OK;
  428.     // MakeResFileObject only returns an IHXXResFile
  429.     // if there are any resources in the current language
  430.     IHXXResFile* pResFile = MakeResFileObject(pPath);
  431.     if (pResFile)
  432.     {
  433. if(!m_pResourceList)
  434. {
  435.     m_pResourceList = new CHXSimpleList;
  436. }
  437.      m_pResourceList->AddTail(pResFile);
  438.     }
  439.     return rc;
  440. }
  441. BOOL
  442. HXExternalResourceManager::FileInfoCurrent(const char* pFileName, 
  443.     const char* pPath)
  444. {
  445.     BOOL rc = FALSE;
  446.     IHXBuffer* pStatInfo = ChecksumFile(pPath);
  447.     if(pStatInfo)
  448.     {
  449. IHXBuffer* pPrefValue = NULL;
  450. CHXString prefString;
  451. prefString.Format("%s\%s\%s\%s",
  452.     EXT_RES_DATA_KEY,
  453.     FILE_INFO_KEY,
  454.     pFileName,
  455.     CHECKSUM_KEY);
  456. if(HXR_OK == m_pPrefs->ReadPref(prefString, pPrefValue) &&
  457.     pPrefValue)
  458. {
  459.     const char* pActualPrefValue = (const char*)pPrefValue->GetBuffer();
  460.     const char* pActualStatInfo = (const char*)pStatInfo->GetBuffer();
  461.     if(strcmp(pActualPrefValue, pActualStatInfo) == 0)
  462.     {
  463. rc = TRUE;
  464.     }
  465.     HX_RELEASE(pPrefValue);
  466. }
  467. HX_RELEASE(pStatInfo);
  468.     }
  469.     return rc;
  470. }
  471. BOOL
  472. HXExternalResourceManager::ContainsCurrentLanguage(const char* pFileName,
  473.    const char* pPath)
  474. {
  475. #if defined (_MACINTOSH) || defined (_UNIX)
  476.     /* Temporary - Mac Installer does not write this pref yet -- XXXRA */
  477.     return TRUE;
  478. #endif
  479.     BOOL rc = FALSE;
  480.     IHXBuffer* pLangInfo = NULL;
  481.     CHXString prefString;
  482.     prefString.Format("%s\%s\%s\%s\%ld",
  483. EXT_RES_DATA_KEY,
  484. FILE_INFO_KEY,
  485. pFileName,
  486. LANGUAGE_KEY,
  487. m_ulLanguageID);
  488.     if(HXR_OK == m_pPrefs->ReadPref(prefString, pLangInfo))
  489.     {
  490. rc = TRUE;
  491. HX_RELEASE(pLangInfo);
  492.     }
  493.     return rc;
  494. }
  495. HX_RESULT
  496. HXExternalResourceManager::LoadResourceFiles()
  497. {
  498.     CFindFile* pFileFinder = NULL;
  499.     char* pResFile = NULL;
  500.     const char* pFileExtension = "*.xrs";
  501.     HX_RESULT   rc = HXR_OK;
  502.     // find plugins with specified pattern
  503.     pFileFinder = CFindFile::CreateFindFile(m_pExternalResDir, 0, 
  504.     pFileExtension);
  505.     if (NULL == pFileFinder)
  506.     {
  507. rc = HXR_FAIL;
  508. goto cleanup;
  509.     }
  510.     // collect plugin info.
  511.     pResFile = pFileFinder->FindFirst();
  512.     while (pResFile)
  513.     {
  514. BOOL bLoadFile = FALSE;
  515. const char* pResPath = pFileFinder->GetCurFilePath();
  516. // only load the file if it has resources that reflect
  517. // the current system language ID
  518. if(!FileInfoCurrent(pResFile, pResPath))
  519. {
  520.     SaveFileInfo(pResFile, pResPath);
  521. }
  522.     
  523. if(ContainsCurrentLanguage(pResFile, pResPath))
  524. {
  525.     rc = LoadResourceFile(pResPath);
  526. }
  527. if(HXR_OK != rc)
  528. {
  529.     // error - log it and keep on?
  530. }
  531. pResFile = pFileFinder->FindNext();
  532.     }
  533.     delete pFileFinder;
  534. cleanup:
  535.     return rc;
  536. }
  537. // HXExternalResourceReader methods
  538. HXExternalResourceReader::HXExternalResourceReader(
  539.      HXExternalResourceManager* pMgr):
  540.      m_lRefCount(0)
  541.     ,m_pResManager(pMgr)
  542.     ,m_pResourceList(NULL)
  543.     ,m_pDefaultRes(NULL)
  544. {
  545. }
  546. HXExternalResourceReader::~HXExternalResourceReader()
  547. {
  548.     HX_DELETE(m_pResourceList);
  549.     HX_RELEASE(m_pDefaultRes);
  550. }
  551. // IUnknown methods
  552. STDMETHODIMP 
  553. HXExternalResourceReader::QueryInterface(REFIID riid, void** ppvObj)
  554. {
  555.     QInterfaceList qiList[] =
  556.         {
  557.             { GET_IIDHANDLE(IID_IHXExternalResourceReader), (IHXExternalResourceReader*)this },
  558.             { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXExternalResourceReader*)this },
  559.         };
  560.     
  561.     return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  562. }
  563. STDMETHODIMP_(ULONG32) 
  564. HXExternalResourceReader::AddRef()
  565. {
  566.     return InterlockedIncrement(&m_lRefCount);
  567. }
  568. STDMETHODIMP_(ULONG32) 
  569. HXExternalResourceReader::Release()
  570. {
  571.     if (InterlockedDecrement(&m_lRefCount) > 0)
  572.     {
  573. return m_lRefCount;
  574.     }
  575.     delete this;
  576.     return 0;
  577. }
  578. STDMETHODIMP
  579. HXExternalResourceReader::SetDefaultResourceFile(
  580.     const char* pResourcePath)
  581. {
  582.     HX_RESULT rc = HXR_OK;
  583.     m_pDefaultRes = m_pResManager->MakeResFileObject(pResourcePath);
  584.     return rc;
  585. }
  586. IHXXResource*
  587. HXExternalResourceReader::GetResource(IHXXResFile* pResFile,
  588.        UINT32 ulResourceType,
  589.        UINT32 ulResourceID)
  590. {
  591.     IHXXResource* pRes = NULL;
  592.     switch(ulResourceType)
  593.     {
  594. case HX_RT_STRING:
  595. {
  596.     pRes = pResFile->GetString(ulResourceID);
  597. }
  598. break;
  599. case HX_RT_DIALOG:
  600. {
  601.     pRes = pResFile->GetDialog(ulResourceID);
  602. }
  603. break;
  604. case HX_RT_BITMAP:
  605. {
  606.     pRes = pResFile->GetBitmap(ulResourceID);
  607. }
  608. break;
  609. default:
  610. break;
  611.     }
  612.     return pRes;
  613. }
  614. STDMETHODIMP_(IHXXResource*)
  615. HXExternalResourceReader::GetResource(UINT32 ulResourceType,
  616.     UINT32 ulResourceID)
  617. {
  618.     IHXXResource* pRes = NULL;
  619.     if(m_pResourceList)
  620.     {
  621. CHXSimpleList::Iterator i = m_pResourceList->Begin();
  622. for (; i != m_pResourceList->End(); ++i)
  623. {
  624.     IHXXResFile* pResFile = (IHXXResFile*)(*i);
  625.     pRes = GetResource(pResFile, ulResourceType, ulResourceID);
  626.     if(pRes)
  627.     {
  628. break;
  629.     }
  630. }
  631.     }
  632.     if(!pRes &&
  633. m_pDefaultRes) // check default
  634.     {
  635. pRes = GetResource(m_pDefaultRes, ulResourceType, ulResourceID);
  636.     }
  637.     return pRes;
  638. }
  639. HX_RESULT
  640. HXExternalResourceReader::Init(const char* pShortName,
  641. CHXSimpleList* pResList)
  642. {
  643.     HX_RESULT rc = HXR_OK;
  644.     if(pResList)
  645.     {
  646. CHXSimpleList::Iterator i = pResList->Begin();
  647. for (; i != pResList->End(); ++i)
  648. {
  649.     IHXXResFile* pResFile = (IHXXResFile*)(*i);
  650.     if(pResFile->IncludesShortName(pShortName))
  651.     {
  652. if(!m_pResourceList)
  653. {
  654.     m_pResourceList = new CHXSimpleList;
  655. }
  656. m_pResourceList->AddTail(pResFile);
  657.     }
  658. }
  659.     }
  660.     return rc;
  661. }