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.

2337 lines
72 KiB

  1. /*****************************************************************************\
  2. FILE: BaseAppearPg.cpp
  3. DESCRIPTION:
  4. This code will display a "Appearances" tab in the
  5. "Display Properties" dialog (the base dialog, not the advanced dlg).
  6. ??????? ?/??/1993 Created
  7. BryanSt 3/23/2000 Updated and Converted to C++
  8. Copyright (C) Microsoft Corp 1993-2000. All rights reserved.
  9. \*****************************************************************************/
  10. #include "priv.h"
  11. #include "BaseAppearPg.h"
  12. #include "AdvAppearPg.h"
  13. #include "CoverWnd.h"
  14. #include "AppScheme.h"
  15. #include "AdvDlg.h"
  16. #include "fontfix.h"
  17. //============================================================================================================
  18. // *** Globals ***
  19. //============================================================================================================
  20. const static DWORD FAR aBaseAppearanceHelpIds[] =
  21. {
  22. IDC_APPG_APPEARPREVIEW, IDH_DISPLAY_APPEARANCE_PREVIEW,
  23. IDC_APPG_LOOKFEEL, IDH_DISPLAY_APPEARANCE_LOOKFEEL,
  24. IDC_APPG_LOOKFEEL_LABLE, IDH_DISPLAY_APPEARANCE_LOOKFEEL,
  25. IDC_APPG_COLORSCHEME_LABLE, IDH_DISPLAY_APPEARANCE_COLORSCHEME,
  26. IDC_APPG_COLORSCHEME, IDH_DISPLAY_APPEARANCE_COLORSCHEME,
  27. IDC_APPG_WNDSIZE_LABLE, IDH_DISPLAY_APPEARANCE_WNDSIZE,
  28. IDC_APPG_WNDSIZE, IDH_DISPLAY_APPEARANCE_WNDSIZE,
  29. IDC_APPG_EFFECTS, IDH_DISPLAY_APPEARANCE_EFFECTS,
  30. IDC_APPG_ADVANCED, IDH_DISPLAY_APPEARANCE_ADVANCED,
  31. 0, 0
  32. };
  33. #define SZ_HELPFILE_BASEAPPEARANCE TEXT("display.hlp")
  34. // EnableApplyButton() fails in WM_INITDIALOG so we need to do it later.
  35. #define WMUSER_DELAYENABLEAPPLY (WM_USER + 1)
  36. #define DelayEnableApplyButton(hDlg) PostMessage(hDlg, WMUSER_DELAYENABLEAPPLY, 0, 0)
  37. //===========================
  38. // *** Class Internals & Helpers ***
  39. //===========================
  40. #ifdef DEBUG
  41. void _TestFault(void)
  42. {
  43. DWORD dwTemp = 3;
  44. DWORD * pdwDummy = NULL; // This is NULL in order that it causes a fault.
  45. for (int nIndex = 0; nIndex < 1000000; nIndex++)
  46. {
  47. // This will definitely fault sooner or later.
  48. dwTemp += pdwDummy[nIndex];
  49. }
  50. }
  51. #endif // DEBUG
  52. BOOL CBaseAppearancePage::_IsDirty(void)
  53. {
  54. BOOL fIsDirty = m_advDlgState.dwChanged;
  55. if (m_fIsDirty || // We need to check this because we may have gotten dirty from another page before our UI was displayed.
  56. (ComboBox_GetCurSel(m_hwndSchemeDropDown) != m_nSelectedScheme) ||
  57. (ComboBox_GetCurSel(m_hwndStyleDropDown) != m_nSelectedStyle) ||
  58. (ComboBox_GetCurSel(m_hwndSizeDropDown) != m_nSelectedSize) ||
  59. (m_nNewDPI != m_nAppliedDPI))
  60. {
  61. fIsDirty = TRUE;
  62. }
  63. return fIsDirty;
  64. }
  65. INT_PTR CALLBACK CBaseAppearancePage::BaseAppearanceDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
  66. {
  67. CBaseAppearancePage * pThis = (CBaseAppearancePage *)GetWindowLongPtr(hDlg, DWLP_USER);
  68. if (WM_INITDIALOG == wMsg)
  69. {
  70. PROPSHEETPAGE * pPropSheetPage = (PROPSHEETPAGE *) lParam;
  71. if (pPropSheetPage)
  72. {
  73. SetWindowLongPtr(hDlg, DWLP_USER, pPropSheetPage->lParam);
  74. pThis = (CBaseAppearancePage *)pPropSheetPage->lParam;
  75. }
  76. }
  77. if (pThis)
  78. return pThis->_BaseAppearanceDlgProc(hDlg, wMsg, wParam, lParam);
  79. return DefWindowProc(hDlg, wMsg, wParam, lParam);
  80. }
  81. BOOL DisplayAdvAppearancePage(IN IThemeScheme * pSelectedThemeScheme)
  82. {
  83. BOOL fDisplayAdvanced = TRUE;
  84. if (pSelectedThemeScheme)
  85. {
  86. fDisplayAdvanced = IUnknown_CompareCLSID(pSelectedThemeScheme, CLSID_LegacyAppearanceScheme);
  87. }
  88. return fDisplayAdvanced;
  89. }
  90. //============================================================================================================
  91. // *** Dialog Functions ***
  92. //============================================================================================================
  93. HRESULT CBaseAppearancePage::_OnAdvancedOptions(HWND hDlg)
  94. {
  95. HRESULT hr = E_FAIL;
  96. IAdvancedDialog * pAdvAppearDialog;
  97. hr = GetAdvancedDialog(&pAdvAppearDialog);
  98. if (SUCCEEDED(hr))
  99. {
  100. BOOL fEnableApply = FALSE;
  101. IUnknown_SetSite(pAdvAppearDialog, SAFECAST(this, IObjectWithSite *));
  102. hr = pAdvAppearDialog->DisplayAdvancedDialog(hDlg, SAFECAST(this, IPropertyBag *), &fEnableApply);
  103. IUnknown_SetSite(pAdvAppearDialog, NULL);
  104. if (SUCCEEDED(hr) && fEnableApply)
  105. {
  106. EnableApplyButton(hDlg);
  107. // We pass TRUE because we want to switch to Custom if:
  108. // 1) visual styles are off, and 2) some of the system metrics changed. Then we need to update the previews.
  109. _UpdatePreview(TRUE);
  110. }
  111. pAdvAppearDialog->Release();
  112. }
  113. return hr;
  114. }
  115. HRESULT CBaseAppearancePage::_OnEffectsOptions(HWND hDlg)
  116. {
  117. HRESULT hr = E_FAIL;
  118. if (_punkSite)
  119. {
  120. IThemeUIPages * pThemesUIPages;
  121. // Let's get the Effects base page.
  122. hr = _punkSite->QueryInterface(IID_PPV_ARG(IThemeUIPages, &pThemesUIPages));
  123. if (SUCCEEDED(hr))
  124. {
  125. IEnumUnknown * pEnumUnknown;
  126. hr = pThemesUIPages->GetBasePagesEnum(&pEnumUnknown);
  127. if (SUCCEEDED(hr))
  128. {
  129. IUnknown * punk;
  130. hr = IEnumUnknown_FindCLSID(pEnumUnknown, PPID_Effects, &punk);
  131. if (SUCCEEDED(hr))
  132. {
  133. IBasePropPage * pEffects;
  134. hr = punk->QueryInterface(IID_PPV_ARG(IBasePropPage, &pEffects));
  135. if (SUCCEEDED(hr))
  136. {
  137. IAdvancedDialog * pEffectsDialog;
  138. hr = pEffects->GetAdvancedDialog(&pEffectsDialog);
  139. if (SUCCEEDED(hr))
  140. {
  141. IPropertyBag * pEffectsBag;
  142. hr = punk->QueryInterface(IID_PPV_ARG(IPropertyBag, &pEffectsBag));
  143. if (SUCCEEDED(hr))
  144. {
  145. BOOL fEnableApply = FALSE;
  146. IUnknown_SetSite(pEffectsDialog, SAFECAST(this, IObjectWithSite *));
  147. hr = pEffectsDialog->DisplayAdvancedDialog(hDlg, pEffectsBag, &fEnableApply);
  148. IUnknown_SetSite(pEffectsDialog, NULL);
  149. if (SUCCEEDED(hr) && fEnableApply)
  150. {
  151. EnableApplyButton(hDlg);
  152. // We pass TRUE because we want to switch to Custom if:
  153. // 1) visual styles are off, and 2) some of the system metrics changed. Then we need to update the previews.
  154. _UpdatePreview(TRUE);
  155. }
  156. pEffectsBag->Release();
  157. }
  158. pEffectsDialog->Release();
  159. }
  160. pEffects->Release();
  161. }
  162. punk->Release();
  163. }
  164. pEnumUnknown->Release();
  165. }
  166. pThemesUIPages->Release();
  167. }
  168. }
  169. return hr;
  170. }
  171. HRESULT CBaseAppearancePage::_PopulateSchemeDropdown(void)
  172. {
  173. HRESULT hr = E_FAIL;
  174. _FreeSchemeDropdown(); // Purge any existing items.
  175. if (m_pThemeManager && m_pSelectedThemeScheme)
  176. {
  177. CComBSTR bstrSelectedName;
  178. m_nSelectedStyle = -1;
  179. // This will fail if someone deleted the .msstyles file.
  180. if (FAILED(m_pSelectedThemeScheme->get_DisplayName(&bstrSelectedName)))
  181. {
  182. bstrSelectedName = (BSTR)NULL;
  183. }
  184. VARIANT varIndex;
  185. #ifndef ENABLE_IA64_VISUALSTYLES
  186. // We use a different regkey for 64bit because we need to leave it off until the pre-Whistler
  187. // 64-bit release forks from the Whistler code base.
  188. BOOL fSkinsFeatureEnabled = SHRegGetBoolUSValue(SZ_REGKEY_APPEARANCE, SZ_REGVALUE_DISPLAYSCHEMES64, FALSE, FALSE);
  189. #else // ENABLE_IA64_VISUALSTYLES
  190. BOOL fSkinsFeatureEnabled = SHRegGetBoolUSValue(SZ_REGKEY_APPEARANCE, SZ_REGVALUE_DISPLAYSCHEMES, FALSE, TRUE);
  191. #endif // ENABLE_IA64_VISUALSTYLES
  192. varIndex.vt = VT_I4;
  193. varIndex.lVal = 0;
  194. do
  195. {
  196. hr = E_FAIL;
  197. // Only add the Skins if the policy doesn't lock it.
  198. if ((0 == varIndex.lVal) || fSkinsFeatureEnabled)
  199. {
  200. // Only add the Skins if the policy doesn't lock it.
  201. IThemeScheme * pThemeScheme;
  202. VARIANT varIndex2;
  203. varIndex2.vt = VT_I4;
  204. varIndex2.lVal = 0;
  205. // If a Theme can have more than one Scheme (Skin), then we should enum.
  206. hr = m_pThemeManager->get_schemeItem(varIndex, &pThemeScheme);
  207. if (SUCCEEDED(hr))
  208. {
  209. CComBSTR bstrDisplayName;
  210. hr = pThemeScheme->get_DisplayName(&bstrDisplayName);
  211. if (SUCCEEDED(hr) && m_hwndSchemeDropDown)
  212. {
  213. int nAddIndex = ComboBox_AddString(m_hwndSchemeDropDown, bstrDisplayName);
  214. if (-1 != nAddIndex)
  215. {
  216. ComboBox_SetItemData(m_hwndSchemeDropDown, nAddIndex, pThemeScheme);
  217. pThemeScheme = NULL;
  218. }
  219. else
  220. {
  221. hr = E_OUTOFMEMORY;
  222. }
  223. }
  224. ATOMICRELEASE(pThemeScheme);
  225. }
  226. }
  227. varIndex.lVal++;
  228. }
  229. while (SUCCEEDED(hr));
  230. //---- now that sorted list is built, find index of "bstrSelectedName" ----
  231. if (bstrSelectedName)
  232. {
  233. int nIndex = (int)ComboBox_FindStringExact(m_hwndSchemeDropDown, 0, bstrSelectedName);
  234. if (nIndex != -1) // got a match
  235. {
  236. ComboBox_SetCurSel(m_hwndSchemeDropDown, nIndex);
  237. m_nSelectedScheme = nIndex;
  238. }
  239. }
  240. hr = S_OK;
  241. }
  242. if (-1 == m_nSelectedScheme)
  243. {
  244. m_nSelectedScheme = 0;
  245. ComboBox_SetCurSel(m_hwndSchemeDropDown, m_nSelectedScheme);
  246. }
  247. return hr;
  248. }
  249. HRESULT CBaseAppearancePage::_FreeSchemeDropdown(void)
  250. {
  251. HRESULT hr = S_OK;
  252. LPARAM lParam;
  253. if (m_hwndSchemeDropDown)
  254. {
  255. do
  256. {
  257. lParam = ComboBox_GetItemData(m_hwndSchemeDropDown, 0);
  258. if (CB_ERR != lParam)
  259. {
  260. IThemeScheme * pThemeScheme = (IThemeScheme *) lParam;
  261. ATOMICRELEASE(pThemeScheme);
  262. ComboBox_DeleteString(m_hwndSchemeDropDown, 0);
  263. }
  264. }
  265. while (CB_ERR != lParam);
  266. }
  267. return hr;
  268. }
  269. HRESULT CBaseAppearancePage::_PopulateStyleDropdown(void)
  270. {
  271. HRESULT hr = E_FAIL;
  272. _FreeStyleDropdown(); // Purge any existing items.
  273. if (m_pSelectedStyle)
  274. {
  275. CComBSTR bstrSelectedName;
  276. m_nSelectedStyle = -1;
  277. hr = m_pSelectedStyle->get_DisplayName(&bstrSelectedName);
  278. if (SUCCEEDED(hr))
  279. {
  280. VARIANT varIndex;
  281. varIndex.vt = VT_I4;
  282. varIndex.lVal = 0;
  283. do
  284. {
  285. // Only add the Skins if the policy doesn't lock it.
  286. IThemeStyle * pThemeStyle;
  287. hr = m_pSelectedThemeScheme->get_item(varIndex, &pThemeStyle);
  288. if (SUCCEEDED(hr))
  289. {
  290. CComBSTR bstrDisplayName;
  291. hr = pThemeStyle->get_DisplayName(&bstrDisplayName);
  292. if (SUCCEEDED(hr) && m_hwndSchemeDropDown)
  293. {
  294. int nAddIndex = ComboBox_AddString(m_hwndStyleDropDown, bstrDisplayName);
  295. if (-1 != nAddIndex)
  296. {
  297. ComboBox_SetItemData(m_hwndStyleDropDown, nAddIndex, pThemeStyle);
  298. pThemeStyle = NULL;
  299. }
  300. else
  301. {
  302. hr = E_OUTOFMEMORY;
  303. }
  304. }
  305. ATOMICRELEASE(pThemeStyle);
  306. }
  307. varIndex.lVal++;
  308. }
  309. while (SUCCEEDED(hr));
  310. //---- now that sorted list is built, find index of "bstrSelectedName" ----
  311. if (bstrSelectedName)
  312. {
  313. int nIndex = (int)ComboBox_FindStringExact(m_hwndStyleDropDown, 0, bstrSelectedName);
  314. if (nIndex != -1) // got a match
  315. {
  316. ComboBox_SetCurSel(m_hwndStyleDropDown, nIndex);
  317. m_nSelectedStyle = nIndex;
  318. }
  319. }
  320. hr = S_OK;
  321. }
  322. }
  323. if (-1 == m_nSelectedStyle)
  324. {
  325. m_nSelectedStyle = 0;
  326. ComboBox_SetCurSel(m_hwndStyleDropDown, m_nSelectedStyle);
  327. }
  328. return hr;
  329. }
  330. HRESULT CBaseAppearancePage::_FreeStyleDropdown(void)
  331. {
  332. HRESULT hr = S_OK;
  333. LPARAM lParam;
  334. if (m_hwndStyleDropDown)
  335. {
  336. do
  337. {
  338. lParam = ComboBox_GetItemData(m_hwndStyleDropDown, 0);
  339. if (CB_ERR != lParam)
  340. {
  341. IThemeStyle * pThemeStyle = (IThemeStyle *) lParam;
  342. ATOMICRELEASE(pThemeStyle);
  343. ComboBox_DeleteString(m_hwndStyleDropDown, 0);
  344. }
  345. }
  346. while (CB_ERR != lParam);
  347. }
  348. return hr;
  349. }
  350. HRESULT CBaseAppearancePage::_PopulateSizeDropdown(void)
  351. {
  352. HRESULT hr = E_FAIL;
  353. _FreeSizeDropdown(); // Purge any existing items.
  354. if (m_pSelectedSize)
  355. {
  356. CComBSTR bstrSelectedName;
  357. m_nSelectedSize = -1;
  358. hr = m_pSelectedSize->get_DisplayName(&bstrSelectedName);
  359. if (SUCCEEDED(hr))
  360. {
  361. VARIANT varIndex;
  362. varIndex.vt = VT_I4;
  363. varIndex.lVal = 0;
  364. do
  365. {
  366. // Only add the Skins if the policy doesn't lock it.
  367. IThemeSize * pThemeSize;
  368. hr = m_pSelectedStyle->get_item(varIndex, &pThemeSize);
  369. if (SUCCEEDED(hr))
  370. {
  371. CComBSTR bstrDisplayName;
  372. hr = pThemeSize->get_DisplayName(&bstrDisplayName);
  373. if (SUCCEEDED(hr) && m_hwndSchemeDropDown)
  374. {
  375. int nAddIndex = ComboBox_AddString(m_hwndSizeDropDown, bstrDisplayName);
  376. if (-1 != nAddIndex)
  377. {
  378. ComboBox_SetItemData(m_hwndSizeDropDown, nAddIndex, pThemeSize);
  379. pThemeSize = NULL;
  380. }
  381. else
  382. {
  383. hr = E_OUTOFMEMORY;
  384. }
  385. }
  386. ATOMICRELEASE(pThemeSize);
  387. }
  388. varIndex.lVal++;
  389. }
  390. while (SUCCEEDED(hr));
  391. //---- now that sorted list is built, find index of "bstrSelectedName" ----
  392. if (bstrSelectedName)
  393. {
  394. int nIndex = (int)ComboBox_FindStringExact(m_hwndSizeDropDown, 0, bstrSelectedName);
  395. if (nIndex != -1) // got a match
  396. {
  397. ComboBox_SetCurSel(m_hwndSizeDropDown, nIndex);
  398. m_nSelectedSize = nIndex;
  399. }
  400. }
  401. hr = S_OK;
  402. }
  403. }
  404. if (-1 == m_nSelectedSize)
  405. {
  406. m_nSelectedSize = 0;
  407. ComboBox_SetCurSel(m_hwndSizeDropDown, m_nSelectedSize);
  408. }
  409. return hr;
  410. }
  411. HRESULT CBaseAppearancePage::_FreeSizeDropdown(void)
  412. {
  413. HRESULT hr = S_OK;
  414. LPARAM lParam;
  415. if (m_hwndSizeDropDown)
  416. {
  417. do
  418. {
  419. lParam = ComboBox_GetItemData(m_hwndSizeDropDown, 0);
  420. if (CB_ERR != lParam)
  421. {
  422. IThemeSize * pThemeSize = (IThemeSize *) lParam;
  423. ATOMICRELEASE(pThemeSize);
  424. ComboBox_DeleteString(m_hwndSizeDropDown, 0);
  425. }
  426. }
  427. while (CB_ERR != lParam);
  428. }
  429. return hr;
  430. }
  431. HRESULT CBaseAppearancePage::_OnInitAppearanceDlg(HWND hDlg)
  432. {
  433. HRESULT hr = S_OK;
  434. _OnInitData();
  435. _hwnd = hDlg;
  436. #ifdef DEBUG
  437. if (!SHRegGetBoolUSValue(TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\TaskManager"), TEXT("Enable Test Faults"), FALSE, FALSE))
  438. {
  439. // Disable the feature.
  440. DestroyWindow(GetDlgItem(hDlg, IDC_APPG_TESTFAULT));
  441. }
  442. #endif // DEBUG
  443. m_hwndSchemeDropDown = GetDlgItem(hDlg, IDC_APPG_LOOKFEEL);
  444. m_hwndStyleDropDown = GetDlgItem(hDlg, IDC_APPG_COLORSCHEME);
  445. m_hwndSizeDropDown = GetDlgItem(hDlg, IDC_APPG_WNDSIZE);
  446. hr = _OnInitData();
  447. if (SUCCEEDED(hr))
  448. {
  449. hr = _PopulateSchemeDropdown();
  450. if (SUCCEEDED(hr))
  451. {
  452. hr = _PopulateStyleDropdown();
  453. if (SUCCEEDED(hr))
  454. {
  455. hr = _PopulateSizeDropdown();
  456. if (SUCCEEDED(hr))
  457. {
  458. hr = _UpdatePreview(FALSE);
  459. }
  460. }
  461. }
  462. }
  463. TCHAR szTemp[MAX_PATH];
  464. DWORD dwType;
  465. DWORD cbSize = sizeof(szTemp);
  466. if (SHRestricted(REST_NOVISUALSTYLECHOICE) ||
  467. (ERROR_SUCCESS == SHRegGetUSValue(SZ_REGKEY_POLICIES_SYSTEM, SZ_REGVALUE_POLICY_SETVISUALSTYLE, &dwType, (void *) szTemp, &cbSize, FALSE, NULL, 0)))
  468. {
  469. EnableWindow(GetDlgItem(hDlg, IDC_APPG_LOOKFEEL_LABLE), FALSE);
  470. EnableWindow(GetDlgItem(hDlg, IDC_APPG_LOOKFEEL), FALSE);
  471. m_fLockVisualStylePolicyEnabled = TRUE;
  472. LogStatus("POLICY ENABLED: Either NoVisualChoice or SetVisualStyle policy is set, locking the visual style selection.");
  473. }
  474. if (SHRestricted(REST_NOCOLORCHOICE))
  475. {
  476. EnableWindow(GetDlgItem(hDlg, IDC_APPG_COLORSCHEME_LABLE), FALSE);
  477. EnableWindow(GetDlgItem(hDlg, IDC_APPG_COLORSCHEME), FALSE);
  478. }
  479. if (SHRestricted(REST_NOSIZECHOICE))
  480. {
  481. EnableWindow(GetDlgItem(hDlg, IDC_APPG_WNDSIZE_LABLE), FALSE);
  482. EnableWindow(GetDlgItem(hDlg, IDC_APPG_WNDSIZE), FALSE);
  483. }
  484. if (m_pszLoadMSTheme)
  485. {
  486. hr = _LoadVisaulStyleFile(m_pszLoadMSTheme);
  487. }
  488. _EnableAdvancedButton();
  489. return S_OK;
  490. }
  491. HRESULT CBaseAppearancePage::_OnInitData(void)
  492. {
  493. HRESULT hr = S_OK;
  494. if (!m_fInitialized)
  495. {
  496. // Load DPI Value
  497. HDC hdc = GetDC(NULL);
  498. int nDefault = GetDeviceCaps(hdc, LOGPIXELSY); // Get the default value;
  499. ReleaseDC(NULL, hdc);
  500. m_nAppliedDPI = HrRegGetDWORD(HKEY_CURRENT_USER, SZ_WINDOWMETRICS, SZ_APPLIEDDPI, DPI_PERSISTED);
  501. if (!m_nAppliedDPI)
  502. {
  503. m_nAppliedDPI = nDefault;
  504. }
  505. m_nNewDPI = m_nAppliedDPI;
  506. LogStatus("DPI: SYSTEMMETRICS currently at %d DPI CBaseAppearancePage::_OnInitData\r\n", m_nAppliedDPI);
  507. // Load everything else.
  508. AssertMsg((NULL != _punkSite), TEXT("I need my punkSite!!!"));
  509. if (!m_pThemeManager && _punkSite)
  510. {
  511. hr = _punkSite->QueryInterface(IID_PPV_ARG(IThemeManager, &m_pThemeManager));
  512. }
  513. if (SUCCEEDED(hr) && !m_pSelectedThemeScheme)
  514. {
  515. hr = m_pThemeManager->get_SelectedScheme(&m_pSelectedThemeScheme);
  516. if (SUCCEEDED(hr) && !m_pSelectedStyle)
  517. {
  518. hr = m_pSelectedThemeScheme->get_SelectedStyle(&m_pSelectedStyle);
  519. if (SUCCEEDED(hr) && !m_pSelectedSize)
  520. {
  521. hr = m_pSelectedStyle->get_SelectedSize(&m_pSelectedSize);
  522. if (SUCCEEDED(hr))
  523. {
  524. // We want to load whatever system metrics the users have now.
  525. hr = _LoadLiveSettings(SZ_SAVEGROUP_ALL);
  526. }
  527. }
  528. }
  529. }
  530. m_fInitialized = TRUE;
  531. }
  532. return hr;
  533. }
  534. HRESULT CBaseAppearancePage::_OnDestroy(HWND hDlg)
  535. {
  536. _FreeSchemeDropdown();
  537. _FreeStyleDropdown();
  538. _FreeSizeDropdown();
  539. return S_OK;
  540. }
  541. HRESULT CBaseAppearancePage::_EnableAdvancedButton(void)
  542. {
  543. HRESULT hr = S_OK;
  544. #ifdef FEATURE_ENABLE_ADVANCED_WITH_SKINSON
  545. BOOL fTurnOn = TRUE;
  546. #else // FEATURE_ENABLE_ADVANCED_WITH_SKINSON
  547. BOOL fTurnOn = (m_pSelectedThemeScheme ? IUnknown_CompareCLSID(m_pSelectedThemeScheme, CLSID_LegacyAppearanceScheme) : FALSE);
  548. if (SHRegGetBoolUSValue(SZ_REGKEY_APPEARANCE, L"AlwaysAllowAdvanced", FALSE, FALSE))
  549. {
  550. fTurnOn = TRUE;
  551. }
  552. #endif // FEATURE_ENABLE_ADVANCED_WITH_SKINSON
  553. EnableWindow(GetDlgItem(_hwnd, IDC_APPG_ADVANCED), fTurnOn);
  554. return hr;
  555. }
  556. HRESULT CBaseAppearancePage::_UpdatePreview(IN BOOL fUpdateThemePage)
  557. {
  558. HRESULT hr = S_OK;
  559. if (!m_pThemePreview)
  560. {
  561. // We won't execute the following code if our dialog hasn't
  562. // been created yet. That's fine because the preview will
  563. // obtain the correct state when we first initialize.
  564. if (_punkSite && m_hwndSchemeDropDown)
  565. {
  566. hr = CThemePreview_CreateInstance(NULL, IID_PPV_ARG(IThemePreview, &m_pThemePreview));
  567. if (SUCCEEDED(hr))
  568. {
  569. IPropertyBag * pPropertyBag;
  570. hr = _punkSite->QueryInterface(IID_PPV_ARG(IPropertyBag, &pPropertyBag));
  571. if (SUCCEEDED(hr))
  572. {
  573. HWND hwndParent = GetParent(m_hwndSchemeDropDown);
  574. HWND hwndPlaceHolder = GetDlgItem(hwndParent, IDC_APPG_APPEARPREVIEW);
  575. RECT rcPreview;
  576. AssertMsg((NULL != m_hwndSchemeDropDown), TEXT("We should have this window at this point. -BryanSt"));
  577. GetClientRect(hwndPlaceHolder, &rcPreview);
  578. MapWindowPoints(hwndPlaceHolder, hwndParent, (LPPOINT)&rcPreview, 2);
  579. if (SUCCEEDED(m_pThemePreview->CreatePreview(hwndParent, TMPREV_SHOWVS, WS_VISIBLE | WS_CHILDWINDOW | WS_BORDER | WS_OVERLAPPED, WS_EX_CLIENTEDGE, rcPreview.left, rcPreview.top, RECTWIDTH(rcPreview), RECTHEIGHT(rcPreview), pPropertyBag, IDC_APPG_APPEARPREVIEW)))
  580. {
  581. // If we succeeded, remove the dummy window.
  582. DestroyWindow(hwndPlaceHolder);
  583. hr = SHPropertyBag_WritePunk(pPropertyBag, SZ_PBPROP_PREVIEW3, m_pThemePreview);
  584. if (SUCCEEDED(hr) && fUpdateThemePage)
  585. {
  586. // Tell the theme that we have customized the values.
  587. hr = SHPropertyBag_WriteInt(pPropertyBag, SZ_PBPROP_CUSTOMIZE_THEME, 0);
  588. }
  589. }
  590. pPropertyBag->Release();
  591. }
  592. }
  593. }
  594. }
  595. else if (_punkSite)
  596. {
  597. IThemeUIPages * pThemeUIPages;
  598. hr = _punkSite->QueryInterface(IID_PPV_ARG(IThemeUIPages, &pThemeUIPages));
  599. if (SUCCEEDED(hr))
  600. {
  601. hr = pThemeUIPages->UpdatePreview(0);
  602. }
  603. pThemeUIPages->Release();
  604. }
  605. if (_punkSite && fUpdateThemePage)
  606. {
  607. IPropertyBag * pPropertyBag;
  608. hr = _punkSite->QueryInterface(IID_PPV_ARG(IPropertyBag, &pPropertyBag));
  609. if (SUCCEEDED(hr))
  610. {
  611. // Tell the theme that we have customized the values.
  612. hr = SHPropertyBag_WriteInt(pPropertyBag, SZ_PBPROP_CUSTOMIZE_THEME, 0);
  613. pPropertyBag->Release();
  614. }
  615. }
  616. return hr;
  617. }
  618. INT_PTR CBaseAppearancePage::_OnCommand(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  619. {
  620. BOOL fHandled = 1; // Not handled (WM_COMMAND seems to be different)
  621. WORD idCtrl = GET_WM_COMMAND_ID(wParam, lParam);
  622. switch (idCtrl)
  623. {
  624. case IDC_APPG_COLORSCHEME:
  625. if(HIWORD(wParam) == CBN_SELCHANGE)
  626. {
  627. _OnStyleChange(hDlg);
  628. }
  629. break;
  630. case IDC_APPG_WNDSIZE:
  631. if(HIWORD(wParam) == CBN_SELCHANGE)
  632. {
  633. _OnSizeChange(hDlg);
  634. }
  635. break;
  636. case IDC_APPG_LOOKFEEL:
  637. if(HIWORD(wParam) == CBN_SELCHANGE)
  638. {
  639. _OnSchemeChange(hDlg, TRUE); // Display Error dialogs since the user is picking the visual style.
  640. }
  641. break;
  642. case IDC_APPG_EFFECTS: // This is the Effects button.
  643. _OnEffectsOptions(hDlg);
  644. break;
  645. case IDC_APPG_ADVANCED: // This is the Advanced button.
  646. _OnAdvancedOptions(hDlg);
  647. break;
  648. #ifdef DEBUG
  649. case IDC_APPG_TESTFAULT:
  650. _TestFault();
  651. break;
  652. #endif // DEBUG
  653. default:
  654. break;
  655. }
  656. return fHandled;
  657. }
  658. HRESULT CBaseAppearancePage::_OnSchemeChange(HWND hDlg, BOOL fDisplayErrors)
  659. {
  660. HRESULT hr = E_FAIL;
  661. int nIndex = ComboBox_GetCurSel(m_hwndSchemeDropDown);
  662. BOOL fPreviousSelectionIsVS = (!IUnknown_CompareCLSID(m_pSelectedThemeScheme, CLSID_LegacyAppearanceScheme));
  663. if (-1 == nIndex)
  664. {
  665. nIndex = 0; // The caller may NOT select nothing.
  666. }
  667. IThemeScheme * pThemeScheme = (IThemeScheme *) ComboBox_GetItemData(m_hwndSchemeDropDown, nIndex);
  668. m_fLoadedAdvState = FALSE; // Forget the state we previously loaded.
  669. m_advDlgState.dwChanged = (METRIC_CHANGE | COLOR_CHANGE | SCHEME_CHANGE);
  670. PropSheet_Changed(GetParent(hDlg), hDlg);
  671. if (pThemeScheme)
  672. {
  673. IUnknown_Set((IUnknown **)&m_pSelectedThemeScheme, pThemeScheme);
  674. }
  675. hr = _SetScheme(TRUE, TRUE, fPreviousSelectionIsVS);
  676. if (FAILED(hr))
  677. {
  678. if (fDisplayErrors)
  679. {
  680. // Displaying an error dialog when the visual style is selected is very important because
  681. // this is where we catch parse errors in the visual style.
  682. hr = DisplayThemeErrorDialog(hDlg, hr, IDS_ERROR_TITLE_LOAD_MSSTYLES_FAIL, IDS_ERROR_LOAD_MSSTYLES_FAIL);
  683. }
  684. }
  685. _EnableAdvancedButton();
  686. return hr;
  687. }
  688. HRESULT CBaseAppearancePage::_OutsideSetScheme(BSTR bstrScheme)
  689. {
  690. HRESULT hr = E_ACCESSDENIED;
  691. if (!m_fLockVisualStylePolicyEnabled)
  692. {
  693. hr = E_FAIL;
  694. BOOL fPreviousSelectionIsVS = !IUnknown_CompareCLSID(m_pSelectedThemeScheme, CLSID_LegacyAppearanceScheme);
  695. ATOMICRELEASE(m_pSelectedThemeScheme);
  696. if (bstrScheme && bstrScheme[0])
  697. {
  698. BOOL fVisualStylesSupported = (QueryThemeServicesWrap() & QTS_AVAILABLE);
  699. LogStatus("QueryThemeServices() returned %hs. In CBaseAppearancePage::_OutsideSetScheme\r\n", (fVisualStylesSupported ? "TRUE" : "FALSE"));
  700. // Do not load a visual style of themes do not work.
  701. if (fVisualStylesSupported)
  702. {
  703. if (PathFileExists(bstrScheme))
  704. {
  705. hr = CSkinScheme_CreateInstance(bstrScheme, &m_pSelectedThemeScheme);
  706. }
  707. else
  708. {
  709. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); // Them the caller that the theme service was not running.
  710. }
  711. }
  712. else
  713. {
  714. hr = HRESULT_FROM_WIN32(ERROR_SERVICE_NOT_ACTIVE); // Them the caller that the theme service was not running.
  715. }
  716. }
  717. else
  718. {
  719. hr = CAppearanceScheme_CreateInstance(NULL, IID_PPV_ARG(IThemeScheme, &m_pSelectedThemeScheme));
  720. }
  721. if (SUCCEEDED(hr))
  722. {
  723. // If we are displaying UI, update it.
  724. if (m_hwndSchemeDropDown)
  725. {
  726. CComBSTR bstrSelectedName;
  727. m_fIsDirty = TRUE;
  728. hr = m_pSelectedThemeScheme->get_DisplayName(&bstrSelectedName);
  729. if (SUCCEEDED(hr))
  730. {
  731. int nIndex = ComboBox_FindString(m_hwndSchemeDropDown, 0, bstrSelectedName);
  732. ComboBox_SetCurSel(m_hwndSchemeDropDown, nIndex);
  733. }
  734. }
  735. if (SUCCEEDED(hr))
  736. {
  737. hr = _SetScheme(FALSE, FALSE, fPreviousSelectionIsVS);
  738. }
  739. }
  740. }
  741. return hr;
  742. }
  743. /*****************************************************************************\
  744. DESCRIPTION:
  745. The caller just loaded a new value into m_pSelectedThemeScheme. Now
  746. load good default values into m_pSelectedStyle and m_pSelectedSize.
  747. Then this is called, the UI may or may not be displayed. Either the user made a change in
  748. the dropdown in this tab or the Theme page is setting our values.
  749. PARAMETERS:
  750. fLoadSystemMetrics: If true, we load the system metrics from the scheme. If false,
  751. we simply select that as the name for the drop down when we let the caller
  752. push the system metrics into us.
  753. fLoadLiveSettings: When the user switches from Skin->NoSkin, do we want to
  754. load custom settings they had before they switched?
  755. \*****************************************************************************/
  756. HRESULT CBaseAppearancePage::_SetScheme(IN BOOL fLoadSystemMetrics, IN BOOL fLoadLiveSettings, IN BOOL fPreviousSelectionIsVS)
  757. {
  758. HRESULT hr = E_FAIL;
  759. if (m_pSelectedThemeScheme)
  760. {
  761. // Now that they choose a different VisualStyle (Scheme), we want to select the new Color Style
  762. // and Size in that Scheme.
  763. // will fall back to the first ColorStyle.
  764. CComBSTR bstrSelectedStyle;
  765. CComBSTR bstrSelectedSize;
  766. if (m_pSelectedStyle) // This will be empty if someone deletes the current .msstyles file.
  767. {
  768. hr = m_pSelectedStyle->get_DisplayName(&bstrSelectedStyle);
  769. }
  770. if (m_pSelectedSize)
  771. {
  772. hr = m_pSelectedSize->get_DisplayName(&bstrSelectedSize);
  773. }
  774. ATOMICRELEASE(m_pSelectedStyle);
  775. ATOMICRELEASE(m_pSelectedSize);
  776. CComVariant varNameBSTR(bstrSelectedStyle);
  777. // We prefer to get the ColorStyle with the same name as the previously selected one.
  778. hr = m_pSelectedThemeScheme->get_item(varNameBSTR, &m_pSelectedStyle);
  779. if (FAILED(hr))
  780. {
  781. // If that failed to return a value, then we will try to get the default ColorStyle.
  782. hr = m_pSelectedThemeScheme->get_SelectedStyle(&m_pSelectedStyle);
  783. if (FAILED(hr))
  784. {
  785. // If that failed then we will just pick the first ColorStyles. (Beggers can't be choosers)
  786. VARIANT varIndex;
  787. varIndex.vt = VT_I4;
  788. varIndex.lVal = 0;
  789. hr = m_pSelectedThemeScheme->get_item(varIndex, &m_pSelectedStyle);
  790. }
  791. }
  792. if (m_pSelectedStyle)
  793. {
  794. varNameBSTR = bstrSelectedSize;
  795. // Now we want to repeat this process with the size.
  796. // We prefer to get the ColorStyle with the same name as the previously selected one.
  797. hr = m_pSelectedStyle->get_item(varNameBSTR, &m_pSelectedSize);
  798. if (FAILED(hr))
  799. {
  800. // If that failed to return a value, then we will try to get the default ColorStyle.
  801. hr = m_pSelectedStyle->get_SelectedSize(&m_pSelectedSize);
  802. if (FAILED(hr))
  803. {
  804. // If that failed then we will just pick the first ColorStyles. (Beggers can't be choosers)
  805. VARIANT varIndex;
  806. varIndex.vt = VT_I4;
  807. varIndex.lVal = 0;
  808. hr = m_pSelectedStyle->get_item(varIndex, &m_pSelectedSize);
  809. }
  810. }
  811. }
  812. hr = _PopulateStyleDropdown();
  813. hr = _PopulateSizeDropdown();
  814. BOOL fStateLoaded = FALSE;
  815. BOOL fIsThemeActive = IsThemeActive();
  816. LogStatus("IsThemeActive() returned %hs. In CBaseAppearancePage::_SetScheme\r\n", (fIsThemeActive ? "TRUE" : "FALSE"));
  817. // If the user switched from a skin to "NoSkin", then we want to load the settings from the settings
  818. // chosen before the user chose the skin.
  819. if (fIsThemeActive && // Was a skin last applied?
  820. fLoadLiveSettings && // Do we want to load live settings?
  821. IUnknown_CompareCLSID(m_pSelectedThemeScheme, CLSID_LegacyAppearanceScheme) && // Is the new selection a "No Skin"?
  822. !m_fLoadedAdvState) // Have we not yet loaded these setting?
  823. {
  824. // We want to load the last set of customized settings....
  825. if (SUCCEEDED(_LoadLiveSettings(SZ_SAVEGROUP_NOSKIN)))
  826. {
  827. fStateLoaded = TRUE;
  828. }
  829. }
  830. // We don't want to load the state if the change came from the outside
  831. // because they will load the state themselves.
  832. if (fLoadSystemMetrics && !fStateLoaded)
  833. {
  834. hr = SystemMetricsAll_Load(m_pSelectedSize, &m_advDlgState, &m_nNewDPI);
  835. if (SUCCEEDED(hr))
  836. {
  837. m_fLoadedAdvState = TRUE;
  838. }
  839. }
  840. m_advDlgState.dwChanged = (METRIC_CHANGE | COLOR_CHANGE | SCHEME_CHANGE);
  841. if (SUCCEEDED(hr))
  842. {
  843. hr = _UpdatePreview(fLoadSystemMetrics);
  844. if (!fPreviousSelectionIsVS &&
  845. !IUnknown_CompareCLSID(m_pSelectedThemeScheme, CLSID_LegacyAppearanceScheme))
  846. {
  847. IPropertyBag * pEffectsBag;
  848. // Whenever we turn on a visual style and a visual style was previously off,
  849. // turn on "Menu Drop Shadows".
  850. if (SUCCEEDED(_GetPageByCLSID(&PPID_Effects, &pEffectsBag)))
  851. {
  852. SHPropertyBag_WriteBOOL(pEffectsBag, SZ_PBPROP_EFFECTS_MENUDROPSHADOWS, VARIANT_TRUE);
  853. pEffectsBag->Release();
  854. }
  855. }
  856. }
  857. }
  858. return hr;
  859. }
  860. HRESULT CBaseAppearancePage::_OnStyleChange(HWND hDlg)
  861. {
  862. int nIndex = ComboBox_GetCurSel(m_hwndStyleDropDown);
  863. m_fLoadedAdvState = FALSE; // Forget the state we previously loaded.
  864. m_advDlgState.dwChanged = (METRIC_CHANGE | COLOR_CHANGE | SCHEME_CHANGE);
  865. PropSheet_Changed(GetParent(hDlg), hDlg);
  866. if (-1 == nIndex)
  867. {
  868. nIndex = 0; // The caller may NOT select nothing.
  869. }
  870. IThemeStyle * pThemeStyle = (IThemeStyle *) ComboBox_GetItemData(m_hwndStyleDropDown, nIndex);
  871. AssertMsg((NULL != pThemeStyle), TEXT("We need pThemeStyle"));
  872. if (pThemeStyle)
  873. {
  874. IUnknown_Set((IUnknown **)&m_pSelectedStyle, pThemeStyle);
  875. }
  876. return _SetStyle(TRUE);
  877. }
  878. HRESULT CBaseAppearancePage::_OutsideSetStyle(BSTR bstrStyle)
  879. {
  880. HRESULT hr = E_FAIL;
  881. AssertMsg((NULL != m_pSelectedThemeScheme), TEXT("We need m_pSelectedThemeScheme"));
  882. if (m_pSelectedThemeScheme)
  883. {
  884. IThemeStyle * pSelectedStyle;
  885. CComVariant varNameBSTR(bstrStyle);
  886. m_fIsDirty = TRUE;
  887. hr = m_pSelectedThemeScheme->get_item(varNameBSTR, &pSelectedStyle);
  888. if (SUCCEEDED(hr))
  889. {
  890. ATOMICRELEASE(m_pSelectedStyle);
  891. m_pSelectedStyle = pSelectedStyle;
  892. // If we are displaying UI, update it.
  893. if (m_hwndStyleDropDown)
  894. {
  895. CComBSTR bstrSelectedName;
  896. hr = m_pSelectedStyle->get_DisplayName(&bstrSelectedName);
  897. if (SUCCEEDED(hr))
  898. {
  899. int nIndex = ComboBox_FindString(m_hwndStyleDropDown, 0, bstrSelectedName);
  900. ComboBox_SetCurSel(m_hwndStyleDropDown, nIndex);
  901. }
  902. }
  903. hr = _SetStyle(FALSE);
  904. }
  905. }
  906. return hr;
  907. }
  908. HRESULT CBaseAppearancePage::_SetStyle(IN BOOL fUpdateThemePage)
  909. {
  910. HRESULT hr = E_FAIL;
  911. AssertMsg((m_pSelectedSize && m_pSelectedSize), TEXT("We need m_pSelectedSize && m_pSelectedSize"));
  912. if (m_pSelectedSize && m_pSelectedSize)
  913. {
  914. // Now that they choose a different style, we want to select the new size
  915. // in that style. We prefer to get the size with the same name but will
  916. // will fall back to the first style.
  917. CComBSTR bstrSelectedSize;
  918. hr = m_pSelectedSize->get_DisplayName(&bstrSelectedSize);
  919. ATOMICRELEASE(m_pSelectedSize);
  920. CComVariant varNameBSTR(bstrSelectedSize);
  921. hr = m_pSelectedStyle->get_item(varNameBSTR, &m_pSelectedSize);
  922. if (FAILED(hr))
  923. {
  924. VARIANT varIndex;
  925. varIndex.vt = VT_I4;
  926. varIndex.lVal = 0;
  927. hr = m_pSelectedStyle->get_item(varIndex, &m_pSelectedSize);
  928. }
  929. hr = _PopulateSizeDropdown();
  930. if (fUpdateThemePage && SUCCEEDED(SystemMetricsAll_Load(m_pSelectedSize, &m_advDlgState, &m_nNewDPI)))
  931. {
  932. m_fLoadedAdvState = TRUE;
  933. m_advDlgState.dwChanged = (METRIC_CHANGE | COLOR_CHANGE | SCHEME_CHANGE);
  934. }
  935. if (SUCCEEDED(hr))
  936. {
  937. hr = _UpdatePreview(fUpdateThemePage);
  938. }
  939. }
  940. return hr;
  941. }
  942. HRESULT CBaseAppearancePage::_OnSizeChange(HWND hDlg)
  943. {
  944. int nIndex = ComboBox_GetCurSel(m_hwndSizeDropDown);
  945. PropSheet_Changed(GetParent(hDlg), hDlg);
  946. if (-1 == nIndex)
  947. {
  948. nIndex = 0; // The caller may NOT select nothing.
  949. }
  950. IThemeSize * pThemeSize = (IThemeSize *) ComboBox_GetItemData(m_hwndSizeDropDown, nIndex);
  951. AssertMsg((NULL != pThemeSize), TEXT("We need pThemeSize"));
  952. if (pThemeSize)
  953. {
  954. IUnknown_Set((IUnknown **)&m_pSelectedSize, pThemeSize);
  955. }
  956. return _SetSize(TRUE, TRUE);
  957. }
  958. HRESULT CBaseAppearancePage::_OutsideSetSize(BSTR bstrSize)
  959. {
  960. HRESULT hr = E_FAIL;
  961. AssertMsg((m_pSelectedThemeScheme && m_pSelectedStyle), TEXT("We need m_pSelectedThemeScheme && m_pSelectedStyle"));
  962. if (m_pSelectedThemeScheme && m_pSelectedStyle)
  963. {
  964. IThemeSize * pSelectedSize;
  965. CComVariant varNameBSTR(bstrSize);
  966. m_fIsDirty = TRUE;
  967. hr = m_pSelectedStyle->get_item(varNameBSTR, &pSelectedSize);
  968. if (SUCCEEDED(hr))
  969. {
  970. ATOMICRELEASE(m_pSelectedSize);
  971. m_pSelectedSize = pSelectedSize;
  972. // If we are displaying UI, update it.
  973. if (m_hwndSizeDropDown)
  974. {
  975. CComBSTR bstrSelectedName;
  976. hr = m_pSelectedSize->get_DisplayName(&bstrSelectedName);
  977. if (SUCCEEDED(hr))
  978. {
  979. int nIndex = ComboBox_FindString(m_hwndSizeDropDown, 0, bstrSelectedName);
  980. ComboBox_SetCurSel(m_hwndSizeDropDown, nIndex);
  981. }
  982. }
  983. hr = _SetSize(TRUE, FALSE);
  984. }
  985. }
  986. return hr;
  987. }
  988. HRESULT CBaseAppearancePage::_SetSize(IN BOOL fLoadSystemMetrics, IN BOOL fUpdateThemePage)
  989. {
  990. HRESULT hr = E_FAIL;
  991. AssertMsg((NULL != m_pSelectedSize), TEXT("We need m_pSelectedSize"));
  992. if (m_pSelectedSize)
  993. {
  994. hr = S_OK;
  995. // SystemMetricsAll_Load() will fail if m_pSelectedSize is a .msstyles file.
  996. if (fLoadSystemMetrics)
  997. {
  998. if (SUCCEEDED(SystemMetricsAll_Load(m_pSelectedSize, &m_advDlgState, &m_nNewDPI)))
  999. {
  1000. m_fLoadedAdvState = TRUE;
  1001. m_advDlgState.dwChanged = (METRIC_CHANGE | COLOR_CHANGE | SCHEME_CHANGE);
  1002. }
  1003. else
  1004. {
  1005. m_fLoadedAdvState = FALSE;
  1006. }
  1007. }
  1008. if (SUCCEEDED(hr))
  1009. {
  1010. hr = _UpdatePreview(fUpdateThemePage);
  1011. }
  1012. }
  1013. return hr;
  1014. }
  1015. HRESULT CBaseAppearancePage::_GetPageByCLSID(const GUID * pClsid, IPropertyBag ** ppPropertyBag)
  1016. {
  1017. HRESULT hr = E_FAIL;
  1018. *ppPropertyBag = NULL;
  1019. if (_punkSite)
  1020. {
  1021. IThemeUIPages * pThemeUI;
  1022. hr = _punkSite->QueryInterface(IID_PPV_ARG(IThemeUIPages, &pThemeUI));
  1023. if (SUCCEEDED(hr))
  1024. {
  1025. IEnumUnknown * pEnumUnknown;
  1026. hr = pThemeUI->GetBasePagesEnum(&pEnumUnknown);
  1027. if (SUCCEEDED(hr))
  1028. {
  1029. IUnknown * punk;
  1030. // This may not exit due to policy
  1031. hr = IEnumUnknown_FindCLSID(pEnumUnknown, *pClsid, &punk);
  1032. if (SUCCEEDED(hr))
  1033. {
  1034. hr = punk->QueryInterface(IID_PPV_ARG(IPropertyBag, ppPropertyBag));
  1035. punk->Release();
  1036. }
  1037. pEnumUnknown->Release();
  1038. }
  1039. pThemeUI->Release();
  1040. }
  1041. }
  1042. return hr;
  1043. }
  1044. HRESULT CBaseAppearancePage::_OnSetActive(HWND hDlg)
  1045. {
  1046. #ifdef READ_3D_RULES_FROM_REGISTRY
  1047. Look_Reset3DRatios();
  1048. #endif
  1049. _LoadState();
  1050. _EnableAdvancedButton();
  1051. _ScaleSizesSinceDPIChanged(); // We want to update our settings if someone changed the DPI
  1052. return S_OK;
  1053. }
  1054. HRESULT CBaseAppearancePage::_OnApply(HWND hDlg, LPARAM lParam)
  1055. {
  1056. // Our parent dialog will be notified of the Apply event and will call our
  1057. // IBasePropPage::OnApply() to do the real work.
  1058. return S_OK;
  1059. }
  1060. // This Property Sheet appear in the top level of the "Display Control Panel".
  1061. INT_PTR CBaseAppearancePage::_BaseAppearanceDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  1062. {
  1063. NMHDR FAR *lpnm;
  1064. switch(message)
  1065. {
  1066. case WM_NOTIFY:
  1067. lpnm = (NMHDR FAR *)lParam;
  1068. switch(lpnm->code)
  1069. {
  1070. case PSN_SETACTIVE:
  1071. _OnSetActive(hDlg);
  1072. break;
  1073. case PSN_APPLY:
  1074. _OnApply(hDlg, lParam);
  1075. break;
  1076. case PSN_RESET:
  1077. break;
  1078. }
  1079. break;
  1080. case WM_INITDIALOG:
  1081. _OnInitAppearanceDlg(hDlg);
  1082. break;
  1083. case WM_DESTROY:
  1084. _OnDestroy(hDlg);
  1085. break;
  1086. case WM_HELP:
  1087. WinHelp((HWND) ((LPHELPINFO) lParam)->hItemHandle, SZ_HELPFILE_BASEAPPEARANCE, HELP_WM_HELP, (DWORD_PTR) aBaseAppearanceHelpIds);
  1088. break;
  1089. case WM_CONTEXTMENU: // right mouse click
  1090. WinHelp((HWND) wParam, SZ_HELPFILE_BASEAPPEARANCE, HELP_CONTEXTMENU, (DWORD_PTR) aBaseAppearanceHelpIds);
  1091. break;
  1092. case WM_COMMAND:
  1093. _OnCommand(hDlg, message, wParam, lParam);
  1094. break;
  1095. case WMUSER_DELAYENABLEAPPLY:
  1096. EnableApplyButton(hDlg);
  1097. break;
  1098. }
  1099. return FALSE;
  1100. }
  1101. HRESULT CBaseAppearancePage::_LoadState(void)
  1102. {
  1103. HRESULT hr = S_OK;
  1104. if (!m_fLoadedAdvState)
  1105. {
  1106. m_advDlgState.dwChanged = NO_CHANGE;
  1107. if (m_pSelectedThemeScheme && m_pSelectedStyle && m_pSelectedSize)
  1108. {
  1109. hr = SystemMetricsAll_Load(m_pSelectedSize, &m_advDlgState, &m_nNewDPI);
  1110. if (SUCCEEDED(hr))
  1111. {
  1112. m_fLoadedAdvState = TRUE;
  1113. }
  1114. }
  1115. else
  1116. {
  1117. hr = E_FAIL;
  1118. }
  1119. }
  1120. return hr;
  1121. }
  1122. BOOL IsSkinScheme(IN IThemeScheme * pThemeScheme)
  1123. {
  1124. BOOL fIsSkin = !IUnknown_CompareCLSID(pThemeScheme, CLSID_LegacyAppearanceScheme);
  1125. return fIsSkin;
  1126. }
  1127. /*****************************************************************************\
  1128. DESCRIPTION:
  1129. This method will turn on or off the visual style.
  1130. \*****************************************************************************/
  1131. HRESULT CBaseAppearancePage::_ApplyScheme(IThemeScheme * pThemeScheme, IThemeStyle * pColorStyle, IThemeSize * pThemeSize)
  1132. {
  1133. HRESULT hr = E_INVALIDARG;
  1134. if (pThemeScheme && pColorStyle && pThemeSize)
  1135. {
  1136. hr = pColorStyle->put_SelectedSize(pThemeSize);
  1137. if (SUCCEEDED(hr))
  1138. {
  1139. hr = pThemeScheme->put_SelectedStyle(pColorStyle);
  1140. if (SUCCEEDED(hr))
  1141. {
  1142. CComBSTR bstrPath;
  1143. if (IsSkinScheme(pThemeScheme) &&
  1144. SUCCEEDED(hr = pThemeScheme->get_Path(&bstrPath)) &&
  1145. SUCCEEDED(CheckThemeSignature(bstrPath)))
  1146. {
  1147. CComBSTR bstrStyle;
  1148. hr = pColorStyle->get_Name(&bstrStyle);
  1149. if (SUCCEEDED(hr))
  1150. {
  1151. CComBSTR bstrSize;
  1152. hr = pThemeSize->get_Name(&bstrSize);
  1153. if (SUCCEEDED(hr))
  1154. {
  1155. hr = ApplyVisualStyle(bstrPath, bstrStyle, bstrSize);
  1156. if (FAILED(hr))
  1157. {
  1158. HWND hwndParent = NULL;
  1159. // We want to display UI if an error occured here. We want to do
  1160. // it instead of our parent because THEMELOADPARAMS contains
  1161. // extra error information that we can't pass back to the caller.
  1162. // However, we will only display error UI if our caller wants us
  1163. // to. We determine that by the fact that they make an hwnd available
  1164. // to us. We get the hwnd by getting our site pointer and getting
  1165. // the hwnd via ::GetWindow().
  1166. if (_punkSite && SUCCEEDED(IUnknown_GetWindow(_punkSite, &hwndParent)))
  1167. {
  1168. hr = DisplayThemeErrorDialog(hwndParent, hr, IDS_ERROR_TITLE_APPLYBASEAPPEARANCE, IDS_ERROR_APPLYBASEAPPEARANCE_LOADTHEME);
  1169. }
  1170. }
  1171. }
  1172. }
  1173. }
  1174. else
  1175. {
  1176. // Unload any existing skin.
  1177. hr = ApplyVisualStyle(NULL, NULL, NULL);
  1178. #ifndef ENABLE_IA64_VISUALSTYLES
  1179. // We don't support themes on non-x86 don't ignore the error value.
  1180. hr = S_OK;
  1181. #endif // ENABLE_IA64_VISUALSTYLES
  1182. }
  1183. IPropertyBag * pPropertyBag;
  1184. if (SUCCEEDED(pThemeSize->QueryInterface(IID_PPV_ARG(IPropertyBag, &pPropertyBag))))
  1185. {
  1186. TCHAR szLegacyName[MAX_PATH];
  1187. // Here, we need to update a regkey with the selected legacy name. That way we can tell if
  1188. // 3rd party UI or downlevel OSs change the Win2k "Appearance Scheme". If they do, uxtheme (LMouton)
  1189. // will disable visual styles on the next login. This will make sure we don't get someone else's
  1190. // NONCLIENTMETRICS and our visual style.
  1191. if (FAILED(SHPropertyBag_ReadStr(pPropertyBag, SZ_PBPROP_COLORSCHEME_LEGACYNAME, szLegacyName, ARRAYSIZE(szLegacyName))))
  1192. {
  1193. szLegacyName[0] = 0;
  1194. }
  1195. HrRegSetValueString(HKEY_CURRENT_USER, SZ_REGKEY_APPEARANCE, THEMEPROP_NEWCURRSCHEME, szLegacyName);
  1196. HrRegSetValueString(HKEY_CURRENT_USER, SZ_REGKEY_APPEARANCE, SZ_REGVALUE_CURRENT, szLegacyName);
  1197. pPropertyBag->Release();
  1198. }
  1199. }
  1200. }
  1201. }
  1202. return hr;
  1203. }
  1204. HRESULT CBaseAppearancePage::_SaveState(CDimmedWindow* pDimmedWindow)
  1205. {
  1206. HRESULT hr = S_OK;
  1207. BOOL fIsSkinApplied = IsThemeActive(); // This will keep track if a skin was applied before this apply action.
  1208. LogStatus("IsThemeActive() returned %hs in CBaseAppearancePage::_SaveState.\r\n", (fIsSkinApplied ? "TRUE" : "FALSE"));
  1209. // If we are switching from NoSkin->Skin, we want to save the live settings before
  1210. // we turn on the skin (now & here). We do this so we can reload these settings
  1211. // if the user turns Skins off later. This acts like a "Custom" settings option.
  1212. if (!fIsSkinApplied && !IUnknown_CompareCLSID(m_pSelectedThemeScheme, CLSID_LegacyAppearanceScheme))
  1213. {
  1214. hr = _SaveLiveSettings(SZ_SAVEGROUP_NOSKIN); // If we are switching from "NoSkin" to "Skin", we want to save the custom settings now.
  1215. }
  1216. hr = _ApplyScheme(m_pSelectedThemeScheme, m_pSelectedStyle, m_pSelectedSize);
  1217. if (SUCCEEDED(hr))
  1218. {
  1219. m_nSelectedScheme = ComboBox_GetCurSel(m_hwndSchemeDropDown);
  1220. m_nSelectedStyle = ComboBox_GetCurSel(m_hwndStyleDropDown);
  1221. m_nSelectedSize = ComboBox_GetCurSel(m_hwndSizeDropDown);
  1222. }
  1223. if (SUCCEEDED(hr))
  1224. {
  1225. // Here we save the settings no matter which direction we are going. These
  1226. // settings will be loaded when the Display Control Panel is opened next time.
  1227. hr = _SaveLiveSettings(SZ_SAVEGROUP_ALL);
  1228. }
  1229. // We normally want the call to IThemeManager->put_SelectedScheme() to not only
  1230. // store the selection but to also update the live system metrics. We special case
  1231. // the Legacy "Appearance Schemes" because the user could have customized the
  1232. // settings in the Advanced Appearance dialog. If they did, then m_advDlgState.dwChanged
  1233. // will have dirty bits set and we need to apply that state ourselves.
  1234. if (m_advDlgState.dwChanged)
  1235. {
  1236. hr = SystemMetricsAll_Set(&m_advDlgState, pDimmedWindow);
  1237. LogSystemMetrics("CBaseAppearancePage::_SaveState() pushing to live", &m_advDlgState);
  1238. }
  1239. if (SUCCEEDED(hr))
  1240. {
  1241. m_advDlgState.dwChanged = NO_CHANGE;
  1242. m_fIsDirty = FALSE;
  1243. }
  1244. return hr;
  1245. }
  1246. // If we are switching from "NoSkin" to "Skin", we want to save the custom settings now.
  1247. HRESULT CBaseAppearancePage::_LoadLiveSettings(IN LPCWSTR pszSaveGroup)
  1248. {
  1249. HRESULT hr = S_OK;
  1250. if (!m_fLoadedAdvState)
  1251. {
  1252. #ifndef FEATURE_SAVECUSTOM_APPEARANCE
  1253. if (!StrCmpI(pszSaveGroup, SZ_SAVEGROUP_ALL))
  1254. {
  1255. SystemMetricsAll_Get(&m_advDlgState);
  1256. LogSystemMetrics("LOADING SYSMETRICS: ", &m_advDlgState);
  1257. m_fLoadedAdvState = TRUE;
  1258. }
  1259. else
  1260. {
  1261. hr = E_FAIL; // The caller needs to get their own system metrics.
  1262. }
  1263. #else // FEATURE_SAVECUSTOM_APPEARANCE
  1264. AssertMsg((NULL != m_pSelectedThemeScheme), TEXT("_LoadLiveSettings() can't get it's job done without m_pSelectedThemeScheme"));
  1265. if (m_pSelectedThemeScheme)
  1266. {
  1267. IThemeScheme * pThemeScheme;
  1268. hr = CAppearanceScheme_CreateInstance(NULL, IID_PPV_ARG(IThemeScheme, &pThemeScheme));
  1269. if (SUCCEEDED(hr))
  1270. {
  1271. CComVariant varCurrentNameBSTR(pszSaveGroup);
  1272. IThemeStyle * pSelectedStyle;
  1273. // The next call may fail because we may have never saved the settings yet.
  1274. hr = pThemeScheme->get_item(varCurrentNameBSTR, &pSelectedStyle);
  1275. if (FAILED(hr))
  1276. {
  1277. // So, let's save the settings now.
  1278. hr = _SaveLiveSettings(pszSaveGroup);
  1279. if (SUCCEEDED(hr))
  1280. {
  1281. hr = m_pSelectedThemeScheme->get_item(varCurrentNameBSTR, &pSelectedStyle);
  1282. }
  1283. }
  1284. if (SUCCEEDED(hr))
  1285. {
  1286. IThemeSize * pSelectedSize;
  1287. VARIANT varIndex;
  1288. varIndex.vt = VT_I4;
  1289. varIndex.lVal = 0;
  1290. hr = pSelectedStyle->get_item(varIndex, &pSelectedSize);
  1291. if (FAILED(hr))
  1292. {
  1293. HKEY hKeyTemp;
  1294. if (SUCCEEDED(HrRegOpenKeyEx(HKEY_CURRENT_USER, SZ_REGKEY_UPGRADE_KEY, 0, KEY_READ, &hKeyTemp)))
  1295. {
  1296. RegCloseKey(hKeyTemp);
  1297. }
  1298. else
  1299. {
  1300. // If this happens, we may not have saved the previous settings. So do that now
  1301. // and retry.
  1302. _SaveLiveSettings(pszSaveGroup);
  1303. hr = pSelectedStyle->get_item(varIndex, &pSelectedSize);
  1304. }
  1305. }
  1306. if (SUCCEEDED(hr))
  1307. {
  1308. if (SUCCEEDED(SystemMetricsAll_Load(pSelectedSize, &m_advDlgState, &m_nNewDPI)))
  1309. {
  1310. LogSystemMetrics("LOADING SYSMETRICS: ", &m_advDlgState);
  1311. m_fLoadedAdvState = TRUE;
  1312. }
  1313. pSelectedSize->Release();
  1314. }
  1315. pSelectedStyle->Release();
  1316. }
  1317. pThemeScheme->Release();
  1318. }
  1319. }
  1320. else
  1321. {
  1322. hr = E_FAIL;
  1323. }
  1324. #endif // FEATURE_SAVECUSTOM_APPEARANCE
  1325. }
  1326. return hr;
  1327. }
  1328. HRESULT CBaseAppearancePage::_SaveLiveSettings(IN LPCWSTR pszSaveGroup)
  1329. {
  1330. HRESULT hr = S_OK;
  1331. // Now, get the current (possibly custom) settings and save them.
  1332. SYSTEMMETRICSALL state = {0};
  1333. hr = SystemMetricsAll_Get(&state);
  1334. if (SUCCEEDED(hr))
  1335. {
  1336. IThemeScheme * pThemeScheme;
  1337. LogSystemMetrics("CBaseAppearancePage::_SaveLiveSettings() getting live", &state);
  1338. hr = CAppearanceScheme_CreateInstance(NULL, IID_PPV_ARG(IThemeScheme, &pThemeScheme));
  1339. if (SUCCEEDED(hr))
  1340. {
  1341. CComVariant varCurrentNameBSTR(pszSaveGroup); // The "Customized Live" item
  1342. IThemeStyle * pSelectedStyle;
  1343. hr = pThemeScheme->get_item(varCurrentNameBSTR, &pSelectedStyle);
  1344. if (SUCCEEDED(hr))
  1345. {
  1346. IThemeSize * pSelectedSize;
  1347. VARIANT varIndex;
  1348. varIndex.vt = VT_I4;
  1349. varIndex.lVal = 0;
  1350. hr = pSelectedStyle->get_item(varIndex, &pSelectedSize);
  1351. if (FAILED(hr))
  1352. {
  1353. hr = pSelectedStyle->AddSize(&pSelectedSize);
  1354. }
  1355. if (SUCCEEDED(hr))
  1356. {
  1357. hr = SystemMetricsAll_Save(&state, pSelectedSize, &m_nNewDPI);
  1358. CHAR szTemp[MAX_PATH];
  1359. wnsprintfA(szTemp, ARRAYSIZE(szTemp), "CBaseAppearancePage::_SaveLiveSettings() Grp=\"%ls\", new DPI=%d", pszSaveGroup, m_nNewDPI);
  1360. LogSystemMetrics(szTemp, &state);
  1361. pSelectedSize->Release();
  1362. }
  1363. pSelectedStyle->Release();
  1364. }
  1365. pThemeScheme->Release();
  1366. }
  1367. }
  1368. return hr;
  1369. }
  1370. HRESULT CBaseAppearancePage::_LoadVisaulStyleFile(IN LPCWSTR pszPath)
  1371. {
  1372. HRESULT hr = E_FAIL;
  1373. if (SUCCEEDED(CheckThemeSignature(pszPath)))
  1374. {
  1375. // Now we want to:
  1376. int nSlot = -1;
  1377. int nCount = ComboBox_GetCount(m_hwndSchemeDropDown);
  1378. hr = S_OK;
  1379. // 1. Is it in the list already?
  1380. for (int nIndex = 0; nIndex < nCount; nIndex++)
  1381. {
  1382. IThemeScheme * pThemeScheme = (IThemeScheme *) ComboBox_GetItemData(m_hwndSchemeDropDown, nIndex);
  1383. if (pThemeScheme)
  1384. {
  1385. CComBSTR bstrPath;
  1386. hr = pThemeScheme->get_Path(&bstrPath);
  1387. if (SUCCEEDED(hr))
  1388. {
  1389. if (!StrCmpIW(bstrPath, pszPath))
  1390. {
  1391. bstrPath.Empty();
  1392. // We found it, so stop looking.
  1393. nSlot = nIndex;
  1394. break;
  1395. }
  1396. }
  1397. }
  1398. }
  1399. // 2. If it is not in the list, add it. We put it on the bottom, right above "Other...".
  1400. if (-1 == nSlot)
  1401. {
  1402. IThemeScheme * pThemeSchemeNew;
  1403. hr = CSkinScheme_CreateInstance(pszPath, &pThemeSchemeNew);
  1404. if (SUCCEEDED(hr))
  1405. {
  1406. CComBSTR bstrDisplayName;
  1407. hr = pThemeSchemeNew->get_DisplayName(&bstrDisplayName);
  1408. if (SUCCEEDED(hr))
  1409. {
  1410. nIndex = ComboBox_GetCount(m_hwndSchemeDropDown);
  1411. if (nIndex > 1)
  1412. {
  1413. nIndex -= 1;
  1414. }
  1415. nSlot = nIndex = ComboBox_InsertString(m_hwndSchemeDropDown, nIndex, bstrDisplayName);
  1416. if ((CB_ERR != nIndex) && (CB_ERRSPACE != nIndex))
  1417. {
  1418. if (CB_ERR == ComboBox_SetItemData(m_hwndSchemeDropDown, nIndex, pThemeSchemeNew))
  1419. {
  1420. hr = E_FAIL;
  1421. }
  1422. }
  1423. else
  1424. {
  1425. hr = E_OUTOFMEMORY;
  1426. }
  1427. }
  1428. if (FAILED(hr))
  1429. {
  1430. pThemeSchemeNew->Release();
  1431. }
  1432. }
  1433. }
  1434. if (-1 != nSlot)
  1435. {
  1436. ComboBox_SetCurSel(m_hwndSchemeDropDown, nIndex);
  1437. // 3. Select the theme from the list.
  1438. if (CB_ERR != ComboBox_GetItemData(m_hwndSchemeDropDown, ComboBox_GetCurSel(m_hwndSchemeDropDown)))
  1439. {
  1440. // Okay, we now know we won't recurse infinitely, so let's recurse.
  1441. hr = _OnSchemeChange(_hwnd, FALSE); // FALSE means don't display error dialogs
  1442. if (SUCCEEDED(hr))
  1443. {
  1444. // Since this happens during WM_INITDIALOG, we need to delay enabling the Apply button.
  1445. DelayEnableApplyButton(_hwnd);
  1446. }
  1447. }
  1448. else
  1449. {
  1450. hr = E_FAIL;
  1451. AssertMsg(0, TEXT("We should have correctly selected the item. Please investiate. -BryanSt"));
  1452. }
  1453. }
  1454. else
  1455. {
  1456. hr = E_FAIL;
  1457. }
  1458. }
  1459. return hr;
  1460. }
  1461. //===========================
  1462. // *** IObjectWithSite Interface ***
  1463. //===========================
  1464. HRESULT CBaseAppearancePage::SetSite(IN IUnknown *punkSite)
  1465. {
  1466. if (!punkSite)
  1467. {
  1468. ATOMICRELEASE(m_pThemeManager); // This is a copy of our _punkSite and we need to break the cycle.
  1469. }
  1470. HRESULT hr = CObjectWithSite::SetSite(punkSite);
  1471. if (punkSite)
  1472. {
  1473. // Load the defaults so we will have them if another base tab opens the advanced dlg.
  1474. _OnInitData();
  1475. }
  1476. return hr;
  1477. }
  1478. //===========================
  1479. // *** IPreviewSystemMetrics Interface ***
  1480. //===========================
  1481. HRESULT CBaseAppearancePage::RefreshColors(void)
  1482. {
  1483. UINT i;
  1484. HKEY hk;
  1485. TCHAR szColor[15];
  1486. DWORD dwSize, dwType;
  1487. int iColors[COLOR_MAX];
  1488. COLORREF rgbColors[COLOR_MAX];
  1489. // Open the Colors key in the registry
  1490. if (RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_COLORS, 0, KEY_READ, &hk) != ERROR_SUCCESS)
  1491. {
  1492. return S_OK;
  1493. }
  1494. // Query for the color information
  1495. for (i = 0; i < ARRAYSIZE(s_pszColorNames); i++)
  1496. {
  1497. dwSize = 15 * sizeof(TCHAR);
  1498. if ((RegQueryValueEx(hk, s_pszColorNames[i], NULL, &dwType, (LPBYTE) szColor, &dwSize) == ERROR_SUCCESS) &&
  1499. (REG_SZ == dwType))
  1500. {
  1501. m_advDlgState.schemeData.rgb[i] = ConvertColor(szColor);
  1502. }
  1503. else
  1504. {
  1505. m_advDlgState.schemeData.rgb[i] = GetSysColor(i);
  1506. }
  1507. }
  1508. RegCloseKey(hk);
  1509. // This call causes user to send a WM_SYSCOLORCHANGE
  1510. for (i=0; i < ARRAYSIZE(rgbColors); i++)
  1511. {
  1512. iColors[i] = i;
  1513. rgbColors[i] = m_advDlgState.schemeData.rgb[i] & 0x00FFFFFF;
  1514. }
  1515. SetSysColors(ARRAYSIZE(rgbColors), iColors, rgbColors);
  1516. return S_OK;
  1517. }
  1518. // When another tab in the Display Control Panel changes the DPI, this tab needs
  1519. // to update any state that was based on the old DPI. For us, this could be
  1520. // the cached data in m_advDlgState.
  1521. HRESULT CBaseAppearancePage::_ScaleSizesSinceDPIChanged(void)
  1522. {
  1523. HRESULT hr = _LoadState();
  1524. //Check if the DPI value has really changed since the last time we applied a DPI change.
  1525. if (SUCCEEDED(hr) && (m_nNewDPI != m_nAppliedDPI))
  1526. {
  1527. CHAR szTemp[MAX_PATH];
  1528. wnsprintfA(szTemp, ARRAYSIZE(szTemp), "CBaseAppear::_ScaleSizesSinceDPIChanged() BEFORE Apply(%d)->New(%d) on DPI chang", m_nAppliedDPI, m_nNewDPI);
  1529. LogSystemMetrics(szTemp, &m_advDlgState);
  1530. // Cycle through all the UI fonts and change their sizes.
  1531. DPIConvert_SystemMetricsAll(FALSE, &m_advDlgState, m_nAppliedDPI, m_nNewDPI);
  1532. wnsprintfA(szTemp, ARRAYSIZE(szTemp), "CBaseAppear::_ScaleSizesSinceDPIChanged() AFTER Apply(%d)->New(%d) on DPI chang", m_nAppliedDPI, m_nNewDPI);
  1533. LogSystemMetrics(szTemp, &m_advDlgState);
  1534. m_nAppliedDPI = m_nNewDPI;
  1535. m_fIsDirty = TRUE;
  1536. m_advDlgState.dwChanged = (METRIC_CHANGE | COLOR_CHANGE | SCHEME_CHANGE);
  1537. _UpdatePreview(FALSE);
  1538. }
  1539. return hr;
  1540. }
  1541. HRESULT CBaseAppearancePage::UpdateCharsetChanges(void)
  1542. {
  1543. return FixFontsOnLanguageChange();
  1544. }
  1545. /**************************************************************\
  1546. DESCRIPTION:
  1547. We shipped this API long ago. The goal is to:
  1548. 1. Set the current "Appearance Scheme".
  1549. 2. If the UI is displayed, update the UI.
  1550. 3. Apply the changes.
  1551. \**************************************************************/
  1552. HRESULT CBaseAppearancePage::DeskSetCurrentScheme(IN LPCWSTR pwzSchemeName)
  1553. {
  1554. int nIndex;
  1555. HRESULT hr = E_INVALIDARG;
  1556. if (pwzSchemeName)
  1557. {
  1558. TCHAR szTemp[MAX_PATH];
  1559. if (!pwzSchemeName[0])
  1560. {
  1561. if (LoadString(HINST_THISDLL, IDS_DEFAULT_APPEARANCES_SCHEME, szTemp, ARRAYSIZE(szTemp)))
  1562. {
  1563. pwzSchemeName = szTemp;
  1564. }
  1565. }
  1566. LoadConversionMappings(); // Load theme if needed.
  1567. hr = MapLegacyAppearanceSchemeToIndex(pwzSchemeName, &nIndex); // Failure means, FALSE, we didn't convert.
  1568. if (SUCCEEDED(hr) && _punkSite)
  1569. {
  1570. IThemeManager * pThemeManager;
  1571. hr = _punkSite->QueryInterface(IID_PPV_ARG(IThemeManager, &pThemeManager));
  1572. if (SUCCEEDED(hr))
  1573. {
  1574. hr = InstallVisualStyle(pThemeManager, L"", g_UpgradeMapping[nIndex].szNewColorSchemeName, g_UpgradeMapping[nIndex].szNewSizeName);
  1575. if (SUCCEEDED(hr))
  1576. {
  1577. // This ApplyNow() call will take a little while in normal situation (~10-20 seconds) in order
  1578. // to broadcast the message to all open apps. If a top level window is hung, it may take the
  1579. // full 30 seconds to timeout.
  1580. hr = pThemeManager->ApplyNow();
  1581. // We need to delete the "Live settings" because they are no longer valid.
  1582. SHDeleteKey(HKEY_CURRENT_USER, SZ_SAVEGROUP_NOSKIN_KEY);
  1583. SHDeleteKey(HKEY_CURRENT_USER, SZ_SAVEGROUP_ALL_KEY);
  1584. }
  1585. IUnknown_SetSite(pThemeManager, NULL); // Break the ref-count cycle.
  1586. pThemeManager->Release();
  1587. }
  1588. }
  1589. }
  1590. LogStatus("DeskSetCurrentScheme(\"%ls\") returned hr=%#08lx.\r\n", pwzSchemeName, hr);
  1591. return hr;
  1592. }
  1593. //===========================
  1594. // *** IPropertyBag Interface ***
  1595. //===========================
  1596. HRESULT CBaseAppearancePage::Read(IN LPCOLESTR pszPropName, IN VARIANT * pVar, IN IErrorLog *pErrorLog)
  1597. {
  1598. HRESULT hr = E_INVALIDARG;
  1599. _OnInitData();
  1600. if (pszPropName && pVar)
  1601. {
  1602. if (!StrCmpW(pszPropName, SZ_PBPROP_VISUALSTYLE_PATH) && m_pSelectedThemeScheme)
  1603. {
  1604. CComBSTR bstrPath;
  1605. hr = m_pSelectedThemeScheme->get_Path(&bstrPath);
  1606. if (FAILED(hr))
  1607. {
  1608. bstrPath = L"";
  1609. hr = S_OK; // We return an empty string for "Windows Classic" since they ask for the path.
  1610. }
  1611. pVar->vt = VT_BSTR;
  1612. hr = HrSysAllocString(bstrPath, &pVar->bstrVal);
  1613. }
  1614. else if (!StrCmpW(pszPropName, SZ_PBPROP_VISUALSTYLE_COLOR) && m_pSelectedStyle)
  1615. {
  1616. CComBSTR bstrName;
  1617. hr = m_pSelectedStyle->get_Name(&bstrName);
  1618. if (SUCCEEDED(hr))
  1619. {
  1620. pVar->vt = VT_BSTR;
  1621. hr = HrSysAllocString(bstrName, &pVar->bstrVal);
  1622. }
  1623. }
  1624. else if (!StrCmpW(pszPropName, SZ_PBPROP_VISUALSTYLE_SIZE) && m_pSelectedSize)
  1625. {
  1626. CComBSTR bstrName;
  1627. hr = m_pSelectedSize->get_Name(&bstrName);
  1628. if (SUCCEEDED(hr))
  1629. {
  1630. pVar->vt = VT_BSTR;
  1631. hr = HrSysAllocString(bstrName, &pVar->bstrVal);
  1632. }
  1633. }
  1634. else if (!StrCmpW(pszPropName, SZ_PBPROP_SYSTEM_METRICS))
  1635. {
  1636. hr = _LoadState();
  1637. // This is pretty ugly.
  1638. pVar->vt = VT_BYREF;
  1639. pVar->byref = &m_advDlgState;
  1640. }
  1641. else if (!StrCmpW(pszPropName, SZ_PBPROP_BACKGROUND_COLOR))
  1642. {
  1643. hr = _LoadState();
  1644. // This is pretty ugly.
  1645. pVar->vt = VT_UI4;
  1646. pVar->ulVal = m_advDlgState.schemeData.rgb[COLOR_BACKGROUND];
  1647. }
  1648. else if (!StrCmpW(pszPropName, SZ_PBPROP_DPI_MODIFIED_VALUE))
  1649. {
  1650. pVar->vt = VT_I4;
  1651. pVar->lVal = m_nNewDPI;
  1652. hr = S_OK;
  1653. }
  1654. else if (!StrCmpW(pszPropName, SZ_PBPROP_DPI_APPLIED_VALUE))
  1655. {
  1656. pVar->vt = VT_I4;
  1657. pVar->lVal = m_nAppliedDPI;
  1658. hr = S_OK;
  1659. }
  1660. }
  1661. return hr;
  1662. }
  1663. HRESULT CBaseAppearancePage::Write(IN LPCOLESTR pszPropName, IN VARIANT *pVar)
  1664. {
  1665. HRESULT hr = E_INVALIDARG;
  1666. _OnInitData();
  1667. if (pszPropName && pVar)
  1668. {
  1669. if (VT_BSTR == pVar->vt)
  1670. {
  1671. if (!StrCmpW(pszPropName, SZ_PBPROP_VISUALSTYLE_PATH))
  1672. {
  1673. hr = _OutsideSetScheme(pVar->bstrVal);
  1674. }
  1675. else if (!StrCmpW(pszPropName, SZ_PBPROP_VISUALSTYLE_COLOR))
  1676. {
  1677. hr = _OutsideSetStyle(pVar->bstrVal);
  1678. }
  1679. else if (!StrCmpW(pszPropName, SZ_PBPROP_VISUALSTYLE_SIZE))
  1680. {
  1681. hr = _OutsideSetSize(pVar->bstrVal);
  1682. }
  1683. }
  1684. else if ((VT_BYREF == pVar->vt) && pVar->byref)
  1685. {
  1686. if (!StrCmpW(pszPropName, SZ_PBPROP_SYSTEM_METRICS))
  1687. {
  1688. hr = S_OK;
  1689. if (!m_fLoadedAdvState)
  1690. {
  1691. AssertMsg((NULL != m_pSelectedSize), TEXT("m_pSelectedSize should have already been loaded by now or we shouldn't be showing the Adv Appearance page. -BryanSt"));
  1692. hr = SystemMetricsAll_Load(m_pSelectedSize, &m_advDlgState, &m_nNewDPI);
  1693. if (SUCCEEDED(hr))
  1694. {
  1695. m_fLoadedAdvState = TRUE;
  1696. }
  1697. }
  1698. SystemMetricsAll_Copy((SYSTEMMETRICSALL *) pVar->byref, &m_advDlgState);
  1699. m_fIsDirty = TRUE;
  1700. m_advDlgState.dwChanged = (METRIC_CHANGE | COLOR_CHANGE | SCHEME_CHANGE);
  1701. }
  1702. }
  1703. else if ((VT_UI4 == pVar->vt) &&
  1704. !StrCmpW(pszPropName, SZ_PBPROP_BACKGROUND_COLOR))
  1705. {
  1706. hr = S_OK;
  1707. if (!m_fLoadedAdvState)
  1708. {
  1709. AssertMsg((NULL != m_pSelectedSize), TEXT("m_pSelectedSize should have already been loaded by now or we shouldn't be showing the Adv Appearance page. -BryanSt"));
  1710. hr = SystemMetricsAll_Load(m_pSelectedSize, &m_advDlgState, &m_nNewDPI);
  1711. if (SUCCEEDED(hr))
  1712. {
  1713. m_fLoadedAdvState = TRUE;
  1714. }
  1715. }
  1716. // This is pretty ugly.
  1717. m_advDlgState.schemeData.rgb[COLOR_BACKGROUND] = pVar->ulVal;
  1718. m_fIsDirty = TRUE;
  1719. m_advDlgState.dwChanged = (METRIC_CHANGE | COLOR_CHANGE | SCHEME_CHANGE);
  1720. }
  1721. else if ((VT_LPWSTR == pVar->vt) &&
  1722. !StrCmpW(pszPropName, SZ_PBPROP_APPEARANCE_LAUNCHMSTHEME))
  1723. {
  1724. Str_SetPtrW(&m_pszLoadMSTheme, pVar->bstrVal);
  1725. hr = S_OK;
  1726. }
  1727. else if (VT_I4 == pVar->vt)
  1728. {
  1729. if (!StrCmpW(pszPropName, SZ_PBPROP_DPI_MODIFIED_VALUE))
  1730. {
  1731. m_nNewDPI = pVar->lVal;
  1732. hr = _ScaleSizesSinceDPIChanged(); // Scale all the values.
  1733. }
  1734. else if (!StrCmpW(pszPropName, SZ_PBPROP_DPI_APPLIED_VALUE))
  1735. {
  1736. m_nAppliedDPI = pVar->lVal;
  1737. hr = S_OK;
  1738. }
  1739. }
  1740. }
  1741. return hr;
  1742. }
  1743. //===========================
  1744. // *** IBasePropPage Interface ***
  1745. //===========================
  1746. HRESULT CBaseAppearancePage::GetAdvancedDialog(OUT IAdvancedDialog ** ppAdvDialog)
  1747. {
  1748. HRESULT hr = E_INVALIDARG;
  1749. if (ppAdvDialog)
  1750. {
  1751. *ppAdvDialog = NULL;
  1752. hr = _LoadState();
  1753. if (SUCCEEDED(hr))
  1754. {
  1755. _ScaleSizesSinceDPIChanged(); // We want to update our settings if someone changed the DPI
  1756. hr = CAdvAppearancePage_CreateInstance(ppAdvDialog, &m_advDlgState);
  1757. }
  1758. }
  1759. return hr;
  1760. }
  1761. HRESULT CBaseAppearancePage::OnApply(IN PROPPAGEONAPPLY oaAction)
  1762. {
  1763. HRESULT hr = S_OK;
  1764. if (PPOAACTION_CANCEL != oaAction)
  1765. {
  1766. HCURSOR old = SetCursor(LoadCursor(NULL, IDC_WAIT));
  1767. if (_IsDirty())
  1768. {
  1769. //Check to see if there is a change in the DPI value due to "Advanced->General" tab.
  1770. _ScaleSizesSinceDPIChanged();
  1771. // Update the "AppliedDPI" value in the registry.
  1772. HrRegSetDWORD(HKEY_CURRENT_USER, SZ_WINDOWMETRICS, SZ_APPLIEDDPI, m_nNewDPI);
  1773. LogStatus("DPI: SYSTEMMETRICS saved at %d DPI CBaseAppearancePage::OnApply\r\n", m_nNewDPI);
  1774. CDimmedWindow* pDimmedWindow = NULL;
  1775. if (!g_fInSetup)
  1776. {
  1777. pDimmedWindow = new CDimmedWindow(HINST_THISDLL);
  1778. if (pDimmedWindow)
  1779. {
  1780. pDimmedWindow->Create(30000);
  1781. }
  1782. }
  1783. hr = _SaveState(pDimmedWindow);
  1784. if (pDimmedWindow)
  1785. {
  1786. pDimmedWindow->Release();
  1787. }
  1788. if (FAILED(hr) && !g_fInSetup && (HRESULT_FROM_WIN32(ERROR_CANCELLED) != hr))
  1789. {
  1790. // We want to display UI here. Especially if we fail.
  1791. HWND hwndParent = GetParent(m_hwndSchemeDropDown);
  1792. WCHAR szTitle[MAX_PATH];
  1793. LoadString(HINST_THISDLL, IDS_ERROR_TITLE_APPLYBASEAPPEARANCE2, szTitle, ARRAYSIZE(szTitle));
  1794. ErrorMessageBox(hwndParent, szTitle, IDS_ERROR_APPLYBASEAPPEARANCE, hr, NULL, (MB_OK | MB_ICONEXCLAMATION));
  1795. hr = HRESULT_FROM_WIN32(ERROR_CANCELLED);
  1796. }
  1797. }
  1798. SetCursor(old);
  1799. }
  1800. if (PPOAACTION_OK == oaAction)
  1801. {
  1802. }
  1803. return hr;
  1804. }
  1805. //===========================
  1806. // *** IShellPropSheetExt Interface ***
  1807. //===========================
  1808. HRESULT CBaseAppearancePage::AddPages(IN LPFNSVADDPROPSHEETPAGE pfnAddPage, IN LPARAM lParam)
  1809. {
  1810. HRESULT hr = E_INVALIDARG;
  1811. PROPSHEETPAGE psp = {0};
  1812. psp.dwSize = sizeof(psp);
  1813. psp.hInstance = HINST_THISDLL;
  1814. psp.dwFlags = PSP_DEFAULT;
  1815. psp.lParam = (LPARAM) this;
  1816. psp.pszTemplate = MAKEINTRESOURCE(DLG_APPEARANCEPG);
  1817. psp.pfnDlgProc = CBaseAppearancePage::BaseAppearanceDlgProc;
  1818. HPROPSHEETPAGE hpsp = CreatePropertySheetPage(&psp);
  1819. if (hpsp)
  1820. {
  1821. if (pfnAddPage(hpsp, lParam))
  1822. {
  1823. hr = S_OK;
  1824. }
  1825. else
  1826. {
  1827. DestroyPropertySheetPage(hpsp);
  1828. hr = E_FAIL;
  1829. }
  1830. }
  1831. return hr;
  1832. }
  1833. //===========================
  1834. // *** IUnknown Interface ***
  1835. //===========================
  1836. ULONG CBaseAppearancePage::AddRef()
  1837. {
  1838. return InterlockedIncrement(&m_cRef);
  1839. }
  1840. ULONG CBaseAppearancePage::Release()
  1841. {
  1842. if (InterlockedDecrement(&m_cRef))
  1843. return m_cRef;
  1844. delete this;
  1845. return 0;
  1846. }
  1847. HRESULT CBaseAppearancePage::QueryInterface(REFIID riid, void **ppvObj)
  1848. {
  1849. static const QITAB qit[] =
  1850. {
  1851. QITABENT(CBaseAppearancePage, IObjectWithSite),
  1852. QITABENT(CBaseAppearancePage, IOleWindow),
  1853. QITABENT(CBaseAppearancePage, IPersist),
  1854. QITABENT(CBaseAppearancePage, IPropertyBag),
  1855. QITABENT(CBaseAppearancePage, IPreviewSystemMetrics),
  1856. QITABENT(CBaseAppearancePage, IBasePropPage),
  1857. QITABENTMULTI(CBaseAppearancePage, IShellPropSheetExt, IBasePropPage),
  1858. { 0 },
  1859. };
  1860. return QISearch(this, qit, riid, ppvObj);
  1861. }
  1862. //===========================
  1863. // *** Class Methods ***
  1864. //===========================
  1865. CBaseAppearancePage::CBaseAppearancePage() : m_cRef(1), CObjectCLSID(&PPID_BaseAppearance)
  1866. {
  1867. DllAddRef();
  1868. // This needs to be allocated in Zero Inited Memory.
  1869. // Assert that all Member Variables are inited to Zero.
  1870. ASSERT(!m_pThemeManager);
  1871. ASSERT(!m_pSelectedThemeScheme);
  1872. ASSERT(!m_pSelectedStyle);
  1873. ASSERT(!m_pSelectedSize);
  1874. ASSERT(!m_hwndSchemeDropDown);
  1875. ASSERT(!m_hwndStyleDropDown);
  1876. ASSERT(!m_hwndSizeDropDown);
  1877. ASSERT(!m_pThemePreview);
  1878. ASSERT(!m_fIsDirty);
  1879. m_fInitialized = FALSE;
  1880. }
  1881. CBaseAppearancePage::~CBaseAppearancePage()
  1882. {
  1883. Str_SetPtrW(&m_pszLoadMSTheme, NULL);
  1884. ATOMICRELEASE(m_pThemeManager);
  1885. ATOMICRELEASE(m_pSelectedThemeScheme);
  1886. ATOMICRELEASE(m_pSelectedStyle);
  1887. ATOMICRELEASE(m_pSelectedSize);
  1888. ATOMICRELEASE(m_pThemePreview);
  1889. DllRelease();
  1890. }