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.

339 lines
9.4 KiB

  1. /*****************************************************************************\
  2. FILE: thScheme.cpp
  3. DESCRIPTION:
  4. This is the Autmation Object to theme scheme object.
  5. BryanSt 5/11/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 "appstyle.h"
  14. #include "thsize.h"
  15. #include "thstyle.h"
  16. #include "thscheme.h"
  17. //===========================
  18. // *** Class Internals & Helpers ***
  19. //===========================
  20. //===========================
  21. // *** ITheme Interface ***
  22. //===========================
  23. HRESULT CSkinScheme::get_DisplayName(OUT BSTR * pbstrDisplayName)
  24. {
  25. WCHAR szDisplayName[MAX_PATH];
  26. HRESULT hr = GetThemeDocumentationProperty(m_pszFilename, SZ_THDOCPROP_DISPLAYNAME, szDisplayName, ARRAYSIZE(szDisplayName));
  27. LogStatus("GetThemeDocumentationProperty(path=\"%ls\", displayname=\"%ls\") returned %#08lx.\r\n", m_pszFilename, szDisplayName, hr);
  28. if (SUCCEEDED(hr))
  29. {
  30. hr = HrSysAllocStringW(szDisplayName, pbstrDisplayName);
  31. }
  32. return hr;
  33. }
  34. HRESULT CSkinScheme::get_Path(OUT BSTR * pbstrPath)
  35. {
  36. return HrSysAllocString(m_pszFilename, pbstrPath);
  37. }
  38. HRESULT CSkinScheme::put_Path(IN BSTR bstrPath)
  39. {
  40. HRESULT hr = E_INVALIDARG;
  41. if (bstrPath)
  42. {
  43. Str_SetPtr(&m_pszFilename, bstrPath);
  44. hr = (m_pszFilename ? S_OK : E_OUTOFMEMORY);
  45. }
  46. return hr;
  47. }
  48. HRESULT CSkinScheme::get_length(OUT long * pnLength)
  49. {
  50. HRESULT hr = E_INVALIDARG;
  51. if (pnLength)
  52. {
  53. hr = S_OK;
  54. if (COLLECTION_SIZE_UNINITIALIZED == m_nSize)
  55. {
  56. THEMENAMEINFO themeInfo;
  57. m_nSize = 0;
  58. // Make sure there are at least 1 color or return a failure HR.
  59. hr = EnumThemeColors(m_pszFilename, NULL, m_nSize, &themeInfo);
  60. do
  61. {
  62. m_nSize++;
  63. }
  64. while (SUCCEEDED(EnumThemeColors(m_pszFilename, NULL, m_nSize, &themeInfo)));
  65. }
  66. *pnLength = m_nSize;
  67. }
  68. return hr;
  69. }
  70. HRESULT CSkinScheme::get_item(IN VARIANT varIndex, OUT IThemeStyle ** ppThemeStyle)
  71. {
  72. HRESULT hr = E_INVALIDARG;
  73. if (ppThemeStyle)
  74. {
  75. long nCount = 0;
  76. get_length(&nCount);
  77. *ppThemeStyle = NULL;
  78. // This is sortof gross, but if we are passed a pointer to another variant, simply
  79. // update our copy here...
  80. if (varIndex.vt == (VT_BYREF | VT_VARIANT) && varIndex.pvarVal)
  81. varIndex = *(varIndex.pvarVal);
  82. switch (varIndex.vt)
  83. {
  84. case VT_I2:
  85. varIndex.lVal = (long)varIndex.iVal;
  86. // And fall through...
  87. case VT_I4:
  88. if ((varIndex.lVal >= 0) && (varIndex.lVal < nCount) && m_pszFilename)
  89. {
  90. THEMENAMEINFO themeInfo;
  91. hr = EnumThemeColors(m_pszFilename, NULL, varIndex.lVal, &themeInfo);
  92. LogStatus("EnumThemeColors(path=\"%ls\") returned %#08lx in CSkinScheme::get_item.\r\n", m_pszFilename, hr);
  93. if (SUCCEEDED(hr))
  94. {
  95. hr = CSkinStyle_CreateInstance(m_pszFilename, themeInfo.szName, themeInfo.szDisplayName, ppThemeStyle);
  96. }
  97. }
  98. break;
  99. case VT_BSTR:
  100. if (varIndex.bstrVal)
  101. {
  102. if (!varIndex.bstrVal[0])
  103. {
  104. if (m_pszFilename)
  105. {
  106. TCHAR szColor[MAX_PATH];
  107. TCHAR szSize[MAX_PATH];
  108. hr = GetThemeDefaults(m_pszFilename, szColor, ARRAYSIZE(szColor), szSize, ARRAYSIZE(szSize));
  109. LogStatus("GetThemeDefaults(pszFilename=\"%ls\", szColor=\"%ls\", szSize=\"%ls\") returned %#08lx in CSkinScheme::get_item.\r\n", m_pszFilename, szColor, szSize, hr);
  110. if (SUCCEEDED(hr))
  111. {
  112. hr = CSkinStyle_CreateInstance(m_pszFilename, szColor, ppThemeStyle);
  113. }
  114. }
  115. }
  116. else
  117. {
  118. THEMENAMEINFO themeInfo;
  119. for (long nIndex = 0; FAILED(hr) && (nIndex < nCount) && SUCCEEDED(EnumThemeColors(m_pszFilename, NULL, nIndex, &themeInfo));
  120. nIndex++)
  121. {
  122. if (!StrCmpIW(themeInfo.szDisplayName, varIndex.bstrVal) ||
  123. !StrCmpIW(themeInfo.szName, varIndex.bstrVal))
  124. {
  125. hr = CSkinStyle_CreateInstance(m_pszFilename, themeInfo.szName, themeInfo.szDisplayName, ppThemeStyle);
  126. }
  127. }
  128. }
  129. }
  130. break;
  131. default:
  132. hr = E_NOTIMPL;
  133. }
  134. }
  135. return hr;
  136. }
  137. HRESULT CSkinScheme::get_SelectedStyle(OUT IThemeStyle ** ppThemeStyle)
  138. {
  139. HRESULT hr = E_INVALIDARG;
  140. if (ppThemeStyle)
  141. {
  142. WCHAR szCurrentPath[MAX_PATH];
  143. WCHAR szCurrentStyle[MAX_PATH];
  144. szCurrentPath[0] = 0;
  145. szCurrentStyle[0] = 0;
  146. *ppThemeStyle = NULL;
  147. hr = GetCurrentThemeName(szCurrentPath, ARRAYSIZE(szCurrentPath), szCurrentStyle, ARRAYSIZE(szCurrentStyle), NULL, 0);
  148. LogStatus("GetCurrentThemeName(path=\"%ls\", color=\"%ls\", size=\"%ls\") returned %#08lx in CSkinScheme::get_SelectedStyle.\r\n", szCurrentPath, szCurrentStyle, TEXT("NULL"), hr);
  149. if (SUCCEEDED(hr))
  150. {
  151. AssertMsg((0 != szCurrentStyle[0]), TEXT("The GetCurrentThemeName() API returned an invalid value."));
  152. // Is this skin currently selected?
  153. if (!StrCmpIW(m_pszFilename, szCurrentPath))
  154. {
  155. // Yes, so get the color style from that API.
  156. if (!m_pSelectedStyle)
  157. {
  158. hr = CSkinStyle_CreateInstance(m_pszFilename, szCurrentStyle, &m_pSelectedStyle);
  159. }
  160. }
  161. else
  162. {
  163. hr = E_FAIL;
  164. }
  165. }
  166. if (FAILED(hr))
  167. {
  168. ATOMICRELEASE(m_pSelectedStyle);
  169. // No, so find the default color style for this skin(scheme).
  170. hr = GetThemeDefaults(m_pszFilename, szCurrentStyle, ARRAYSIZE(szCurrentStyle), NULL, 0);
  171. LogStatus("GetThemeDefaults(szCurrentStyle=\"%ls\", szCurrentStyle=\"%ls\") returned %#08lx in CSkinScheme::get_SelectedStyle.\r\n", szCurrentStyle, szCurrentStyle, hr);
  172. if (SUCCEEDED(hr))
  173. {
  174. hr = CSkinStyle_CreateInstance(m_pszFilename, szCurrentStyle, &m_pSelectedStyle);
  175. }
  176. }
  177. if (m_pSelectedStyle)
  178. {
  179. IUnknown_Set((IUnknown **)ppThemeStyle, m_pSelectedStyle);
  180. }
  181. }
  182. return hr;
  183. }
  184. HRESULT CSkinScheme::put_SelectedStyle(IN IThemeStyle * pThemeStyle)
  185. {
  186. IUnknown_Set((IUnknown **)&m_pSelectedStyle, pThemeStyle);
  187. return S_OK;
  188. }
  189. HRESULT CSkinScheme::AddStyle(OUT IThemeStyle ** ppThemeStyle)
  190. {
  191. if (ppThemeStyle)
  192. {
  193. *ppThemeStyle = NULL;
  194. }
  195. return E_NOTIMPL;
  196. }
  197. //===========================
  198. // *** IUnknown Interface ***
  199. //===========================
  200. ULONG CSkinScheme::AddRef()
  201. {
  202. return InterlockedIncrement(&m_cRef);
  203. }
  204. ULONG CSkinScheme::Release()
  205. {
  206. ASSERT( 0 != m_cRef );
  207. ULONG cRef = InterlockedDecrement(&m_cRef);
  208. if ( 0 == cRef )
  209. {
  210. delete this;
  211. }
  212. return cRef;
  213. }
  214. //===========================
  215. // *** Class Methods ***
  216. //===========================
  217. HRESULT CSkinScheme::QueryInterface(REFIID riid, void **ppvObj)
  218. {
  219. static const QITAB qit[] = {
  220. QITABENT(CSkinScheme, IPersist),
  221. QITABENT(CSkinScheme, IThemeScheme),
  222. QITABENT(CSkinScheme, IDispatch),
  223. { 0 },
  224. };
  225. return QISearch(this, qit, riid, ppvObj);
  226. }
  227. CSkinScheme::CSkinScheme(IN LPCWSTR pszFilename) : CObjectCLSID(&CLSID_SkinScheme), m_cRef(1)
  228. {
  229. DllAddRef();
  230. // This needs to be allocated in Zero Inited Memory.
  231. // Assert that all Member Variables are inited to Zero.
  232. ASSERT(!m_pSelectedStyle);
  233. Str_SetPtr(&m_pszFilename, pszFilename);
  234. m_nSize = COLLECTION_SIZE_UNINITIALIZED;
  235. }
  236. CSkinScheme::~CSkinScheme()
  237. {
  238. ATOMICRELEASE(m_pSelectedStyle);
  239. Str_SetPtr(&m_pszFilename, NULL);
  240. DllRelease();
  241. }
  242. HRESULT CSkinScheme_CreateInstance(IN LPCWSTR pszFilename, OUT IThemeScheme ** ppThemeScheme)
  243. {
  244. HRESULT hr = E_INVALIDARG;
  245. if (pszFilename && ppThemeScheme)
  246. {
  247. TCHAR szPath[MAX_PATH];
  248. StringCchCopy(szPath, ARRAYSIZE(szPath), pszFilename);
  249. ExpandResourceDir(szPath, ARRAYSIZE(szPath));
  250. CSkinScheme * pObject = new CSkinScheme(szPath);
  251. *ppThemeScheme = NULL;
  252. hr = E_OUTOFMEMORY;
  253. if (pObject)
  254. {
  255. if (pObject->m_pszFilename)
  256. {
  257. hr = pObject->QueryInterface(IID_PPV_ARG(IThemeScheme, ppThemeScheme));
  258. }
  259. pObject->Release();
  260. }
  261. }
  262. return hr;
  263. }