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.

477 lines
13 KiB

  1. /*****************************************************************************\
  2. FILE: appStyle.cpp
  3. DESCRIPTION:
  4. This is the Autmation Object to theme scheme object.
  5. BryanSt 4/3/2000 (Bryan Starbuck)
  6. Copyright (C) Microsoft Corp 2000-2000. All rights reserved.
  7. \*****************************************************************************/
  8. #include "priv.h"
  9. #include <cowsite.h>
  10. #include <atlbase.h>
  11. #include "util.h"
  12. #include "theme.h"
  13. #include "appsize.h"
  14. #include "appstyle.h"
  15. //===========================
  16. // *** Class Internals & Helpers ***
  17. //===========================
  18. HRESULT CAppearanceStyle::_getSizeByIndex(IN long nIndex, OUT IThemeSize ** ppThemeSize)
  19. {
  20. HRESULT hr = E_INVALIDARG;
  21. if (ppThemeSize)
  22. {
  23. HKEY hKeyStyle;
  24. *ppThemeSize = NULL;
  25. hr = HrRegOpenKeyEx(m_hKeyStyle, NULL, 0, (KEY_WRITE | KEY_READ), &hKeyStyle); // Clone the key.
  26. if (SUCCEEDED(hr))
  27. {
  28. HKEY kKeySizes;
  29. hr = HrRegCreateKeyEx(m_hKeyStyle, SZ_REGKEY_SIZES, 0, NULL, REG_OPTION_NON_VOLATILE, (KEY_WRITE | KEY_READ), NULL, &kKeySizes, NULL);
  30. if (SUCCEEDED(hr))
  31. {
  32. HKEY kKeyTheSize;
  33. TCHAR szKeyName[MAXIMUM_SUB_KEY_LENGTH];
  34. StringCchPrintf(szKeyName, ARRAYSIZE(szKeyName), TEXT("%d"), nIndex);
  35. hr = HrRegOpenKeyEx(kKeySizes, szKeyName, 0, (KEY_WRITE | KEY_READ), &kKeyTheSize);
  36. if (SUCCEEDED(hr))
  37. {
  38. hr = CAppearanceSize_CreateInstance(hKeyStyle, kKeyTheSize, ppThemeSize); // This function takes ownership of hKeyStyle and kKeyTheSize
  39. }
  40. RegCloseKey(kKeySizes);
  41. }
  42. if (FAILED(hr))
  43. {
  44. RegCloseKey(hKeyStyle);
  45. }
  46. }
  47. }
  48. return hr;
  49. }
  50. #define SZ_APPEARANCE_SCHEME_NAME L"NoVisualStyle"
  51. //===========================
  52. // *** ITheme Interface ***
  53. //===========================
  54. HRESULT CAppearanceStyle::get_DisplayName(OUT BSTR * pbstrDisplayName)
  55. {
  56. HRESULT hr = E_INVALIDARG;
  57. if (pbstrDisplayName)
  58. {
  59. CComBSTR bstrDisplayName;
  60. *pbstrDisplayName = NULL;
  61. hr = HrBStrRegQueryValue(m_hKeyStyle, SZ_REGVALUE_DISPLAYNAME, &bstrDisplayName);
  62. if (SUCCEEDED(hr))
  63. {
  64. WCHAR szDisplayName[MAX_PATH];
  65. if (SUCCEEDED(SHLoadIndirectString(bstrDisplayName, szDisplayName, ARRAYSIZE(szDisplayName), NULL)))
  66. {
  67. hr = HrSysAllocStringW(szDisplayName, pbstrDisplayName);
  68. }
  69. else
  70. {
  71. hr = HrSysAllocStringW(bstrDisplayName, pbstrDisplayName);
  72. }
  73. }
  74. }
  75. return hr;
  76. }
  77. HRESULT CAppearanceStyle::put_DisplayName(IN BSTR bstrDisplayName)
  78. {
  79. return HrRegSetValueString(m_hKeyStyle, NULL, SZ_REGVALUE_DISPLAYNAME, bstrDisplayName);
  80. }
  81. HRESULT CAppearanceStyle::get_Name(OUT BSTR * pbstrName)
  82. {
  83. // This will be connonical. And it will be language independent if it is one that
  84. // we could upgrade to MUI compat strings.
  85. return HrBStrRegQueryValue(m_hKeyStyle, SZ_REGVALUE_DISPLAYNAME, pbstrName);
  86. }
  87. HRESULT CAppearanceStyle::put_Name(IN BSTR bstrName)
  88. {
  89. return E_NOTIMPL;
  90. }
  91. HRESULT CAppearanceStyle::get_length(OUT long * pnLength)
  92. {
  93. HRESULT hr = E_INVALIDARG;
  94. if (pnLength)
  95. {
  96. HKEY hKeyStyle;
  97. *pnLength = 0;
  98. hr = HrRegOpenKeyEx(m_hKeyStyle, SZ_REGKEY_SIZES, 0, KEY_READ, &hKeyStyle);
  99. if (SUCCEEDED(hr))
  100. {
  101. DWORD dwValues = 0;
  102. hr = HrRegQueryInfoKey(hKeyStyle, NULL, NULL, NULL, &dwValues, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
  103. *pnLength = (long) dwValues;
  104. RegCloseKey(hKeyStyle);
  105. }
  106. }
  107. return hr;
  108. }
  109. HRESULT CAppearanceStyle::get_item(IN VARIANT varIndex, OUT IThemeSize ** ppThemeSize)
  110. {
  111. HRESULT hr = E_INVALIDARG;
  112. if (ppThemeSize)
  113. {
  114. long nCount = 0;
  115. get_length(&nCount);
  116. *ppThemeSize = NULL;
  117. // This is sortof gross, but if we are passed a pointer to another variant, simply
  118. // update our copy here...
  119. if (varIndex.vt == (VT_BYREF | VT_VARIANT) && varIndex.pvarVal)
  120. varIndex = *(varIndex.pvarVal);
  121. switch (varIndex.vt)
  122. {
  123. case VT_I2:
  124. varIndex.lVal = (long)varIndex.iVal;
  125. // And fall through...
  126. case VT_I4:
  127. if ((varIndex.lVal >= 0) && (varIndex.lVal < nCount))
  128. {
  129. hr = _getSizeByIndex(varIndex.lVal, ppThemeSize);
  130. }
  131. break;
  132. case VT_BSTR:
  133. if (varIndex.bstrVal)
  134. {
  135. for (int nIndex = 0; FAILED(hr) && (nIndex < nCount); nIndex++)
  136. {
  137. IThemeSize * pThemeSize;
  138. if (SUCCEEDED(_getSizeByIndex(nIndex, &pThemeSize)))
  139. {
  140. CComBSTR bstrDisplayName;
  141. if (SUCCEEDED(pThemeSize->get_DisplayName(&bstrDisplayName)))
  142. {
  143. if (!StrCmpIW(bstrDisplayName, varIndex.bstrVal))
  144. {
  145. // They match, so this is the one.
  146. *ppThemeSize = pThemeSize;
  147. pThemeSize = NULL;
  148. hr = S_OK;
  149. }
  150. }
  151. if (FAILED(hr))
  152. {
  153. if (bstrDisplayName)
  154. {
  155. bstrDisplayName.Empty();
  156. }
  157. if (SUCCEEDED(pThemeSize->get_Name(&bstrDisplayName)))
  158. {
  159. if (!StrCmpIW(bstrDisplayName, varIndex.bstrVal))
  160. {
  161. // They match, so this is the one.
  162. *ppThemeSize = pThemeSize;
  163. pThemeSize = NULL;
  164. hr = S_OK;
  165. }
  166. }
  167. }
  168. ATOMICRELEASE(pThemeSize);
  169. }
  170. }
  171. }
  172. break;
  173. default:
  174. hr = E_NOTIMPL;
  175. }
  176. }
  177. return hr;
  178. }
  179. HRESULT CAppearanceStyle::get_SelectedSize(OUT IThemeSize ** ppThemeSize)
  180. {
  181. HRESULT hr = E_INVALIDARG;
  182. if (ppThemeSize)
  183. {
  184. HKEY hKeyStyle;
  185. *ppThemeSize = NULL;
  186. AssertMsg((NULL != m_hKeyStyle), TEXT("If this isn't set, then someone didn't construct us correctly"));
  187. hr = HrRegOpenKeyEx(m_hKeyStyle, NULL, 0, (KEY_WRITE | KEY_READ), &hKeyStyle); // Clone the key.
  188. if (SUCCEEDED(hr))
  189. {
  190. TCHAR szSelectedSize[MAXIMUM_SUB_KEY_LENGTH];
  191. DWORD cbSize = sizeof(szSelectedSize);
  192. hr = HrSHGetValue(m_hKeyStyle, NULL, SZ_REGVALUE_SELECTEDSIZE, NULL, szSelectedSize, &cbSize);
  193. if (FAILED(hr))
  194. {
  195. StringCchCopy(szSelectedSize, ARRAYSIZE(szSelectedSize), TEXT("0")); // Select the first one in the list when in doubt.
  196. hr = S_OK;
  197. }
  198. if (SUCCEEDED(hr))
  199. {
  200. TCHAR szKeyName[MAXIMUM_SUB_KEY_LENGTH];
  201. HKEY hKeyTheSize;
  202. StringCchPrintf(szKeyName, ARRAYSIZE(szKeyName), TEXT("%s\\%s"), SZ_REGKEY_SIZES, szSelectedSize);
  203. // Let's find the next empty slot
  204. hr = HrRegOpenKeyEx(m_hKeyStyle, szKeyName, 0, (KEY_WRITE | KEY_READ), &hKeyTheSize);
  205. if (SUCCEEDED(hr))
  206. {
  207. hr = CAppearanceSize_CreateInstance(hKeyStyle, hKeyTheSize, ppThemeSize); // This function takes ownership of hKeyStyle and kKeySizes
  208. if (FAILED(hr))
  209. {
  210. RegCloseKey(hKeyTheSize);
  211. }
  212. }
  213. }
  214. if (FAILED(hr))
  215. {
  216. RegCloseKey(hKeyStyle);
  217. }
  218. }
  219. }
  220. return hr;
  221. }
  222. HRESULT CAppearanceStyle::put_SelectedSize(IN IThemeSize * pThemeSize)
  223. {
  224. HRESULT hr = E_INVALIDARG;
  225. if (pThemeSize)
  226. {
  227. TCHAR szKeyName[MAXIMUM_SUB_KEY_LENGTH];
  228. CComBSTR bstrDisplayNameSource;
  229. szKeyName[0] = 0;
  230. hr = pThemeSize->get_DisplayName(&bstrDisplayNameSource);
  231. if (SUCCEEDED(hr))
  232. {
  233. for (int nIndex = 0; SUCCEEDED(hr); nIndex++)
  234. {
  235. IThemeSize * pThemeSizeInList;
  236. hr = _getSizeByIndex(nIndex, &pThemeSizeInList);
  237. if (SUCCEEDED(hr))
  238. {
  239. CComBSTR bstrDisplayName;
  240. hr = pThemeSizeInList->get_DisplayName(&bstrDisplayName);
  241. if (SUCCEEDED(hr))
  242. {
  243. ATOMICRELEASE(pThemeSizeInList);
  244. if (!StrCmpIW(bstrDisplayName, bstrDisplayNameSource))
  245. {
  246. // They match, so this is the one.
  247. StringCchPrintf(szKeyName, ARRAYSIZE(szKeyName), TEXT("%d"), nIndex);
  248. break;
  249. }
  250. }
  251. }
  252. }
  253. }
  254. if (SUCCEEDED(hr) && szKeyName[0])
  255. {
  256. DWORD cbSize = ((lstrlen(szKeyName) + 1) * sizeof(szKeyName[0]));
  257. hr = HrSHSetValue(m_hKeyStyle, NULL, SZ_REGVALUE_SELECTEDSIZE, REG_SZ, szKeyName, cbSize);
  258. }
  259. }
  260. return hr;
  261. }
  262. HRESULT CAppearanceStyle::AddSize(OUT IThemeSize ** ppThemeSize)
  263. {
  264. HRESULT hr = E_INVALIDARG;
  265. if (ppThemeSize)
  266. {
  267. HKEY kKeySizes;
  268. *ppThemeSize = NULL;
  269. hr = HrRegCreateKeyEx(m_hKeyStyle, SZ_REGKEY_SIZES, 0, NULL, REG_OPTION_NON_VOLATILE, (KEY_WRITE | KEY_READ), NULL, &kKeySizes, NULL);
  270. if (SUCCEEDED(hr))
  271. {
  272. for (int nIndex = 0; nIndex < 10000; nIndex++)
  273. {
  274. HKEY hKeyTheSize;
  275. TCHAR szKeyName[MAXIMUM_SUB_KEY_LENGTH];
  276. StringCchPrintf(szKeyName, ARRAYSIZE(szKeyName), TEXT("%d"), nIndex);
  277. // Let's find the next empty slot
  278. hr = HrRegOpenKeyEx(kKeySizes, szKeyName, 0, (KEY_WRITE | KEY_READ), &hKeyTheSize);
  279. if (SUCCEEDED(hr))
  280. {
  281. RegCloseKey(hKeyTheSize);
  282. }
  283. else
  284. {
  285. hr = HrRegCreateKeyEx(kKeySizes, szKeyName, 0, NULL, REG_OPTION_NON_VOLATILE, (KEY_WRITE | KEY_READ), NULL, &hKeyTheSize, NULL);
  286. if (SUCCEEDED(hr))
  287. {
  288. HKEY hKeyStyle;
  289. hr = HrRegOpenKeyEx(m_hKeyStyle, NULL, 0, (KEY_WRITE | KEY_READ), &hKeyStyle); // Clone the key.
  290. if (SUCCEEDED(hr))
  291. {
  292. hr = CAppearanceSize_CreateInstance(hKeyStyle, hKeyTheSize, ppThemeSize); // This function takes ownership of hKeyStyle and kKeySizes
  293. if (FAILED(hr))
  294. {
  295. RegCloseKey(hKeyStyle);
  296. }
  297. }
  298. if (FAILED(hr))
  299. {
  300. RegCloseKey(hKeyTheSize);
  301. }
  302. }
  303. break;
  304. }
  305. }
  306. RegCloseKey(kKeySizes);
  307. }
  308. }
  309. return hr;
  310. }
  311. //===========================
  312. // *** IUnknown Interface ***
  313. //===========================
  314. ULONG CAppearanceStyle::AddRef()
  315. {
  316. return InterlockedIncrement(&m_cRef);
  317. }
  318. ULONG CAppearanceStyle::Release()
  319. {
  320. ASSERT( 0 != m_cRef );
  321. ULONG cRef = InterlockedDecrement(&m_cRef);
  322. if ( 0 == cRef )
  323. {
  324. delete this;
  325. }
  326. return cRef;
  327. }
  328. //===========================
  329. // *** Class Methods ***
  330. //===========================
  331. HRESULT CAppearanceStyle::QueryInterface(REFIID riid, void **ppvObj)
  332. {
  333. static const QITAB qit[] = {
  334. QITABENT(CAppearanceStyle, IThemeStyle),
  335. QITABENT(CAppearanceStyle, IDispatch),
  336. { 0 },
  337. };
  338. return QISearch(this, qit, riid, ppvObj);
  339. }
  340. CAppearanceStyle::CAppearanceStyle(IN HKEY hkeyStyle) : m_cRef(1)
  341. {
  342. DllAddRef();
  343. // This needs to be allocated in Zero Inited Memory.
  344. // Assert that all Member Variables are inited to Zero.
  345. m_hKeyStyle = hkeyStyle;
  346. }
  347. CAppearanceStyle::~CAppearanceStyle()
  348. {
  349. if (m_hKeyStyle)
  350. {
  351. RegCloseKey(m_hKeyStyle);
  352. }
  353. DllRelease();
  354. }
  355. HRESULT CAppearanceStyle_CreateInstance(IN HKEY hkeyStyle, OUT IThemeStyle ** ppThemeStyle)
  356. {
  357. HRESULT hr = E_INVALIDARG;
  358. if (ppThemeStyle)
  359. {
  360. CAppearanceStyle * pObject = new CAppearanceStyle(hkeyStyle);
  361. *ppThemeStyle = NULL;
  362. if (pObject)
  363. {
  364. hr = pObject->QueryInterface(IID_PPV_ARG(IThemeStyle, ppThemeStyle));
  365. pObject->Release();
  366. }
  367. else
  368. {
  369. hr = E_OUTOFMEMORY;
  370. }
  371. }
  372. return hr;
  373. }