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.

525 lines
9.5 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 2000
  6. //
  7. // File: cpduihlp.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "shellprv.h"
  11. #include <uxtheme.h>
  12. #include "cpviewp.h"
  13. #include "cpduihlp.h"
  14. #include "cputil.h"
  15. HRESULT
  16. CPL::Dui_AddAtom(
  17. LPCWSTR pszName,
  18. ATOM *pAtom
  19. )
  20. {
  21. ASSERT(NULL != pszName);
  22. ASSERT(NULL != pAtom);
  23. ASSERT(!IsBadWritePtr(pAtom, sizeof(*pAtom)));
  24. HRESULT hr = S_OK;
  25. *pAtom = AddAtomW(pszName);
  26. if (0 == *pAtom)
  27. {
  28. hr = CPL::ResultFromLastError();
  29. }
  30. return THR(hr);
  31. }
  32. HRESULT
  33. CPL::Dui_DeleteAtom(
  34. ATOM atom
  35. )
  36. {
  37. HRESULT hr = S_OK;
  38. if (0 != atom)
  39. {
  40. if (0 != DeleteAtom(atom))
  41. {
  42. hr = CPL::ResultFromLastError();
  43. }
  44. }
  45. return THR(hr);
  46. }
  47. HRESULT
  48. CPL::Dui_AddOrDeleteAtoms(
  49. struct CPL::ATOMINFO *pAtomInfo,
  50. UINT cEntries,
  51. bool bAdd
  52. )
  53. {
  54. ASSERT(NULL != pAtomInfo);
  55. HRESULT hr = S_OK;
  56. for (UINT i = 0; i < cEntries && SUCCEEDED(hr); i++)
  57. {
  58. if (bAdd)
  59. {
  60. ASSERT(0 == *(pAtomInfo->pAtom));
  61. hr = Dui_AddAtom(pAtomInfo->pszName, pAtomInfo->pAtom);
  62. }
  63. else
  64. {
  65. if (0 != *(pAtomInfo->pAtom))
  66. {
  67. Dui_DeleteAtom(*(pAtomInfo->pAtom));
  68. }
  69. }
  70. pAtomInfo++;
  71. }
  72. return THR(hr);
  73. }
  74. HRESULT
  75. CPL::Dui_FindDescendent(
  76. DUI::Element *pe,
  77. LPCWSTR pszDescendent,
  78. DUI::Element **ppeDescendent
  79. )
  80. {
  81. HRESULT hr = E_FAIL;
  82. DUI::Element *peDescendent = pe->FindDescendent(DUI::StrToID(pszDescendent));
  83. if (NULL != peDescendent)
  84. {
  85. *ppeDescendent = peDescendent;
  86. hr = S_OK;
  87. }
  88. return THR(hr);
  89. }
  90. HRESULT
  91. CPL::Dui_DestroyDescendentElement(
  92. DUI::Element *pe,
  93. LPCWSTR pszDescendent
  94. )
  95. {
  96. HRESULT hr = E_FAIL;
  97. DUI::Element *peDescendent = pe->FindDescendent(DUI::StrToID(pszDescendent));
  98. if (NULL != peDescendent)
  99. {
  100. hr = peDescendent->Destroy();
  101. }
  102. return THR(hr);
  103. }
  104. HRESULT
  105. CPL::Dui_CreateElement(
  106. DUI::Parser *pParser,
  107. LPCWSTR pszTemplate,
  108. DUI::Element *peSubstitute,
  109. DUI::Element **ppe
  110. )
  111. {
  112. DUI::Element *pe = NULL;
  113. HRESULT hr = pParser->CreateElement(pszTemplate, peSubstitute, &pe);
  114. if (SUCCEEDED(hr))
  115. {
  116. //
  117. // ISSUE-2000/12/22-BrianAu DUI bug.
  118. // DUI::Parser::CreateElement will return S_OK if
  119. // the element doesn't exist. I've notified MarkFi
  120. // about the issue. I think he'll fix it.
  121. //
  122. if (NULL == pe)
  123. {
  124. ASSERT(0 && "DUI::Parser::CreateElement returned S_OK for non-existent element");
  125. hr = E_FAIL;
  126. }
  127. }
  128. *ppe = pe;
  129. return THR(hr);
  130. }
  131. HRESULT
  132. CPL::Dui_GetStyleSheet(
  133. DUI::Parser *pParser,
  134. LPCWSTR pszSheet,
  135. DUI::Value **ppvSheet
  136. )
  137. {
  138. HRESULT hr = E_FAIL;
  139. DUI::Value *pvSheet = pParser->GetSheet(pszSheet);
  140. if (NULL != pvSheet)
  141. {
  142. *ppvSheet = pvSheet;
  143. hr = S_OK;
  144. }
  145. return THR(hr);
  146. }
  147. HRESULT
  148. CPL::Dui_CreateElementWithStyle(
  149. DUI::Parser *pParser,
  150. LPCWSTR pszTemplate,
  151. LPCWSTR pszStyleSheet,
  152. DUI::Element **ppe
  153. )
  154. {
  155. HRESULT hr = CPL::Dui_CreateElement(pParser, pszTemplate, NULL, ppe);
  156. if (SUCCEEDED(hr))
  157. {
  158. CPL::CDuiValuePtr pvStyle;
  159. hr = CPL::Dui_GetStyleSheet(pParser, pszStyleSheet, &pvStyle);
  160. if (SUCCEEDED(hr))
  161. {
  162. hr = Dui_SetElementProperty(*ppe, SheetProp, pvStyle);
  163. }
  164. }
  165. return THR(hr);
  166. }
  167. HRESULT
  168. CPL::Dui_CreateString(
  169. LPCWSTR pszText,
  170. DUI::Value **ppvString
  171. )
  172. {
  173. HRESULT hr = E_OUTOFMEMORY;
  174. HINSTANCE hInstance = NULL;
  175. if (IS_INTRESOURCE(pszText))
  176. {
  177. hInstance = HINST_THISDLL;
  178. }
  179. DUI::Value *pvString = DUI::Value::CreateString(pszText, hInstance);
  180. if (NULL != pvString)
  181. {
  182. *ppvString = pvString;
  183. hr = S_OK;
  184. }
  185. return THR(hr);
  186. }
  187. HRESULT
  188. CPL::Dui_SetElementProperty_Int(
  189. DUI::Element *pe,
  190. DUI::PropertyInfo *ppi,
  191. int i
  192. )
  193. {
  194. HRESULT hr = E_OUTOFMEMORY;
  195. CPL::CDuiValuePtr pv = DUI::Value::CreateInt(i);
  196. if (!pv.IsNULL())
  197. {
  198. hr = CPL::Dui_SetValue(pe, ppi, pv);
  199. }
  200. return THR(hr);
  201. }
  202. HRESULT
  203. CPL::Dui_SetElementProperty_String(
  204. DUI::Element *pe,
  205. DUI::PropertyInfo *ppi,
  206. LPCWSTR psz
  207. )
  208. {
  209. HRESULT hr = E_OUTOFMEMORY;
  210. CPL::CDuiValuePtr pv = DUI::Value::CreateString(psz);
  211. if (!pv.IsNULL())
  212. {
  213. hr = CPL::Dui_SetValue(pe, ppi, pv);
  214. }
  215. return THR(hr);
  216. }
  217. HRESULT
  218. CPL::Dui_SetElementText(
  219. DUI::Element *peElement,
  220. LPCWSTR pszText
  221. )
  222. {
  223. CPL::CDuiValuePtr pvString;
  224. HRESULT hr = CPL::Dui_CreateString(pszText, &pvString);
  225. if (SUCCEEDED(hr))
  226. {
  227. hr = CPL::Dui_SetElementProperty(peElement, ContentProp, pvString);
  228. }
  229. return THR(hr);
  230. }
  231. HRESULT
  232. CPL::Dui_SetDescendentElementText(
  233. DUI::Element *peElement,
  234. LPCWSTR pszDescendent,
  235. LPCWSTR pszText
  236. )
  237. {
  238. DUI::Element *peDescendent;
  239. HRESULT hr = CPL::Dui_FindDescendent(peElement, pszDescendent, &peDescendent);
  240. if (SUCCEEDED(hr))
  241. {
  242. hr = CPL::Dui_SetElementText(peDescendent, pszText);
  243. }
  244. return THR(hr);
  245. }
  246. //
  247. // Retrieve the width and height of an element.
  248. //
  249. HRESULT
  250. CPL::Dui_GetElementExtent(
  251. DUI::Element *pe,
  252. SIZE *pext
  253. )
  254. {
  255. HRESULT hr = E_FAIL;
  256. CPL::CDuiValuePtr pv;
  257. *pext = *(pe->GetExtent(&pv));
  258. if (!pv.IsNULL())
  259. {
  260. hr = S_OK;
  261. }
  262. return THR(hr);
  263. }
  264. HRESULT
  265. CPL::Dui_CreateGraphic(
  266. HICON hIcon,
  267. DUI::Value **ppValue
  268. )
  269. {
  270. HRESULT hr = E_OUTOFMEMORY;
  271. DUI::Value *pvGraphic;
  272. pvGraphic = DUI::Value::CreateGraphic(hIcon);
  273. if (NULL != pvGraphic)
  274. {
  275. *ppValue = pvGraphic;
  276. hr = S_OK;
  277. }
  278. return THR(hr);
  279. }
  280. HRESULT
  281. CPL::Dui_SetElementIcon(
  282. DUI::Element *pe,
  283. HICON hIcon
  284. )
  285. {
  286. CPL::CDuiValuePtr pvGraphic;
  287. HRESULT hr = CPL::Dui_CreateGraphic(hIcon, &pvGraphic);
  288. if (SUCCEEDED(hr))
  289. {
  290. hr = CPL::Dui_SetElementProperty(pe, ContentProp, pvGraphic);
  291. }
  292. return THR(hr);
  293. }
  294. HRESULT
  295. CPL::Dui_SetDescendentElementIcon(
  296. DUI::Element *peElement,
  297. LPCWSTR pszDescendent,
  298. HICON hIcon
  299. )
  300. {
  301. DUI::Element *peDescendent;
  302. HRESULT hr = CPL::Dui_FindDescendent(peElement, pszDescendent, &peDescendent);
  303. if (SUCCEEDED(hr))
  304. {
  305. hr = CPL::Dui_SetElementIcon(peDescendent, hIcon);
  306. }
  307. return THR(hr);
  308. }
  309. HRESULT
  310. CPL::Dui_GetElementRootHWND(
  311. DUI::Element *pe,
  312. HWND *phwnd
  313. )
  314. {
  315. HRESULT hr = E_FAIL;
  316. const HWND hwnd = ((DUI::HWNDElement *)pe->GetRoot())->GetHWND();
  317. if (NULL != hwnd)
  318. {
  319. hr = S_OK;
  320. }
  321. *phwnd = hwnd;
  322. return THR(hr);
  323. }
  324. HRESULT
  325. CPL::Dui_MapElementPointToRootHWND(
  326. DUI::Element *pe,
  327. const POINT& ptElement,
  328. POINT *pptRoot,
  329. HWND *phwndRoot // Optional. Default == NULL;
  330. )
  331. {
  332. HWND hwndRoot;
  333. HRESULT hr = CPL::Dui_GetElementRootHWND(pe, &hwndRoot);
  334. if (SUCCEEDED(hr))
  335. {
  336. pe->GetRoot()->MapElementPoint(pe, &ptElement, pptRoot);
  337. if (NULL != phwndRoot)
  338. {
  339. *phwndRoot = hwndRoot;
  340. }
  341. hr = S_OK;
  342. }
  343. return THR(hr);
  344. }
  345. void CALLBACK
  346. Dui_ParserErrorCallback(
  347. LPCWSTR pszError,
  348. LPCWSTR pszToken,
  349. int iLine
  350. )
  351. {
  352. WCHAR szBuffer[1024];
  353. if (-1 != iLine)
  354. {
  355. wsprintfW(szBuffer, L"%s '%s' at line %d.", pszError, pszToken, iLine);
  356. }
  357. else
  358. {
  359. wsprintfW(szBuffer, L"%s '%s'", pszError, pszToken);
  360. }
  361. MessageBoxW(NULL, szBuffer, L"DUI Parser Message", MB_OK | MB_ICONERROR);
  362. }
  363. HRESULT
  364. CPL::Dui_CreateParser(
  365. const char *pszUiFile,
  366. int cchUiFile,
  367. HINSTANCE hInstance,
  368. DUI::Parser **ppParser
  369. )
  370. {
  371. ASSERT(NULL != pszUiFile);
  372. ASSERT(!IsBadStringPtrA(pszUiFile, cchUiFile));
  373. ASSERT(NULL != ppParser);
  374. ASSERT(!IsBadWritePtr(ppParser, sizeof(*ppParser)));
  375. HRESULT hr = E_FAIL;
  376. DUI::Parser *pParser;
  377. HANDLE arHandles[2];
  378. arHandles[0] = hInstance;
  379. arHandles[1] = OpenThemeData(NULL, L"Scrollbar");
  380. DUI::Parser::Create(pszUiFile, cchUiFile, arHandles, Dui_ParserErrorCallback, &pParser);
  381. if (NULL != pParser)
  382. {
  383. if (!pParser->WasParseError())
  384. {
  385. hr = S_OK;
  386. }
  387. else
  388. {
  389. pParser->Destroy();
  390. pParser = NULL;
  391. }
  392. }
  393. else
  394. {
  395. hr = E_OUTOFMEMORY;
  396. }
  397. if (arHandles[1])
  398. {
  399. CloseThemeData (arHandles[1]);
  400. }
  401. *ppParser = pParser;
  402. return THR(hr);
  403. }
  404. //-----------------------------------------------------------------------------
  405. // CDuiValuePtr
  406. //-----------------------------------------------------------------------------
  407. CPL::CDuiValuePtr&
  408. CPL::CDuiValuePtr::operator = (
  409. const CDuiValuePtr& rhs
  410. )
  411. {
  412. if (this != &rhs)
  413. {
  414. Attach(rhs.Detach());
  415. }
  416. return *this;
  417. }
  418. void
  419. CPL::CDuiValuePtr::Attach(
  420. DUI::Value *pv
  421. )
  422. {
  423. _Release();
  424. m_pv = pv;
  425. m_bOwns = true;
  426. }
  427. DUI::Value *
  428. CPL::CDuiValuePtr::Detach(
  429. void
  430. ) const
  431. {
  432. DUI::Value *pv = m_pv;
  433. m_pv = NULL;
  434. m_bOwns = false;
  435. return pv;
  436. }
  437. void
  438. CPL::CDuiValuePtr::_ReleaseAndReset(
  439. void
  440. )
  441. {
  442. _Release();
  443. m_pv = NULL;
  444. m_bOwns = false;
  445. }
  446. void
  447. CPL::CDuiValuePtr::_Release(
  448. void
  449. )
  450. {
  451. if (NULL != m_pv && m_bOwns)
  452. {
  453. m_pv->Release();
  454. }
  455. }