Leaked source code of windows server 2003
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.

456 lines
8.8 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 = 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 = 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_CreateString(
  149. LPCWSTR pszText,
  150. DUI::Value **ppvString
  151. )
  152. {
  153. HRESULT hr = E_OUTOFMEMORY;
  154. HINSTANCE hInstance = NULL;
  155. if (IS_INTRESOURCE(pszText))
  156. {
  157. hInstance = HINST_THISDLL;
  158. }
  159. DUI::Value *pvString = DUI::Value::CreateString(pszText, hInstance);
  160. if (NULL != pvString)
  161. {
  162. *ppvString = pvString;
  163. hr = S_OK;
  164. }
  165. return THR(hr);
  166. }
  167. HRESULT
  168. CPL::Dui_SetElementText(
  169. DUI::Element *peElement,
  170. LPCWSTR pszText
  171. )
  172. {
  173. CPL::CDuiValuePtr pvString;
  174. HRESULT hr = CPL::Dui_CreateString(pszText, &pvString);
  175. if (SUCCEEDED(hr))
  176. {
  177. hr = CPL::Dui_SetElementProperty(peElement, ContentProp, pvString);
  178. }
  179. return THR(hr);
  180. }
  181. HRESULT
  182. CPL::Dui_SetDescendentElementText(
  183. DUI::Element *peElement,
  184. LPCWSTR pszDescendent,
  185. LPCWSTR pszText
  186. )
  187. {
  188. DUI::Element *peDescendent;
  189. HRESULT hr = CPL::Dui_FindDescendent(peElement, pszDescendent, &peDescendent);
  190. if (SUCCEEDED(hr))
  191. {
  192. hr = CPL::Dui_SetElementText(peDescendent, pszText);
  193. }
  194. return THR(hr);
  195. }
  196. //
  197. // Retrieve the width and height of an element.
  198. //
  199. HRESULT
  200. CPL::Dui_GetElementExtent(
  201. DUI::Element *pe,
  202. SIZE *pext
  203. )
  204. {
  205. HRESULT hr = E_FAIL;
  206. CPL::CDuiValuePtr pv;
  207. *pext = *(pe->GetExtent(&pv));
  208. if (!pv.IsNULL())
  209. {
  210. hr = S_OK;
  211. }
  212. return THR(hr);
  213. }
  214. HRESULT
  215. CPL::Dui_CreateGraphic(
  216. HICON hIcon,
  217. DUI::Value **ppValue
  218. )
  219. {
  220. HRESULT hr = E_OUTOFMEMORY;
  221. DUI::Value *pvGraphic;
  222. pvGraphic = DUI::Value::CreateGraphic(hIcon);
  223. if (NULL != pvGraphic)
  224. {
  225. *ppValue = pvGraphic;
  226. hr = S_OK;
  227. }
  228. return THR(hr);
  229. }
  230. HRESULT
  231. CPL::Dui_SetElementIcon(
  232. DUI::Element *pe,
  233. HICON hIcon
  234. )
  235. {
  236. CPL::CDuiValuePtr pvGraphic;
  237. HRESULT hr = CPL::Dui_CreateGraphic(hIcon, &pvGraphic);
  238. if (SUCCEEDED(hr))
  239. {
  240. hr = CPL::Dui_SetElementProperty(pe, ContentProp, pvGraphic);
  241. }
  242. return THR(hr);
  243. }
  244. HRESULT
  245. CPL::Dui_SetDescendentElementIcon(
  246. DUI::Element *peElement,
  247. LPCWSTR pszDescendent,
  248. HICON hIcon
  249. )
  250. {
  251. DUI::Element *peDescendent;
  252. HRESULT hr = CPL::Dui_FindDescendent(peElement, pszDescendent, &peDescendent);
  253. if (SUCCEEDED(hr))
  254. {
  255. hr = CPL::Dui_SetElementIcon(peDescendent, hIcon);
  256. }
  257. return THR(hr);
  258. }
  259. HRESULT
  260. CPL::Dui_GetElementRootHWND(
  261. DUI::Element *pe,
  262. HWND *phwnd
  263. )
  264. {
  265. HRESULT hr = E_FAIL;
  266. const HWND hwnd = ((DUI::HWNDElement *)pe->GetRoot())->GetHWND();
  267. if (NULL != hwnd)
  268. {
  269. hr = S_OK;
  270. }
  271. *phwnd = hwnd;
  272. return THR(hr);
  273. }
  274. HRESULT
  275. CPL::Dui_MapElementPointToRootHWND(
  276. DUI::Element *pe,
  277. const POINT& ptElement,
  278. POINT *pptRoot,
  279. HWND *phwndRoot // Optional. Default == NULL;
  280. )
  281. {
  282. HWND hwndRoot;
  283. HRESULT hr = CPL::Dui_GetElementRootHWND(pe, &hwndRoot);
  284. if (SUCCEEDED(hr))
  285. {
  286. pe->GetRoot()->MapElementPoint(pe, &ptElement, pptRoot);
  287. if (NULL != phwndRoot)
  288. {
  289. *phwndRoot = hwndRoot;
  290. }
  291. hr = S_OK;
  292. }
  293. return THR(hr);
  294. }
  295. void CALLBACK
  296. Dui_ParserErrorCallback(
  297. LPCWSTR pszError,
  298. LPCWSTR pszToken,
  299. int iLine
  300. )
  301. {
  302. WCHAR szBuffer[1024];
  303. if (-1 != iLine)
  304. {
  305. StringCchPrintfW(szBuffer, ARRAYSIZE(szBuffer), L"%s '%s' at line %d.", pszError, pszToken, iLine);
  306. }
  307. else
  308. {
  309. StringCchPrintfW(szBuffer, ARRAYSIZE(szBuffer), L"%s '%s'", pszError, pszToken);
  310. }
  311. MessageBoxW(NULL, szBuffer, L"DUI Parser Message", MB_OK | MB_ICONERROR);
  312. }
  313. HRESULT
  314. CPL::Dui_CreateParser(
  315. const char *pszUiFile,
  316. int cchUiFile,
  317. HINSTANCE hInstance,
  318. DUI::Parser **ppParser
  319. )
  320. {
  321. ASSERT(NULL != pszUiFile);
  322. ASSERT(!IsBadStringPtrA(pszUiFile, cchUiFile));
  323. ASSERT(NULL != ppParser);
  324. ASSERT(!IsBadWritePtr(ppParser, sizeof(*ppParser)));
  325. HRESULT hr = E_FAIL;
  326. DUI::Parser *pParser;
  327. HANDLE arHandles[2];
  328. arHandles[0] = hInstance;
  329. arHandles[1] = OpenThemeData(NULL, L"Scrollbar");
  330. DUI::Parser::Create(pszUiFile, cchUiFile, arHandles, Dui_ParserErrorCallback, &pParser);
  331. if (NULL != pParser)
  332. {
  333. if (!pParser->WasParseError())
  334. {
  335. hr = S_OK;
  336. }
  337. else
  338. {
  339. pParser->Destroy();
  340. pParser = NULL;
  341. }
  342. }
  343. else
  344. {
  345. hr = E_OUTOFMEMORY;
  346. }
  347. if (arHandles[1])
  348. {
  349. CloseThemeData (arHandles[1]);
  350. }
  351. *ppParser = pParser;
  352. return THR(hr);
  353. }
  354. //-----------------------------------------------------------------------------
  355. // CDuiValuePtr
  356. //-----------------------------------------------------------------------------
  357. CPL::CDuiValuePtr&
  358. CPL::CDuiValuePtr::operator = (
  359. const CDuiValuePtr& rhs
  360. )
  361. {
  362. if (this != &rhs)
  363. {
  364. Attach(rhs.Detach());
  365. }
  366. return *this;
  367. }
  368. void
  369. CPL::CDuiValuePtr::Attach(
  370. DUI::Value *pv
  371. )
  372. {
  373. _Release();
  374. m_pv = pv;
  375. m_bOwns = true;
  376. }
  377. DUI::Value *
  378. CPL::CDuiValuePtr::Detach(
  379. void
  380. ) const
  381. {
  382. DUI::Value *pv = m_pv;
  383. m_pv = NULL;
  384. m_bOwns = false;
  385. return pv;
  386. }
  387. void
  388. CPL::CDuiValuePtr::_Release(
  389. void
  390. )
  391. {
  392. if (NULL != m_pv && m_bOwns)
  393. {
  394. m_pv->Release();
  395. }
  396. }