Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

232 lines
6.3 KiB

  1. #include "stdafx.h"
  2. #pragma hdrstop
  3. class CResourceMap : public IResourceMap, IPersistFile
  4. {
  5. public:
  6. CResourceMap();
  7. ~CResourceMap();
  8. STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj);
  9. STDMETHODIMP_(ULONG) AddRef(void);
  10. STDMETHODIMP_(ULONG) Release(void);
  11. // IPersist
  12. STDMETHODIMP GetClassID(CLSID* pClassID)
  13. { *pClassID = CLSID_NULL; return S_OK; }
  14. // IPersistFile
  15. STDMETHODIMP IsDirty(void)
  16. { return S_FALSE; };
  17. STDMETHODIMP Load(LPCOLESTR pszFileName, DWORD dwMode);
  18. STDMETHODIMP Save(LPCOLESTR pszFileName, BOOL fRemember)
  19. { return S_OK; };
  20. STDMETHODIMP SaveCompleted(LPCOLESTR pszFileName)
  21. { return S_OK; };
  22. STDMETHODIMP GetCurFile(LPOLESTR *ppszFileName);
  23. // IResourceMap
  24. STDMETHODIMP LoadResourceMap(LPCTSTR pszClass, LPCTSTR pszID);
  25. STDMETHODIMP SelectResourceScope(LPCTSTR pszResourceType, LPCTSTR pszID, IXMLDOMNode **ppdn);
  26. STDMETHODIMP LoadBitmap(IXMLDOMNode *pdn, LPCTSTR pszID, HBITMAP *pbm);
  27. STDMETHODIMP LoadString(IXMLDOMNode *pdn, LPCTSTR pszID, LPTSTR pszBuffer, int cch);
  28. private:
  29. LONG _cRef;
  30. TCHAR _szMapURL[MAX_PATH];
  31. IXMLDOMNode *_pdnRsrcMap; // XML node which describes this wizard
  32. };
  33. CResourceMap::CResourceMap() :
  34. _cRef(1)
  35. {
  36. }
  37. CResourceMap::~CResourceMap()
  38. {
  39. ATOMICRELEASE(_pdnRsrcMap);
  40. }
  41. ULONG CResourceMap::AddRef()
  42. {
  43. return InterlockedIncrement(&_cRef);
  44. }
  45. ULONG CResourceMap::Release()
  46. {
  47. if (InterlockedDecrement(&_cRef))
  48. return _cRef;
  49. delete this;
  50. return 0;
  51. }
  52. HRESULT CResourceMap::QueryInterface(REFIID riid, void **ppv)
  53. {
  54. static const QITAB qit[] =
  55. {
  56. QITABENT(CResourceMap, IResourceMap), // IID_IResourceMap
  57. QITABENTMULTI(CResourceMap, IPersist, IPersistFile), // rare IID_IPersist
  58. QITABENT(CResourceMap, IPersistFile), // IID_IPersistFile
  59. {0, 0 },
  60. };
  61. return QISearch(this, qit, riid, ppv);
  62. }
  63. STDAPI CResourceMap_Initialize(LPCWSTR pszURL, IResourceMap **pprm)
  64. {
  65. CResourceMap *prm = new CResourceMap;
  66. if (!prm)
  67. return E_OUTOFMEMORY;
  68. // load from the URL we were given
  69. IPersistFile *ppf;
  70. HRESULT hr = prm->QueryInterface(IID_PPV_ARG(IPersistFile, &ppf));
  71. if (SUCCEEDED(hr))
  72. {
  73. hr = ppf->Load(pszURL, 0x0);
  74. ppf->Release();
  75. }
  76. // if that succeeded then lets get the IResourceMap for the caller
  77. if (SUCCEEDED(hr))
  78. hr = prm->QueryInterface(IID_PPV_ARG(IResourceMap, pprm));
  79. prm->Release();
  80. return hr;
  81. }
  82. // IPersistFile support
  83. HRESULT CResourceMap::Load(LPCOLESTR pszFileName, DWORD dwMode)
  84. {
  85. StrCpyN(_szMapURL, pszFileName, ARRAYSIZE(_szMapURL));
  86. ATOMICRELEASE(_pdnRsrcMap);
  87. return S_OK;
  88. }
  89. HRESULT CResourceMap::GetCurFile(LPOLESTR *ppszFileName)
  90. {
  91. HRESULT hr = E_FAIL;
  92. if (_szMapURL[0])
  93. {
  94. *ppszFileName = SysAllocString(_szMapURL);
  95. hr = *ppszFileName ? S_OK:E_OUTOFMEMORY;
  96. }
  97. return hr;
  98. }
  99. // IResourceMap support
  100. HRESULT CResourceMap::LoadResourceMap(LPCTSTR pszResourceClass, LPCTSTR pszID)
  101. {
  102. IXMLDOMDocument *pdocWizardDefn;
  103. HRESULT hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IXMLDOMDocument, &pdocWizardDefn));
  104. if (SUCCEEDED(hr))
  105. {
  106. ATOMICRELEASE(_pdnRsrcMap);
  107. VARIANT varName;
  108. hr = InitVariantFromStr(&varName, _szMapURL);
  109. if (SUCCEEDED(hr))
  110. {
  111. VARIANT_BOOL fSuccess;
  112. hr = pdocWizardDefn->load(varName, &fSuccess);
  113. if (hr == S_OK)
  114. {
  115. if (fSuccess == VARIANT_TRUE)
  116. {
  117. TCHAR szPath[MAX_PATH];
  118. wnsprintf(szPath, ARRAYSIZE(szPath), TEXT("resourcemap/%s[@id='%s']"), pszResourceClass, pszID);
  119. hr = pdocWizardDefn->selectSingleNode(szPath, &_pdnRsrcMap);
  120. }
  121. else
  122. {
  123. hr = E_FAIL;
  124. }
  125. }
  126. VariantClear(&varName);
  127. }
  128. pdocWizardDefn->Release();
  129. }
  130. return (SUCCEEDED(hr) && (hr != S_OK)) ? E_FAIL:hr;
  131. }
  132. HRESULT CResourceMap::SelectResourceScope(LPCTSTR pszResourceType, LPCTSTR pszID, IXMLDOMNode **ppdn)
  133. {
  134. TCHAR szPath[MAX_PATH];
  135. wnsprintf(szPath, ARRAYSIZE(szPath), TEXT("%s[@id='%s']"), pszResourceType, pszID);
  136. HRESULT hr = _pdnRsrcMap->selectSingleNode(szPath, ppdn);
  137. return (SUCCEEDED(hr) && (hr != S_OK)) ? E_FAIL:hr; // the call can return S_FALSE
  138. }
  139. HRESULT CResourceMap::LoadBitmap(IXMLDOMNode *pdn, LPCTSTR pszID, HBITMAP *phbm)
  140. {
  141. *phbm = NULL;
  142. TCHAR szPath[MAX_PATH];
  143. wnsprintf(szPath, ARRAYSIZE(szPath), TEXT("bitmap[@id='%s']"), pszID);
  144. IXMLDOMNode *pn;
  145. HRESULT hr = (pdn ? pdn:_pdnRsrcMap)->selectSingleNode(szPath, &pn);
  146. if (hr == S_OK)
  147. {
  148. VARIANT var;
  149. hr = pn->get_nodeTypedValue(&var);
  150. if (SUCCEEDED(hr))
  151. {
  152. TCHAR szPath[MAX_PATH];
  153. VariantToStr(&var, szPath, ARRAYSIZE(szPath));
  154. VariantClear(&var);
  155. INT idRes = PathParseIconLocation(szPath) * -1; // fix -ve resource ID
  156. HINSTANCE hinst = LoadLibrary(szPath);
  157. if (hinst)
  158. {
  159. *phbm = (HBITMAP)LoadImage(hinst, MAKEINTRESOURCE(idRes),IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
  160. FreeLibrary(hinst);
  161. }
  162. }
  163. pn->Release();
  164. }
  165. return *phbm ? S_OK:E_FAIL;;
  166. }
  167. HRESULT CResourceMap::LoadString(IXMLDOMNode *pdn, LPCTSTR pszID, LPTSTR pszBuffer, int cch)
  168. {
  169. TCHAR szPath[MAX_PATH];
  170. wnsprintf(szPath, ARRAYSIZE(szPath), TEXT("text[@id='%s']"), pszID);
  171. IXMLDOMNode *pn;
  172. HRESULT hr = (pdn ? pdn:_pdnRsrcMap)->selectSingleNode(szPath, &pn);
  173. if (hr == S_OK)
  174. {
  175. VARIANT var;
  176. hr = pn->get_nodeTypedValue(&var);
  177. if (SUCCEEDED(hr))
  178. {
  179. VariantToStr(&var, pszBuffer, cch);
  180. SHLoadIndirectString(pszBuffer, pszBuffer, cch, NULL);
  181. VariantClear(&var);
  182. }
  183. pn->Release();
  184. }
  185. // try global strings if this load fails
  186. if (((FAILED(hr)) || (hr != S_OK)) && (pdn != NULL))
  187. {
  188. hr = LoadString(NULL, pszID, pszBuffer, cch);
  189. }
  190. return (SUCCEEDED(hr) && (hr != S_OK)) ? E_FAIL:hr; // the call can return S_FALSE
  191. }