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.

1985 lines
62 KiB

  1. #include "stdafx.h"
  2. #pragma hdrstop
  3. #define _BROWSEUI_ // Make functions exported from browseui as stdapi (as they are delay loaded)
  4. #include "iethread.h"
  5. #include "browseui.h"
  6. #include "securent.h"
  7. #include <cfgmgr32.h> // MAX_GUID_STRING_LEN
  8. static void EmptyListview(IActiveDesktop * pActiveDesktop, HWND hwndLV);
  9. #define DXA_GROWTH_CONST 10
  10. #define COMP_CHECKED 0x00002000
  11. #define COMP_UNCHECKED 0x00001000
  12. #define GALRET_NO 0x00000001
  13. #define GALRET_NEVER 0x00000002
  14. #define CCompPropSheetPage CCompPropSheetPage
  15. const static DWORD aDesktopItemsHelpIDs[] = { // Context Help IDs
  16. IDC_COMP_DESKTOPWEBPAGES_TITLE1, IDH_DISPLAY_WEB_ACTIVEDESKTOP_LIST,
  17. IDC_COMP_LIST, IDH_DISPLAY_WEB_ACTIVEDESKTOP_LIST,
  18. IDC_COMP_NEW, IDH_DISPLAY_WEB_NEW_BUTTON,
  19. IDC_COMP_DELETE, IDH_DISPLAY_WEB_DELETE_BUTTON,
  20. IDC_COMP_PROPERTIES, IDH_DISPLAY_WEB_PROPERTIES_BUTTON,
  21. IDC_COMP_SYNCHRONIZE,IDH_DISPLAY_WEB_SYNCHRONIZE_BUTTON,
  22. IDC_COMP_DESKTOPICONS_GROUP, IDH_DESKTOPITEMS_DESKTOPICONS_GROUP,
  23. IDC_DESKTOP_ICON_MYDOCS, IDH_DESKTOPITEMS_DESKTOPICONS_GROUP,
  24. IDC_DESKTOP_ICON_MYCOMP, IDH_DESKTOPITEMS_DESKTOPICONS_GROUP,
  25. IDC_DESKTOP_ICON_MYNET, IDH_DESKTOPITEMS_DESKTOPICONS_GROUP,
  26. IDC_DESKTOP_ICON_IE, IDH_DESKTOPITEMS_DESKTOPICONS_GROUP,
  27. IDC_COMP_CHANGEDESKTOPICON_LABEL, IDH_DESKTOPITEMS_ICONS,
  28. IDC_DESKTOP_ICONS, IDH_DESKTOPITEMS_ICONS, // List of icons
  29. IDC_CHANGEICON2, IDH_DESKTOPITEMS_CHANGEICON2, // Change Icon Button
  30. IDC_ICONDEFAULT, IDH_DESKTOPITEMS_ICONDEFAULT, // Default Icon Button
  31. IDC_COMP_DESKTOPWEBPAGES_LABEL, IDH_DISPLAY_WEB_ACTIVEDESKTOP_LIST,
  32. IDC_DESKCLNR_CHECK, IDH_DESKTOPITEMS_DESKCLNR_CHECK,
  33. IDC_DESKCLNR_MOVEUNUSED, IDH_DESKTOPITEMS_DESKCLNR_CHECK,
  34. IDC_DESKCLNR_RUNWIZARD, IDH_DESKTOPITEMS_DESKCLNR_RUNNOW,
  35. IDC_COMP_DESKTOPWEBPAGES_CHECK, IDH_DESKTOPITEMS_LOCKDESKITEMS_CHECK,
  36. IDC_COMP_DESKTOPWEBPAGES_TITLE2, IDH_DESKTOPITEMS_LOCKDESKITEMS_CHECK,
  37. 0, 0
  38. };
  39. #define SZ_HELPFILE_DESKTOPITEMS TEXT("display.hlp")
  40. // registry paths defined in shell\applet\cleanup\fldrclnr\cleanupwiz.h
  41. #define REGSTR_DESKTOP_CLEANUP TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Desktop\\CleanupWiz")
  42. #define REGSTR_VAL_DONTRUN TEXT("NoRun")
  43. extern int g_iRunDesktopCleanup;
  44. typedef struct
  45. {
  46. WCHAR wszURL[INTERNET_MAX_URL_LENGTH];
  47. SUBSCRIPTIONINFO si;
  48. } BACKUPSUBSCRIPTION;
  49. const LPCWSTR s_Icons[] =
  50. {
  51. L"CLSID\\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\DefaultIcon:DefaultValue", // My Computer
  52. L"CLSID\\{450D8FBA-AD25-11D0-98A8-0800361B1103}\\DefaultIcon:DefaultValue", // My Documents
  53. L"CLSID\\{208D2C60-3AEA-1069-A2D7-08002B30309D}\\DefaultIcon:DefaultValue", // My Network Places
  54. L"CLSID\\{645FF040-5081-101B-9F08-00AA002F954E}\\DefaultIcon:full", // Recycle Bin (Full)
  55. L"CLSID\\{645FF040-5081-101B-9F08-00AA002F954E}\\DefaultIcon:empty", // Recycle Bin (Empty)
  56. };
  57. IActiveDesktop * g_pActiveDeskAdv = NULL; // We need to keep a different copy than g_pActiveDesk
  58. extern DWORD g_dwApplyFlags;
  59. // Extract Icon from a file in proper Hi or Lo color for current system display
  60. //
  61. // from FrancisH on 6/22/95 with mods by TimBragg
  62. HRESULT ExtractPlusColorIcon(LPCTSTR szPath, int nIndex, HICON *phIcon, UINT uSizeLarge, UINT uSizeSmall)
  63. {
  64. IShellLink * psl;
  65. HRESULT hres;
  66. HICON hIcons[2]; // MUST! - provide for TWO return icons
  67. *phIcon = NULL;
  68. if (SUCCEEDED(hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IShellLink, &psl))))
  69. {
  70. if (SUCCEEDED(hres = psl->SetIconLocation(szPath, nIndex)))
  71. {
  72. IExtractIcon *pei;
  73. if (SUCCEEDED(hres = psl->QueryInterface(IID_PPV_ARG(IExtractIcon, &pei))))
  74. {
  75. if (SUCCEEDED(hres = pei->Extract(szPath, nIndex, &hIcons[0], &hIcons[1], (UINT)MAKEWPARAM((WORD)uSizeLarge, (WORD)uSizeSmall))))
  76. {
  77. DestroyIcon(hIcons[1]);
  78. *phIcon = hIcons[0]; // Return first icon to caller
  79. }
  80. pei->Release();
  81. }
  82. }
  83. psl->Release();
  84. }
  85. return hres;
  86. } // end ExtractPlusColorIcon()
  87. BOOL AreEditAndDisplaySchemesDifferent(IActiveDesktop * pActiveDesktop)
  88. {
  89. BOOL fAreDifferent = FALSE;
  90. IActiveDesktopP * piadp;
  91. if (SUCCEEDED(pActiveDesktop->QueryInterface(IID_PPV_ARG(IActiveDesktopP, &piadp))))
  92. {
  93. WCHAR wszEdit[MAX_PATH];
  94. WCHAR wszDisplay[MAX_PATH];
  95. DWORD dwcch = ARRAYSIZE(wszEdit);
  96. // If the edit scheme and display scheme are different, then we need to make
  97. // sure we force an update.
  98. if (SUCCEEDED(piadp->GetScheme(wszEdit, &dwcch, SCHEME_GLOBAL | SCHEME_EDIT)))
  99. {
  100. dwcch = ARRAYSIZE(wszDisplay);
  101. if (SUCCEEDED(piadp->GetScheme(wszDisplay, &dwcch, SCHEME_GLOBAL | SCHEME_DISPLAY)))
  102. {
  103. if (StrCmpW(wszDisplay, wszEdit))
  104. {
  105. fAreDifferent = TRUE;
  106. }
  107. }
  108. }
  109. piadp->Release();
  110. }
  111. return fAreDifferent;
  112. }
  113. HRESULT ActiveDesktop_CopyDesktopComponentsState(IN IActiveDesktop * pADSource, IN IActiveDesktop * pADDest)
  114. {
  115. HRESULT hr = S_OK;
  116. int nCompCount;
  117. int nIndex;
  118. COMPONENT comp = {sizeof(comp)};
  119. IPropertyBag *iPropBag = NULL;
  120. if(SUCCEEDED(pADDest->QueryInterface(IID_PPV_ARG(IPropertyBag, &iPropBag))))
  121. {
  122. //Inform the AD object to ignore policies. Otherwise, the following Remove and AddDesktopItem
  123. //calls will generate error messages if those policies were in effect.
  124. SHPropertyBag_WriteBOOL(iPropBag, c_wszPropName_IgnorePolicies, TRUE);
  125. }
  126. // Remove the desktop components from g_pActiveDesk because they will be replaced
  127. // with the ones fro g_pActiveDeskAdv.
  128. pADDest->GetDesktopItemCount(&nCompCount, 0);
  129. for (nIndex = (nCompCount - 1); nIndex >= 0; nIndex--)
  130. {
  131. if (SUCCEEDED(pADDest->GetDesktopItem(nIndex, &comp, 0)))
  132. {
  133. hr = pADDest->RemoveDesktopItem(&comp, 0);
  134. }
  135. }
  136. // Now copy the Desktop Components from g_pActiveDeskAdv to g_pActiveDesk.
  137. pADSource->GetDesktopItemCount(&nCompCount, 0);
  138. for (nIndex = 0; nIndex < nCompCount; nIndex++)
  139. {
  140. if (SUCCEEDED(pADSource->GetDesktopItem(nIndex, &comp, 0)))
  141. {
  142. hr = pADDest->AddDesktopItem(&comp, 0);
  143. }
  144. }
  145. if(iPropBag)
  146. {
  147. //We have removed and added all the desktop items. We are done manipulating the AD object.
  148. // Now, signal the AD object to reset the policies bit.
  149. SHPropertyBag_WriteBOOL(iPropBag, c_wszPropName_IgnorePolicies, FALSE);
  150. iPropBag->Release();
  151. }
  152. return hr;
  153. }
  154. HRESULT ActiveDesktop_CopyComponentOptionsState(IN IActiveDesktop * pADSource, IN IActiveDesktop * pADDest)
  155. {
  156. HRESULT hr = S_OK;
  157. COMPONENTSOPT co;
  158. // Copy over the on or off state of ActiveDesktop
  159. co.dwSize = sizeof(COMPONENTSOPT);
  160. hr = pADSource->GetDesktopItemOptions(&co, 0);
  161. if (SUCCEEDED(hr))
  162. {
  163. hr = pADDest->SetDesktopItemOptions(&co, 0);
  164. }
  165. return hr;
  166. }
  167. HRESULT ActiveDesktop_CopyState(IN IActiveDesktop * pADSource, IN IActiveDesktop * pADDest)
  168. {
  169. HRESULT hr = S_OK;
  170. WCHAR szPath[MAX_PATH];
  171. WALLPAPEROPT wallPaperOtp = {0};
  172. // The Advanced page allowed the user to change the state. We need to merge
  173. // the state from g_pActiveDeskAdv back into g_pActiveDesk
  174. hr = ActiveDesktop_CopyDesktopComponentsState(pADSource, pADDest);
  175. hr = ActiveDesktop_CopyComponentOptionsState(pADSource, pADDest);
  176. hr = pADSource->GetWallpaper(szPath, ARRAYSIZE(szPath), 0);
  177. if (SUCCEEDED(hr))
  178. {
  179. hr = pADDest->SetWallpaper(szPath, 0);
  180. }
  181. hr = pADSource->GetPattern(szPath, ARRAYSIZE(szPath), 0);
  182. if (SUCCEEDED(hr))
  183. {
  184. hr = pADDest->SetPattern(szPath, 0);
  185. }
  186. wallPaperOtp.dwSize = sizeof(wallPaperOtp);
  187. hr = pADSource->GetWallpaperOptions(&wallPaperOtp, 0);
  188. if (SUCCEEDED(hr))
  189. {
  190. hr = pADDest->SetWallpaperOptions(&wallPaperOtp, 0);
  191. }
  192. return hr;
  193. }
  194. HRESULT MergeState()
  195. {
  196. HRESULT hr = S_OK;
  197. // The Advanced page allowed the user to change the state. We need to merge
  198. // the state from g_pActiveDeskAdv back into g_pActiveDesk
  199. ActiveDesktop_CopyDesktopComponentsState(g_pActiveDeskAdv, g_pActiveDesk);
  200. // Copy over the on or off state of ActiveDesktop
  201. COMPONENTSOPT co;
  202. co.dwSize = sizeof(COMPONENTSOPT);
  203. g_pActiveDeskAdv->GetDesktopItemOptions(&co, 0);
  204. BOOL fActiveDesktop = co.fActiveDesktop;
  205. g_pActiveDesk->GetDesktopItemOptions(&co, 0);
  206. co.fActiveDesktop = fActiveDesktop; // Replace only this option.
  207. g_pActiveDesk->SetDesktopItemOptions(&co, 0);
  208. // If the edit scheme and display scheme are different, then we need to make
  209. // sure we force an update.
  210. if (AreEditAndDisplaySchemesDifferent(g_pActiveDeskAdv))
  211. {
  212. g_dwApplyFlags |= AD_APPLY_FORCE;
  213. }
  214. return hr;
  215. }
  216. HRESULT SHPropertyBag_ReadIcon(IN IPropertyBag * pAdvPage, IN BOOL fOldIcon, IN int nIndex, IN LPWSTR pszPath, IN DWORD cchSize, IN int * pnIcon)
  217. {
  218. HRESULT hr = E_INVALIDARG;
  219. if (nIndex < ARRAYSIZE(s_Icons))
  220. {
  221. WCHAR szPropName[MAX_URL_STRING];
  222. StrCpyNW(szPropName, s_Icons[nIndex], ARRAYSIZE(szPropName));
  223. if (fOldIcon)
  224. {
  225. // Indicate we want the old icon
  226. LPWSTR pszToken = StrChrW(szPropName, L':');
  227. if (pszToken)
  228. {
  229. pszToken[0] = L';';
  230. }
  231. }
  232. hr = SHPropertyBag_ReadStr(pAdvPage, szPropName, pszPath, cchSize);
  233. if (SUCCEEDED(hr))
  234. {
  235. *pnIcon= PathParseIconLocation(pszPath);
  236. }
  237. }
  238. return hr;
  239. }
  240. HRESULT SHPropertyBag_WriteIcon(IN IPropertyBag * pAdvPage, IN int nIndex, IN LPCWSTR pszPath, IN int nIcon)
  241. {
  242. HRESULT hr = E_INVALIDARG;
  243. if (nIndex < ARRAYSIZE(s_Icons))
  244. {
  245. WCHAR szPathAndIcon[MAX_PATH];
  246. wnsprintfW(szPathAndIcon, ARRAYSIZE(szPathAndIcon), L"%s,%d", pszPath, nIcon);
  247. hr = SHPropertyBag_WriteStr(pAdvPage, s_Icons[nIndex], szPathAndIcon);
  248. }
  249. return hr;
  250. }
  251. HRESULT CCompPropSheetPage::_LoadIconState(IN IPropertyBag * pAdvPage)
  252. {
  253. HRESULT hr = S_OK;
  254. int nIndex;
  255. // Move the values to the base dialog
  256. for (nIndex = 0; SUCCEEDED(hr) && (nIndex < ARRAYSIZE(_IconData)); nIndex++)
  257. {
  258. hr = SHPropertyBag_ReadIcon(pAdvPage, TRUE, nIndex, _IconData[nIndex].szOldFile, ARRAYSIZE(_IconData[nIndex].szOldFile), &_IconData[nIndex].iOldIndex);
  259. if (SUCCEEDED(hr))
  260. {
  261. hr = SHPropertyBag_ReadIcon(pAdvPage, FALSE, nIndex, _IconData[nIndex].szNewFile, ARRAYSIZE(_IconData[nIndex].szNewFile), &_IconData[nIndex].iNewIndex);
  262. }
  263. }
  264. return hr;
  265. }
  266. HRESULT CCompPropSheetPage::_LoadDeskIconState(IN IPropertyBag * pAdvPage)
  267. {
  268. HRESULT hr = S_OK;
  269. // Copy the values from the base dialog
  270. for (int iStartPanel = 0; iStartPanel <= 1; iStartPanel++)
  271. {
  272. WCHAR wszPropName[MAX_GUID_STRING_LEN + 20];
  273. for (int nIndex = 0; SUCCEEDED(hr) && (nIndex < NUM_DESKICONS); nIndex++)
  274. {
  275. wnsprintfW(wszPropName, ARRAYSIZE(wszPropName), c_wszPropNameFormat, c_awszSP[iStartPanel], c_aDeskIconId[nIndex].pwszCLSID);
  276. _afHideIcon[iStartPanel][nIndex] = SHPropertyBag_ReadBOOLDefRet(pAdvPage, wszPropName, FALSE);
  277. if(iStartPanel == 1)
  278. {
  279. wnsprintfW(wszPropName, ARRAYSIZE(wszPropName), c_wszPropNameFormat, POLICY_PREFIX, c_aDeskIconId[nIndex].pwszCLSID);
  280. _afDisableCheckBox[nIndex] = SHPropertyBag_ReadBOOLDefRet(pAdvPage, wszPropName, FALSE);
  281. }
  282. }
  283. }
  284. return hr;
  285. }
  286. HRESULT CCompPropSheetPage::_MergeDeskIconState(IN IPropertyBag * pAdvPage)
  287. {
  288. HRESULT hr = S_OK;
  289. // Move the values to the base dialog
  290. for (int iStartPanel = 0; iStartPanel <= 1; iStartPanel++)
  291. {
  292. WCHAR wszPropName[MAX_GUID_STRING_LEN + 20];
  293. for (int nIndex = 0; SUCCEEDED(hr) && (nIndex < NUM_DESKICONS); nIndex++)
  294. {
  295. wnsprintfW(wszPropName, ARRAYSIZE(wszPropName), c_wszPropNameFormat, c_awszSP[iStartPanel], c_aDeskIconId[nIndex].pwszCLSID);
  296. // Check if any icons have changed.
  297. hr = SHPropertyBag_WriteBOOL(pAdvPage, wszPropName, _afHideIcon[iStartPanel][nIndex]);
  298. }
  299. }
  300. return hr;
  301. }
  302. HRESULT CCompPropSheetPage::_MergeIconState(IN IPropertyBag * pAdvPage)
  303. {
  304. HRESULT hr = S_OK;
  305. BOOL fHasIconsChanged = FALSE;
  306. int nIndex;
  307. // Move the values to the base dialog
  308. for (nIndex = 0; nIndex < ARRAYSIZE(_IconData); nIndex++)
  309. {
  310. // Check if any icons have changed.
  311. if ((_IconData[nIndex].iNewIndex != _IconData[nIndex].iOldIndex) ||
  312. StrCmpI(_IconData[nIndex].szNewFile, _IconData[nIndex].szOldFile))
  313. {
  314. hr = SHPropertyBag_WriteIcon(pAdvPage, nIndex, _IconData[nIndex].szNewFile, _IconData[nIndex].iNewIndex);
  315. fHasIconsChanged = TRUE;
  316. }
  317. }
  318. // Only switch to "Custom" if the icons changed.
  319. if (_punkSite && fHasIconsChanged)
  320. {
  321. // We need to tell the Theme tab to customize the theme.
  322. IPropertyBag * pPropertyBag;
  323. hr = _punkSite->QueryInterface(IID_PPV_ARG(IPropertyBag, &pPropertyBag));
  324. if (SUCCEEDED(hr))
  325. {
  326. // Tell the theme that we have customized the values.
  327. hr = SHPropertyBag_WriteInt(pPropertyBag, SZ_PBPROP_CUSTOMIZE_THEME, 0);
  328. pPropertyBag->Release();
  329. }
  330. }
  331. return hr;
  332. }
  333. void CCompPropSheetPage::_ConstructLVString(COMPONENTA *pcomp, LPTSTR pszBuf, DWORD cchBuf)
  334. {
  335. //
  336. // Use the friendly name if it exists.
  337. // Otherwise use the source name.
  338. //
  339. if (pcomp->szFriendlyName[0])
  340. {
  341. lstrcpyn(pszBuf, pcomp->szFriendlyName, cchBuf);
  342. }
  343. else
  344. {
  345. lstrcpyn(pszBuf, pcomp->szSource, cchBuf);
  346. }
  347. }
  348. void CCompPropSheetPage::_AddComponentToLV(COMPONENTA *pcomp)
  349. {
  350. TCHAR szBuf[INTERNET_MAX_URL_LENGTH + 40];
  351. _ConstructLVString(pcomp, szBuf, ARRAYSIZE(szBuf));
  352. //
  353. // Construct the listview item.
  354. //
  355. LV_ITEM lvi = {0};
  356. lvi.mask = LVIF_TEXT | LVIF_PARAM;
  357. lvi.iItem = 0x7FFFFFFF;
  358. lvi.pszText = szBuf;
  359. lvi.lParam = pcomp->dwID;
  360. int index = ListView_InsertItem(_hwndLV, &lvi);
  361. if (index != -1)
  362. {
  363. ListView_SetItemState(_hwndLV, index, pcomp->fChecked ? COMP_CHECKED : COMP_UNCHECKED, LVIS_STATEIMAGEMASK);
  364. ListView_SetColumnWidth(_hwndLV, 0, LVSCW_AUTOSIZE);
  365. }
  366. }
  367. void CCompPropSheetPage::_SetUIFromDeskState(BOOL fEmpty)
  368. {
  369. //
  370. // Disable redraws while we mess repeatedly with the listview contents.
  371. //
  372. SendMessage(_hwndLV, WM_SETREDRAW, FALSE, 0);
  373. if (fEmpty)
  374. {
  375. EmptyListview(g_pActiveDeskAdv, _hwndLV);
  376. }
  377. //
  378. // Add each component to the listview.
  379. //
  380. int cComp;
  381. g_pActiveDeskAdv->GetDesktopItemCount(&cComp, 0);
  382. for (int i=0; i<cComp; i++)
  383. {
  384. COMPONENT comp;
  385. comp.dwSize = sizeof(comp);
  386. if (SUCCEEDED(g_pActiveDeskAdv->GetDesktopItem(i, &comp, 0)))
  387. {
  388. COMPONENTA compA;
  389. compA.dwSize = sizeof(compA);
  390. WideCompToMultiComp(&comp, &compA);
  391. _AddComponentToLV(&compA);
  392. }
  393. }
  394. _fInitialized = TRUE;
  395. //
  396. // Reenable redraws.
  397. //
  398. SendMessage(_hwndLV, WM_SETREDRAW, TRUE, 0);
  399. InvalidateRect(_hwndLV, NULL, TRUE);
  400. }
  401. void CCompPropSheetPage::_EnableControls(HWND hwnd)
  402. {
  403. BOOL fEnable;
  404. COMPONENT comp = { sizeof(comp) };
  405. BOOL fHaveSelection = FALSE;
  406. BOOL fSpecialComp = FALSE; //Is this a special component that can't be deleted?
  407. LPTSTR pszSource = NULL;
  408. // Read in the information about the selected component (if any).
  409. int iIndex = ListView_GetNextItem(_hwndLV, -1, LVNI_SELECTED);
  410. if (iIndex > -1)
  411. {
  412. LV_ITEM lvi = {0};
  413. lvi.mask = LVIF_PARAM;
  414. lvi.iItem = iIndex;
  415. ListView_GetItem(_hwndLV, &lvi);
  416. if (SUCCEEDED(g_pActiveDeskAdv->GetDesktopItemByID( lvi.lParam, &comp, 0)))
  417. {
  418. fHaveSelection = TRUE;
  419. //Check if this is a special component.
  420. #ifdef UNICODE
  421. pszSource = (LPTSTR)comp.wszSource;
  422. #else
  423. SHUnicodeToAnsi(comp.wszSource, szCompSource, ARRAYSIZE(szCompSource));
  424. pszSource = szCompSource;
  425. #endif
  426. fSpecialComp = !lstrcmpi(pszSource, MY_HOMEPAGE_SOURCE);
  427. }
  428. }
  429. // 98/08/19 vtan #142332: If there was a previously selected item
  430. // then reselect it and mark that there is now no previously selected
  431. // item.
  432. else if (_iPreviousSelection > -1)
  433. {
  434. ListView_SetItemState(_hwndLV, _iPreviousSelection, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  435. _iPreviousSelection = -1;
  436. // The above ListView_SetItemState results in LVN_ITEMCHANGED notification to _onNotify
  437. // function which inturn calls this _EnableControls again (recursively) and that call
  438. // enables/disables the buttons properly because now an item is selected. Nothing more
  439. // to do and hence this return.
  440. // This is done to fix Bug #276568.
  441. return;
  442. }
  443. EnableWindow(GetDlgItem(hwnd, IDC_COMP_NEW), _fAllowAdd);
  444. //
  445. // Delete button only enabled when an item is selected AND if it is NOT a special comp.
  446. //
  447. fEnable = _fAllowDel && fHaveSelection && !fSpecialComp;
  448. EnableWindow(GetDlgItem(hwnd, IDC_COMP_DELETE), fEnable);
  449. //
  450. // Properties button only enabled on URL based pictures
  451. // and websites.
  452. //
  453. fEnable = FALSE;
  454. if (_fAllowEdit && fHaveSelection)
  455. {
  456. switch (comp.iComponentType)
  457. {
  458. case COMP_TYPE_PICTURE:
  459. case COMP_TYPE_WEBSITE:
  460. //pszSource is already initialized if fHaveSelection is TRUE.
  461. if (PathIsURL(pszSource))
  462. {
  463. fEnable = TRUE;
  464. }
  465. break;
  466. }
  467. }
  468. EnableWindow(GetDlgItem(hwnd, IDC_COMP_PROPERTIES), fEnable);
  469. // initialize the Lock Desktop Items button
  470. CheckDlgButton(hwnd, IDC_COMP_DESKTOPWEBPAGES_CHECK, _fLockDesktopItems);
  471. }
  472. HWND CCompPropSheetPage::_CreateListView(HWND hWndParent)
  473. {
  474. LV_ITEM lvI; // List view item structure
  475. TCHAR szTemp[MAX_PATH];
  476. BOOL bEnable = FALSE;
  477. #ifdef JIGGLE_FIX
  478. RECT rc;
  479. #endif
  480. UINT flags = ILC_MASK | ILC_COLOR32;
  481. // Create a device independant size and location
  482. LONG lWndunits = GetDialogBaseUnits();
  483. int iWndx = LOWORD(lWndunits);
  484. int iWndy = HIWORD(lWndunits);
  485. int iX = ((11 * iWndx) / 4);
  486. int iY = ((15 * iWndy) / 8);
  487. int iWidth = ((163 * iWndx) / 4);
  488. int iHeight = ((40 * iWndy) / 8);
  489. int nIndex;
  490. // Ensure that the common control DLL is loaded.
  491. InitCommonControls();
  492. // Get the list view window
  493. _hWndList = GetDlgItem(hWndParent, IDC_DESKTOP_ICONS);
  494. if(_hWndList == NULL)
  495. return NULL;
  496. if(IS_WINDOW_RTL_MIRRORED(hWndParent))
  497. {
  498. flags |= ILC_MIRROR;
  499. }
  500. // initialize the list view window
  501. // First, initialize the image lists we will need
  502. _hIconList = ImageList_Create(32, 32, flags, ARRAYSIZE(c_aIconRegKeys), 0 ); // create an image list for the icons
  503. // load the icons and add them to the image lists
  504. // get the icon files and indexes from the registry, including for the Default recycle bin
  505. for (nIndex = 0; nIndex < ARRAYSIZE(_IconData); nIndex++)
  506. {
  507. HICON hIcon = NULL;
  508. ExtractPlusColorIcon(_IconData[nIndex].szNewFile, _IconData[nIndex].iNewIndex, &hIcon, 0, 0);
  509. // Added this "if" to fix bug 2831. We want to use SHELL32.DLL
  510. // icon 0 if there is no icon in the file specified in the
  511. // registry (or if the registry didn't specify a file).
  512. if(hIcon == NULL)
  513. {
  514. if (!GetSystemDirectory(szTemp, ARRAYSIZE(szTemp)))
  515. {
  516. szTemp[0] = 0;
  517. }
  518. PathAppend(szTemp, TEXT("shell32.dll"));
  519. StrCpyN(_IconData[nIndex].szOldFile, szTemp, ARRAYSIZE(_IconData[nIndex].szOldFile));
  520. StrCpyN(_IconData[nIndex].szNewFile, szTemp, ARRAYSIZE(_IconData[nIndex].szNewFile));
  521. _IconData[nIndex].iOldIndex = _IconData[nIndex].iNewIndex = 0;
  522. ExtractPlusColorIcon(szTemp, 0, &hIcon, 0, 0);
  523. }
  524. if (hIcon)
  525. {
  526. DWORD dwResult = ImageList_AddIcon(_hIconList, hIcon);
  527. // ImageList_AddIcon() does not take ownership of the icon, so we need to free it.
  528. DestroyIcon(hIcon);
  529. if (-1 == dwResult)
  530. {
  531. ImageList_Destroy(_hIconList);
  532. _hIconList = NULL;
  533. return NULL;
  534. }
  535. }
  536. }
  537. // Make sure that all of the icons were added
  538. if (ImageList_GetImageCount(_hIconList) < ARRAYSIZE(c_aIconRegKeys))
  539. {
  540. ImageList_Destroy(_hIconList);
  541. _hIconList = NULL;
  542. return FALSE;
  543. }
  544. ListView_SetImageList(_hWndList, _hIconList, LVSIL_NORMAL);
  545. // Make sure the listview has WS_HSCROLL set on it.
  546. DWORD dwStyle = GetWindowLong(_hWndList, GWL_STYLE);
  547. SetWindowLong(_hWndList, GWL_STYLE, (dwStyle & (~WS_VSCROLL)) | WS_HSCROLL);
  548. // Finally, let's add the actual items to the control. Fill in the LV_ITEM
  549. // structure for each of the items to add to the list. The mask specifies
  550. // the the .pszText, .iImage, and .state members of the LV_ITEM structure are valid.
  551. lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
  552. lvI.state = 0;
  553. lvI.stateMask = 0;
  554. for(nIndex = 0; nIndex < ARRAYSIZE(c_aIconRegKeys); nIndex++ )
  555. {
  556. TCHAR szAppend[64];
  557. BOOL bRet = FALSE;
  558. if (IsEqualCLSID(*c_aIconRegKeys[nIndex].pclsid, CLSID_MyDocuments))
  559. {
  560. LPITEMIDLIST pidl;
  561. HRESULT hr = SHGetSpecialFolderLocation(_hWndList, CSIDL_PERSONAL, &pidl);
  562. // Treat "My Files" differently because we will probably customize the "My" at run time.
  563. if (SUCCEEDED(hr))
  564. {
  565. hr = SHGetNameAndFlags(pidl, SHGDN_INFOLDER, szTemp, ARRAYSIZE(szTemp), NULL);
  566. if (SUCCEEDED(hr))
  567. {
  568. bRet = TRUE;
  569. }
  570. ILFree(pidl);
  571. }
  572. }
  573. else
  574. {
  575. bRet = IconGetRegValueString(c_aIconRegKeys[nIndex].pclsid, NULL, NULL, szTemp, ARRAYSIZE(szTemp));
  576. }
  577. // if the title string was in the registry, else we have to use the default in our resources
  578. if( (bRet) && (lstrlen(szTemp) > 0))
  579. {
  580. if( LoadString(HINST_THISDLL, c_aIconRegKeys[nIndex].iTitleResource, szAppend, ARRAYSIZE(szAppend)) != 0)
  581. {
  582. StrCatBuff(szTemp, szAppend, ARRAYSIZE(szTemp));
  583. }
  584. }
  585. else
  586. {
  587. LoadString(HINST_THISDLL, c_aIconRegKeys[nIndex].iDefaultTitleResource, szTemp, ARRAYSIZE(szTemp));
  588. }
  589. lvI.iItem = nIndex;
  590. lvI.iSubItem = 0;
  591. lvI.pszText = szTemp;
  592. lvI.iImage = nIndex;
  593. if(ListView_InsertItem(_hWndList, &lvI) == -1)
  594. return NULL;
  595. }
  596. #ifdef JIGGLE_FIX
  597. // To fix long standing listview bug, we need to "jiggle" the listview
  598. // window size so that it will do a recompute and realize that we need a
  599. // scroll bar...
  600. GetWindowRect(_hWndList, &rc);
  601. MapWindowPoints( NULL, hWndParent, (LPPOINT)&rc, 2 );
  602. MoveWindow(_hWndList, rc.left, rc.top, rc.right - rc.left+1, rc.bottom - rc.top, FALSE );
  603. MoveWindow(_hWndList, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, FALSE );
  604. #endif
  605. // Set First item to selected
  606. ListView_SetItemState (_hWndList, 0, LVIS_SELECTED, LVIS_SELECTED);
  607. // Get Selected item
  608. for (m_nIndex = 0; m_nIndex < ARRAYSIZE(c_aIconRegKeys); m_nIndex++)
  609. {
  610. if (ListView_GetItemState(_hWndList, m_nIndex, LVIS_SELECTED))
  611. {
  612. bEnable = TRUE;
  613. break;
  614. }
  615. }
  616. if (m_nIndex >= ARRAYSIZE(c_aIconRegKeys))
  617. {
  618. m_nIndex = -1;
  619. }
  620. EnableWindow(GetDlgItem(hWndParent, IDC_CHANGEICON2), bEnable);
  621. EnableWindow(GetDlgItem(hWndParent, IDC_ICONDEFAULT), bEnable);
  622. return _hWndList;
  623. }
  624. #define CUSTOMIZE_DLGPROC 1
  625. #define CUSTOMIZE_WEB_DLGPROC 2
  626. void CCompPropSheetPage::_OnInitDialog(HWND hwnd, INT iPage)
  627. {
  628. if (FAILED(GetActiveDesktop(&g_pActiveDeskAdv)))
  629. {
  630. return;
  631. }
  632. switch (iPage)
  633. {
  634. case CUSTOMIZE_DLGPROC :
  635. {
  636. //
  637. // Read in the restrictions.
  638. //
  639. // Init the Icon UI
  640. // Create our list view and fill it with the system icons
  641. m_nIndex = 0;
  642. _CreateListView(hwnd);
  643. _OnInitDesktopOptionsUI(hwnd);
  644. //
  645. // Enable the Desktop Cleanup Wizard if we are on the right version
  646. // of the OS and the DesktopCleanup NoRun policy is not set
  647. //
  648. //
  649. BOOL fCleanupEnabled = (IsOS(OS_PERSONAL) || IsOS(OS_PROFESSIONAL)) &&
  650. !IsUserAGuest() &&
  651. !SHRestricted(REST_NODESKTOPCLEANUP);
  652. if (fCleanupEnabled)
  653. {
  654. if (BST_INDETERMINATE == g_iRunDesktopCleanup)
  655. {
  656. DWORD dwData = 0;
  657. DWORD dwType;
  658. DWORD cch = sizeof (DWORD);
  659. if (ERROR_SUCCESS == SHRegGetUSValue(REGSTR_DESKTOP_CLEANUP,REGSTR_VAL_DONTRUN,
  660. &dwType, &dwData, &cch, FALSE, NULL, 0) &&
  661. dwData != 0)
  662. {
  663. g_iRunDesktopCleanup = BST_UNCHECKED;
  664. }
  665. else
  666. {
  667. g_iRunDesktopCleanup = BST_CHECKED;
  668. }
  669. }
  670. CheckDlgButton(hwnd, IDC_DESKCLNR_CHECK, g_iRunDesktopCleanup);
  671. }
  672. else
  673. {
  674. ShowWindow(GetDlgItem(hwnd, IDC_COMP_CLEANUP_GROUP), FALSE);
  675. ShowWindow(GetDlgItem(hwnd, IDC_DESKCLNR_MOVEUNUSED), FALSE);
  676. ShowWindow(GetDlgItem(hwnd, IDC_DESKCLNR_CHECK), FALSE);
  677. ShowWindow(GetDlgItem(hwnd, IDC_DESKCLNR_RUNWIZARD), FALSE);
  678. }
  679. }
  680. break;
  681. case CUSTOMIZE_WEB_DLGPROC:
  682. {
  683. _fLaunchGallery = FALSE;
  684. _fAllowAdd = !SHRestricted(REST_NOADDDESKCOMP);
  685. _fAllowDel = !SHRestricted(REST_NODELDESKCOMP);
  686. _fAllowEdit = !SHRestricted(REST_NOEDITDESKCOMP);
  687. _fAllowClose = !SHRestricted(REST_NOCLOSEDESKCOMP);
  688. _fAllowReset = _fAllowAdd && _fAllowDel && _fAllowEdit &&
  689. _fAllowClose && !SHRestricted(REST_NOCHANGINGWALLPAPER);
  690. _fForceAD = SHRestricted(REST_FORCEACTIVEDESKTOPON);
  691. _hwndLV = GetDlgItem(hwnd, IDC_COMP_LIST);
  692. EnableWindow(GetDlgItem(hwnd, IDC_COMP_NEW), _fAllowAdd);
  693. EnableWindow(GetDlgItem(hwnd, IDC_COMP_DELETE), _fAllowDel);
  694. EnableWindow(GetDlgItem(hwnd, IDC_COMP_PROPERTIES), _fAllowEdit);
  695. EnableWindow(GetDlgItem(hwnd, IDC_COMP_SYNCHRONIZE), _fAllowEdit);
  696. if (_fAllowClose)
  697. {
  698. ListView_SetExtendedListViewStyle(_hwndLV, LVS_EX_CHECKBOXES);
  699. }
  700. //
  701. // Add the single column that we want.
  702. //
  703. LV_COLUMN lvc;
  704. lvc.mask = LVCF_FMT | LVCF_SUBITEM;
  705. lvc.fmt = LVCFMT_LEFT;
  706. lvc.iSubItem = 0;
  707. ListView_InsertColumn(_hwndLV, 0, &lvc);
  708. //
  709. // Now make the UI match the g_pActiveDeskAdv object.
  710. //
  711. _SetUIFromDeskState(FALSE);
  712. //
  713. // Select the first item, if it exists.
  714. //
  715. int cComp;
  716. g_pActiveDeskAdv->GetDesktopItemCount(&cComp, 0);
  717. if (cComp)
  718. {
  719. ListView_SetItemState(_hwndLV, 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  720. }
  721. _EnableControls(hwnd);
  722. }
  723. break;
  724. }
  725. }
  726. HRESULT CCompPropSheetPage::_OnInitDesktopOptionsUI(HWND hwnd)
  727. {
  728. SHELLSTATE ss = {0};
  729. SHGetSetSettings(&ss, SSF_STARTPANELON, FALSE); //See if the StartPanel is on!
  730. _iStartPanelOn = ss.fStartPanelOn ? 1 : 0; //Remember this in the class!
  731. // Check or uncheck the various icons based on whether they are on/off now.
  732. _UpdateDesktopIconsUI(hwnd);
  733. return S_OK;
  734. }
  735. HRESULT CCompPropSheetPage::_UpdateDesktopIconsUI(HWND hwnd)
  736. {
  737. // Check or uncheck the various icons based on whether they are on/off now.
  738. for (int iIndex = 0; iIndex < NUM_DESKICONS; iIndex++)
  739. {
  740. // If HideDeskIcon[][] is true, uncheck the checkbox! If it is FALSE, check the checkbox.
  741. CheckDlgButton(hwnd, c_aDeskIconId[iIndex].iDeskIconDlgItemId, !_afHideIcon[_iStartPanelOn][iIndex]);
  742. // If the policy is set, disable this CheckBox!
  743. EnableWindow(GetDlgItem(hwnd, c_aDeskIconId[iIndex].iDeskIconDlgItemId), !_afDisableCheckBox[iIndex]);
  744. }
  745. return S_OK;
  746. }
  747. void CCompPropSheetPage::_OnNotify(HWND hwnd, WPARAM wParam, LPNMHDR lpnm)
  748. {
  749. switch (wParam)
  750. {
  751. case IDC_COMP_DESKTOPWEBPAGES_CHECK:
  752. _fLockDesktopItems = IsDlgButtonChecked(hwnd, IDC_COMP_DESKTOPWEBPAGES_CHECK);
  753. break;
  754. case IDC_DESKTOP_ICONS:
  755. {
  756. switch (lpnm->code)
  757. case LVN_ITEMCHANGED:
  758. {
  759. BOOL fSomethingSelected = FALSE;
  760. // Find out who's selected now
  761. for( m_nIndex = 0; m_nIndex < ARRAYSIZE(c_aIconRegKeys); m_nIndex++)
  762. {
  763. if( ListView_GetItemState(_hWndList, m_nIndex, LVIS_SELECTED))
  764. {
  765. fSomethingSelected = TRUE;
  766. break;
  767. }
  768. }
  769. if (m_nIndex >= ARRAYSIZE(c_aIconRegKeys))
  770. {
  771. m_nIndex = -1;
  772. }
  773. EnableWindow(GetDlgItem(hwnd, IDC_CHANGEICON2), fSomethingSelected);
  774. EnableWindow(GetDlgItem(hwnd, IDC_ICONDEFAULT), fSomethingSelected);
  775. }
  776. }
  777. break;
  778. case IDC_COMP_LIST:
  779. {
  780. switch (lpnm->code)
  781. {
  782. case LVN_ITEMCHANGED:
  783. NM_LISTVIEW *pnmlv = (NM_LISTVIEW *)lpnm;
  784. if ((pnmlv->uChanged & LVIF_STATE) &&
  785. ((pnmlv->uNewState ^ pnmlv->uOldState) & COMP_CHECKED))
  786. {
  787. LV_ITEM lvi = {0};
  788. lvi.iItem = pnmlv->iItem;
  789. lvi.mask = LVIF_PARAM;
  790. ListView_GetItem(_hwndLV, &lvi);
  791. COMPONENT comp;
  792. comp.dwSize = sizeof(COMPONENT);
  793. if (SUCCEEDED(g_pActiveDeskAdv->GetDesktopItemByID(lvi.lParam, &comp, 0)))
  794. {
  795. comp.fChecked = (pnmlv->uNewState & COMP_CHECKED) != 0;
  796. g_pActiveDeskAdv->ModifyDesktopItem(&comp, COMP_ELEM_CHECKED);
  797. }
  798. if (_fInitialized)
  799. {
  800. g_fDirtyAdvanced = TRUE;
  801. }
  802. }
  803. if ((pnmlv->uChanged & LVIF_STATE) &&
  804. ((pnmlv->uNewState ^ pnmlv->uOldState) & LVIS_SELECTED))
  805. {
  806. _EnableControls(hwnd); // toggle delete, properties
  807. }
  808. break;
  809. }
  810. }
  811. break;
  812. default:
  813. {
  814. switch (lpnm->code)
  815. {
  816. case PSN_APPLY:
  817. {
  818. // store desktop flags
  819. DWORD dwFlags, dwFlagsPrev;
  820. dwFlags = dwFlagsPrev = GetDesktopFlags();
  821. if (_fLockDesktopItems)
  822. {
  823. dwFlags |= COMPONENTS_LOCKED;
  824. }
  825. else
  826. {
  827. dwFlags &= ~COMPONENTS_LOCKED;
  828. }
  829. if (dwFlags != dwFlagsPrev)
  830. {
  831. g_fDirtyAdvanced = TRUE;
  832. SetDesktopFlags(COMPONENTS_LOCKED, dwFlags);
  833. }
  834. _fCustomizeDesktopOK = TRUE;
  835. }
  836. break;
  837. }
  838. }
  839. break;
  840. }
  841. }
  842. //
  843. // Returns TRUE if the string looks like a candidate for
  844. // getting qualified as "file:".
  845. //
  846. BOOL LooksLikeFile(LPCTSTR psz)
  847. {
  848. BOOL fRet = FALSE;
  849. if (psz[0] &&
  850. psz[1] &&
  851. #ifndef UNICODE
  852. !IsDBCSLeadByte(psz[0]) &&
  853. !IsDBCSLeadByte(psz[1]) &&
  854. #endif
  855. ((psz[0] == TEXT('\\')) ||
  856. (psz[1] == TEXT(':')) ||
  857. (psz[1] == TEXT('|'))))
  858. {
  859. fRet = TRUE;
  860. }
  861. return fRet;
  862. }
  863. #define GOTO_GALLERY (-2)
  864. BOOL_PTR CALLBACK AddComponentDlgProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  865. {
  866. LPTSTR pszSource = (LPTSTR)GetWindowLongPtr(hdlg, DWLP_USER);
  867. TCHAR szBuf[INTERNET_MAX_URL_LENGTH];
  868. switch (uMsg)
  869. {
  870. case WM_INITDIALOG:
  871. pszSource = (LPTSTR)lParam;
  872. SetWindowLongPtr(hdlg, DWLP_USER, (LONG_PTR)pszSource);
  873. SetDlgItemText(hdlg, IDC_CPROP_SOURCE, c_szNULL);
  874. EnableWindow(GetDlgItem(hdlg, IDOK), FALSE);
  875. SHAutoComplete(GetDlgItem(hdlg, IDC_CPROP_SOURCE), 0);
  876. return TRUE;
  877. case WM_COMMAND:
  878. switch (GET_WM_COMMAND_ID(wParam, lParam))
  879. {
  880. case IDC_CPROP_BROWSE:
  881. {
  882. GetDlgItemText(hdlg, IDC_CPROP_SOURCE, szBuf, ARRAYSIZE(szBuf));
  883. if (!LooksLikeFile(szBuf))
  884. {
  885. //
  886. // Open the favorites folder when we aren't
  887. // looking at a specific file.
  888. //
  889. SHGetSpecialFolderPath(hdlg, szBuf, CSIDL_FAVORITES, FALSE);
  890. //
  891. // Append a slash because GetFileName breaks the
  892. // string into a file & dir, and we want to make sure
  893. // the entire favorites path is treated as a dir.
  894. //
  895. lstrcat(szBuf, TEXT("\\"));
  896. }
  897. else
  898. {
  899. PathRemoveArgs(szBuf);
  900. }
  901. DWORD adwFlags[] = {
  902. GFN_ALL,
  903. GFN_PICTURE,
  904. (GFN_LOCALHTM | GFN_LOCALMHTML | GFN_CDF | GFN_URL),
  905. 0
  906. };
  907. int aiTypes[] = {
  908. IDS_COMP_FILETYPES,
  909. IDS_ALL_PICTURES,
  910. IDS_ALL_HTML,
  911. 0
  912. };
  913. if (GetFileName(hdlg, szBuf, ARRAYSIZE(szBuf), aiTypes, adwFlags))
  914. {
  915. CheckAndResolveLocalUrlFile(szBuf, ARRAYSIZE(szBuf));
  916. SetDlgItemText(hdlg, IDC_CPROP_SOURCE, szBuf);
  917. }
  918. }
  919. break;
  920. case IDC_CPROP_SOURCE:
  921. if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE)
  922. {
  923. EnableWindow(GetDlgItem(hdlg, IDOK), GetWindowTextLength(GetDlgItem(hdlg, IDC_CPROP_SOURCE)) > 0);
  924. }
  925. break;
  926. case IDOK:
  927. GetDlgItemText(hdlg, IDC_CPROP_SOURCE, pszSource, INTERNET_MAX_URL_LENGTH);
  928. ASSERT(pszSource[0]);
  929. if (ValidateFileName(hdlg, pszSource, IDS_COMP_TYPE1))
  930. {
  931. CheckAndResolveLocalUrlFile(pszSource, INTERNET_MAX_URL_LENGTH);
  932. //
  933. // Qualify non file-protocol strings.
  934. //
  935. if (!LooksLikeFile(pszSource))
  936. {
  937. DWORD cchSize = INTERNET_MAX_URL_LENGTH;
  938. PathRemoveBlanks(pszSource);
  939. ParseURLFromOutsideSource(pszSource, pszSource, &cchSize, NULL);
  940. }
  941. EndDialog(hdlg, 0);
  942. }
  943. break;
  944. case IDCANCEL:
  945. EndDialog(hdlg, -1);
  946. break;
  947. case IDC_GOTO_GALLERY:
  948. EndDialog(hdlg, GOTO_GALLERY);
  949. break;
  950. }
  951. break;
  952. }
  953. return FALSE;
  954. }
  955. BOOL IsUrlPicture(LPCTSTR pszUrl)
  956. {
  957. BOOL fRet = FALSE;
  958. if(pszUrl[0] == TEXT('\0'))
  959. {
  960. fRet = TRUE;
  961. }
  962. else
  963. {
  964. LPTSTR pszExt = PathFindExtension(pszUrl);
  965. if ((lstrcmpi(pszExt, TEXT(".BMP")) == 0) ||
  966. (StrCmpIC(pszExt, TEXT(".GIF")) == 0) || // 368690: Strange, but we must compare 'i' in both caps and lower case.
  967. (lstrcmpi(pszExt, TEXT(".JPG")) == 0) ||
  968. (lstrcmpi(pszExt, TEXT(".JPE")) == 0) ||
  969. (lstrcmpi(pszExt, TEXT(".JPEG")) == 0) ||
  970. (lstrcmpi(pszExt, TEXT(".DIB")) == 0) ||
  971. (lstrcmpi(pszExt, TEXT(".PNG")) == 0))
  972. {
  973. fRet = TRUE;
  974. }
  975. }
  976. return(fRet);
  977. }
  978. int GetComponentType(LPCTSTR pszUrl)
  979. {
  980. return IsUrlPicture(pszUrl) ? COMP_TYPE_PICTURE : COMP_TYPE_WEBSITE;
  981. }
  982. void CreateComponent(COMPONENTA *pcomp, LPCTSTR pszUrl)
  983. {
  984. pcomp->dwSize = sizeof(*pcomp);
  985. pcomp->dwID = (DWORD)-1;
  986. pcomp->iComponentType = GetComponentType(pszUrl);
  987. pcomp->fChecked = TRUE;
  988. pcomp->fDirty = FALSE;
  989. pcomp->fNoScroll = FALSE;
  990. pcomp->cpPos.dwSize = sizeof(pcomp->cpPos);
  991. pcomp->cpPos.iLeft = COMPONENT_DEFAULT_LEFT;
  992. pcomp->cpPos.iTop = COMPONENT_DEFAULT_TOP;
  993. pcomp->cpPos.dwWidth = COMPONENT_DEFAULT_WIDTH;
  994. pcomp->cpPos.dwHeight = COMPONENT_DEFAULT_HEIGHT;
  995. pcomp->cpPos.izIndex = COMPONENT_TOP;
  996. pcomp->cpPos.fCanResize = TRUE;
  997. pcomp->cpPos.fCanResizeX = pcomp->cpPos.fCanResizeY = TRUE;
  998. pcomp->cpPos.iPreferredLeftPercent = pcomp->cpPos.iPreferredTopPercent = 0;
  999. lstrcpyn(pcomp->szSource, pszUrl, ARRAYSIZE(pcomp->szSource));
  1000. lstrcpyn(pcomp->szSubscribedURL, pszUrl, ARRAYSIZE(pcomp->szSubscribedURL));
  1001. pcomp->szFriendlyName[0] = TEXT('\0');
  1002. }
  1003. BOOL FindComponent(IN LPCTSTR pszUrl, IN IActiveDesktop * pActiveDesktop)
  1004. {
  1005. BOOL fRet = FALSE;
  1006. int i, ccomp;
  1007. LPWSTR pwszUrl;
  1008. #ifndef UNICODE
  1009. WCHAR wszUrl[INTERNET_MAX_URL_LENGTH];
  1010. SHAnsiToUnicode(pszUrl, wszUrl, ARRAYSIZE(wszUrl));
  1011. pwszUrl = wszUrl;
  1012. #else
  1013. pwszUrl = (LPWSTR)pszUrl;
  1014. #endif
  1015. if (pActiveDesktop)
  1016. {
  1017. pActiveDesktop->GetDesktopItemCount(&ccomp, 0);
  1018. for (i=0; i<ccomp; i++)
  1019. {
  1020. COMPONENT comp;
  1021. comp.dwSize = sizeof(COMPONENT);
  1022. if (SUCCEEDED(pActiveDesktop->GetDesktopItem(i, &comp, 0)))
  1023. {
  1024. if (StrCmpIW(pwszUrl, comp.wszSource) == 0)
  1025. {
  1026. fRet = TRUE;
  1027. break;
  1028. }
  1029. }
  1030. }
  1031. }
  1032. return fRet;
  1033. }
  1034. void EmptyListview(IActiveDesktop * pActiveDesktop, HWND hwndLV)
  1035. {
  1036. //
  1037. // Delete all the old components.
  1038. //
  1039. int cComp;
  1040. pActiveDesktop->GetDesktopItemCount(&cComp, 0);
  1041. int i;
  1042. COMPONENT comp;
  1043. comp.dwSize = sizeof(COMPONENT);
  1044. for (i=0; i<cComp; i++)
  1045. {
  1046. ListView_DeleteItem(hwndLV, 0);
  1047. }
  1048. }
  1049. void CCompPropSheetPage::_SelectComponent(LPWSTR pwszUrl)
  1050. {
  1051. //
  1052. // Look for the component with our URL.
  1053. //
  1054. int cComp;
  1055. COMPONENT comp = { sizeof(comp) };
  1056. g_pActiveDeskAdv->GetDesktopItemCount(&cComp, 0);
  1057. for (int i=0; i<cComp; i++)
  1058. {
  1059. if (SUCCEEDED(g_pActiveDeskAdv->GetDesktopItem(i, &comp, 0)))
  1060. {
  1061. if (StrCmpW(pwszUrl, comp.wszSource) == 0)
  1062. {
  1063. break;
  1064. }
  1065. }
  1066. }
  1067. //
  1068. // Find the matching listview entry (search for dwID).
  1069. //
  1070. if (i != cComp)
  1071. {
  1072. int nItems = ListView_GetItemCount(_hwndLV);
  1073. for (i=0; i<nItems; i++)
  1074. {
  1075. LV_ITEM lvi = {0};
  1076. lvi.iItem = i;
  1077. lvi.mask = LVIF_PARAM;
  1078. ListView_GetItem(_hwndLV, &lvi);
  1079. if (lvi.lParam == (LPARAM)comp.dwID)
  1080. {
  1081. //
  1082. // Found it, select it and exit.
  1083. //
  1084. ListView_SetItemState(_hwndLV, i, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  1085. ListView_EnsureVisible(_hwndLV, i, FALSE);
  1086. break;
  1087. }
  1088. }
  1089. }
  1090. }
  1091. INT_PTR NewComponent(HWND hwndOwner, IActiveDesktop * pad, BOOL fDeferGallery, COMPONENT * pcomp)
  1092. {
  1093. HRESULT hrInit = SHCoInitialize();
  1094. TCHAR szSource[INTERNET_MAX_URL_LENGTH];
  1095. COMPONENT comp;
  1096. INT_PTR iChoice = DialogBoxParam(HINST_THISDLL, MAKEINTRESOURCE(IDD_ADDCOMPONENT), hwndOwner, AddComponentDlgProc, (LPARAM)szSource);
  1097. if (!pcomp)
  1098. {
  1099. pcomp = &comp;
  1100. pcomp->dwSize = sizeof(comp);
  1101. pcomp->dwCurItemState = IS_NORMAL;
  1102. }
  1103. if (iChoice == GOTO_GALLERY) // the user wants to launch the gallery
  1104. {
  1105. if (!fDeferGallery)
  1106. {
  1107. WCHAR szGalleryUrl[INTERNET_MAX_URL_LENGTH];
  1108. if (SUCCEEDED(URLSubLoadString(HINST_THISDLL, IDS_VISIT_URL, szGalleryUrl, ARRAYSIZE(szGalleryUrl), URLSUB_ALL)))
  1109. {
  1110. NavToUrlUsingIEW(szGalleryUrl, TRUE);
  1111. }
  1112. }
  1113. }
  1114. else if (iChoice >= 0)
  1115. { // the user has entered a URL address
  1116. WCHAR szSourceW[INTERNET_MAX_URL_LENGTH];
  1117. SHTCharToUnicode(szSource, szSourceW, ARRAYSIZE(szSourceW));
  1118. if (!SUCCEEDED(pad->AddUrl(hwndOwner, szSourceW, pcomp, 0)))
  1119. iChoice = -1;
  1120. }
  1121. SHCoUninitialize(hrInit);
  1122. return iChoice;
  1123. }
  1124. void CCompPropSheetPage::_NewComponent(HWND hwnd)
  1125. {
  1126. COMPONENT comp;
  1127. comp.dwSize = sizeof(comp);
  1128. comp.dwCurItemState = IS_NORMAL;
  1129. INT_PTR iChoice = NewComponent(hwnd, g_pActiveDeskAdv, TRUE, &comp);
  1130. if (iChoice == GOTO_GALLERY) // the user wants to launch the gallery
  1131. {
  1132. _fLaunchGallery = TRUE;
  1133. g_fLaunchGallery = TRUE;
  1134. g_fDirtyAdvanced = TRUE;
  1135. PropSheet_PressButton(GetParent(hwnd), PSBTN_OK);
  1136. }
  1137. else
  1138. {
  1139. if (iChoice >= 0) // the user has entered a URL address
  1140. {
  1141. // Add component to listview.
  1142. //
  1143. // Need to reload the entire listview so that it is shown in
  1144. // the correct zorder.
  1145. _SetUIFromDeskState(TRUE);
  1146. // Select the newly added component.
  1147. _SelectComponent(comp.wszSource);
  1148. }
  1149. g_fDirtyAdvanced = TRUE;
  1150. }
  1151. }
  1152. void CCompPropSheetPage::_EditComponent(HWND hwnd)
  1153. {
  1154. int iIndex = ListView_GetNextItem(_hwndLV, -1, LVNI_SELECTED);
  1155. if (iIndex > -1)
  1156. {
  1157. LV_ITEM lvi = {0};
  1158. lvi.mask = LVIF_PARAM;
  1159. lvi.iItem = iIndex;
  1160. ListView_GetItem(_hwndLV, &lvi);
  1161. COMPONENT comp = { sizeof(comp) };
  1162. if (SUCCEEDED(g_pActiveDeskAdv->GetDesktopItemByID(lvi.lParam, &comp, 0)))
  1163. {
  1164. LPTSTR pszSubscribedURL;
  1165. #ifndef UNICODE
  1166. TCHAR szSubscribedURL[INTERNET_MAX_URL_LENGTH];
  1167. SHUnicodeToAnsi(comp.wszSubscribedURL, szSubscribedURL, ARRAYSIZE(szSubscribedURL));
  1168. pszSubscribedURL = szSubscribedURL;
  1169. #else
  1170. pszSubscribedURL = (LPTSTR)comp.wszSubscribedURL;
  1171. #endif
  1172. if (SUCCEEDED(ShowSubscriptionProperties(pszSubscribedURL, hwnd)))
  1173. {
  1174. g_fDirtyAdvanced = TRUE;
  1175. }
  1176. }
  1177. }
  1178. }
  1179. void CCompPropSheetPage::_DeleteComponent(HWND hwnd)
  1180. {
  1181. int iIndex = ListView_GetNextItem(_hwndLV, -1, LVNI_ALL | LVNI_SELECTED);
  1182. if (iIndex > -1)
  1183. {
  1184. LV_ITEM lvi = {0};
  1185. lvi.mask = LVIF_PARAM;
  1186. lvi.iItem = iIndex;
  1187. ListView_GetItem(_hwndLV, &lvi);
  1188. COMPONENT comp;
  1189. comp.dwSize = sizeof(COMPONENT);
  1190. if (SUCCEEDED(g_pActiveDeskAdv->GetDesktopItemByID(lvi.lParam, &comp, 0)))
  1191. {
  1192. TCHAR szMsg[1024];
  1193. TCHAR szTitle[MAX_PATH];
  1194. LoadString(HINST_THISDLL, IDS_COMP_CONFIRMDEL, szMsg, ARRAYSIZE(szMsg));
  1195. LoadString(HINST_THISDLL, IDS_COMP_TITLE, szTitle, ARRAYSIZE(szTitle));
  1196. if (MessageBox(hwnd, szMsg, szTitle, MB_YESNO | MB_ICONQUESTION) == IDYES)
  1197. {
  1198. g_pActiveDeskAdv->RemoveDesktopItem(&comp, 0);
  1199. ListView_DeleteItem(_hwndLV, iIndex);
  1200. int cComp = ListView_GetItemCount(_hwndLV);
  1201. if (cComp == 0)
  1202. {
  1203. SendMessage(hwnd, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwnd, IDC_COMP_NEW), TRUE);
  1204. }
  1205. else
  1206. {
  1207. int iSel = (iIndex > cComp - 1 ? cComp - 1 : iIndex);
  1208. ListView_SetItemState(_hwndLV, iSel, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  1209. }
  1210. LPTSTR pszSubscribedURL;
  1211. #ifndef UNICODE
  1212. TCHAR szSubscribedURL[INTERNET_MAX_URL_LENGTH];
  1213. SHUnicodeToAnsi(comp.wszSubscribedURL, szSubscribedURL, ARRAYSIZE(szSubscribedURL));
  1214. pszSubscribedURL = szSubscribedURL;
  1215. #else
  1216. pszSubscribedURL = comp.wszSubscribedURL;
  1217. #endif
  1218. DeleteFromSubscriptionList(pszSubscribedURL);
  1219. }
  1220. g_fDirtyAdvanced = TRUE;
  1221. }
  1222. }
  1223. }
  1224. //
  1225. // Desktop Cleanup stuff
  1226. //
  1227. STDAPI ApplyDesktopCleanupSettings()
  1228. {
  1229. // set the registry value
  1230. DWORD dwData = (BST_CHECKED == g_iRunDesktopCleanup) ? 0 : 1;
  1231. SHRegSetUSValue(REGSTR_DESKTOP_CLEANUP, REGSTR_VAL_DONTRUN,
  1232. REG_DWORD, &dwData, sizeof(dwData), SHREGSET_FORCE_HKCU);
  1233. return S_OK;
  1234. }
  1235. void CCompPropSheetPage::_DesktopCleaner(HWND hwnd)
  1236. {
  1237. SHELLEXECUTEINFO sei = {0};
  1238. sei.cbSize = sizeof(sei);
  1239. sei.hwnd = hwnd;
  1240. sei.lpFile = TEXT("rundll32.exe");
  1241. sei.lpParameters = TEXT("fldrclnr.dll,Wizard_RunDLL all");
  1242. sei.nShow = SW_SHOWNORMAL;
  1243. ShellExecuteEx(&sei);
  1244. }
  1245. void CCompPropSheetPage::_SynchronizeAllComponents(IActiveDesktop *pActDesktop)
  1246. {
  1247. IADesktopP2* padp2;
  1248. if (SUCCEEDED(pActDesktop->QueryInterface(IID_PPV_ARG(IADesktopP2, &padp2))))
  1249. {
  1250. padp2->UpdateAllDesktopSubscriptions();
  1251. padp2->Release();
  1252. }
  1253. }
  1254. void CCompPropSheetPage::_OnCommand(HWND hwnd, WORD wNotifyCode, WORD wID, HWND hwndCtl)
  1255. {
  1256. BOOL fFocusToList = FALSE;
  1257. switch (wID)
  1258. {
  1259. case IDC_COMP_NEW:
  1260. _NewComponent(hwnd);
  1261. // 98/08/19 vtan #152418: Set the default border to "New". This
  1262. // will be changed when the focus is changed to the component list
  1263. // but this allows the dialog handling code to draw the default
  1264. // border correctly.
  1265. (BOOL)SendMessage(hwnd, WM_NEXTDLGCTL, reinterpret_cast<WPARAM>(GetDlgItem(hwnd, IDC_COMP_NEW)), static_cast<BOOL>(true));
  1266. fFocusToList = TRUE;
  1267. break;
  1268. case IDC_COMP_PROPERTIES:
  1269. _EditComponent(hwnd);
  1270. // 98/08/19 vtan #152418: Same as above.
  1271. (BOOL)SendMessage(hwnd, WM_NEXTDLGCTL, reinterpret_cast<WPARAM>(GetDlgItem(hwnd, IDC_COMP_PROPERTIES)), static_cast<BOOL>(true));
  1272. fFocusToList = TRUE;
  1273. break;
  1274. case IDC_COMP_DELETE:
  1275. _DeleteComponent(hwnd);
  1276. // 98/08/19 vtan #152418: Same as above.
  1277. (BOOL)SendMessage(hwnd, WM_NEXTDLGCTL, reinterpret_cast<WPARAM>(GetDlgItem(hwnd, IDC_COMP_DELETE)), static_cast<BOOL>(true));
  1278. fFocusToList = TRUE;
  1279. break;
  1280. case IDC_DESKCLNR_RUNWIZARD:
  1281. _DesktopCleaner(hwnd);
  1282. break;
  1283. case IDC_DESKCLNR_CHECK:
  1284. // if the button is clicked, update the global
  1285. {
  1286. int iButState = IsDlgButtonChecked(hwnd, IDC_DESKCLNR_CHECK);
  1287. if (iButState != g_iRunDesktopCleanup)
  1288. {
  1289. ASSERT(iButState != BST_INDETERMINATE);
  1290. g_iRunDesktopCleanup = iButState;
  1291. g_fDirtyAdvanced = TRUE;
  1292. }
  1293. }
  1294. break;
  1295. case IDC_COMP_SYNCHRONIZE:
  1296. _SynchronizeAllComponents(g_pActiveDeskAdv);
  1297. break;
  1298. case IDC_CHANGEICON2:
  1299. if (-1 != m_nIndex)
  1300. {
  1301. WCHAR szExp[MAX_PATH];
  1302. INT i = _IconData[m_nIndex].iOldIndex;
  1303. ExpandEnvironmentStringsW(_IconData[m_nIndex].szOldFile, szExp, ARRAYSIZE(szExp));
  1304. if (PickIconDlg(hwnd, szExp, ARRAYSIZE(szExp), &i) == TRUE)
  1305. {
  1306. HICON hIcon;
  1307. StrCpyNW(_IconData[m_nIndex].szNewFile, szExp, ARRAYSIZE(_IconData[m_nIndex].szNewFile));
  1308. _IconData[m_nIndex].iNewIndex = i;
  1309. if (SUCCEEDED(ExtractPlusColorIcon(_IconData[m_nIndex].szNewFile, _IconData[m_nIndex].iNewIndex, &hIcon, 0, 0)))
  1310. {
  1311. ImageList_ReplaceIcon(_hIconList, m_nIndex, hIcon);
  1312. ListView_RedrawItems(_hWndList, m_nIndex, m_nIndex);
  1313. }
  1314. }
  1315. SetFocus(_hWndList);
  1316. }
  1317. break;
  1318. case IDC_ICONDEFAULT:
  1319. if (-1 != m_nIndex)
  1320. {
  1321. TCHAR szPath[MAX_PATH];
  1322. HICON hIcon;
  1323. if (!ExpandEnvironmentStrings(c_aIconRegKeys[m_nIndex].pszDefault, szPath, ARRAYSIZE(szPath)))
  1324. {
  1325. StrCpyNW(szPath, c_aIconRegKeys[m_nIndex].pszDefault, ARRAYSIZE(szPath));
  1326. }
  1327. StrCpyN(_IconData[m_nIndex].szNewFile, szPath, ARRAYSIZE(_IconData[m_nIndex].szNewFile));
  1328. _IconData[m_nIndex].iNewIndex = c_aIconRegKeys[m_nIndex].nDefaultIndex;
  1329. ExtractPlusColorIcon(_IconData[m_nIndex].szNewFile, _IconData[m_nIndex].iNewIndex, &hIcon, 0, 0);
  1330. ImageList_ReplaceIcon(_hIconList, m_nIndex, hIcon);
  1331. ListView_RedrawItems(_hWndList, m_nIndex, m_nIndex);
  1332. SetFocus(_hWndList);
  1333. }
  1334. break;
  1335. case IDC_DESKTOP_ICON_MYDOCS:
  1336. case IDC_DESKTOP_ICON_MYCOMP:
  1337. case IDC_DESKTOP_ICON_MYNET:
  1338. case IDC_DESKTOP_ICON_IE:
  1339. {
  1340. //Get the current button state and save it.
  1341. BOOL fOriginalBtnState = IsDlgButtonChecked(hwnd, wID);
  1342. //Toggle the button from checked to unchecked (or vice-versa).
  1343. CheckDlgButton(hwnd, wID, (fOriginalBtnState ? BST_UNCHECKED : BST_CHECKED));
  1344. for(int iIndex = 0; iIndex < NUM_DESKICONS; iIndex++)
  1345. {
  1346. if(wID == c_aDeskIconId[iIndex].iDeskIconDlgItemId)
  1347. {
  1348. // Note#1: The inverse logic is used below. If the originally button is checked,
  1349. // it means that now it is unchecked, which means that icon should now be hidden;
  1350. // (i.e) the HideDeskIcon[][] should be set to TRUE.
  1351. //
  1352. // Note#2: When the end-user toggles these, we want to set the same setting for
  1353. // both the modes now!
  1354. _afHideIcon[0][iIndex] = _afHideIcon[1][iIndex] = fOriginalBtnState;
  1355. }
  1356. }
  1357. }
  1358. break;
  1359. }
  1360. //Set the focus back to the components list, if necessary
  1361. if (fFocusToList)
  1362. {
  1363. int iIndex = ListView_GetNextItem(_hwndLV, -1, LVNI_SELECTED);
  1364. if (iIndex > -1)
  1365. {
  1366. SetFocus(GetDlgItem(hwnd, IDC_COMP_LIST));
  1367. }
  1368. }
  1369. }
  1370. void CCompPropSheetPage::_OnDestroy(INT iPage)
  1371. {
  1372. if (CUSTOMIZE_DLGPROC == iPage)
  1373. {
  1374. ReleaseActiveDesktop(&g_pActiveDeskAdv);
  1375. if (_fLaunchGallery)
  1376. {
  1377. WCHAR szGalleryUrl[INTERNET_MAX_URL_LENGTH];
  1378. if (SUCCEEDED(URLSubLoadString(HINST_THISDLL, IDS_VISIT_URL, szGalleryUrl, ARRAYSIZE(szGalleryUrl), URLSUB_ALL)))
  1379. {
  1380. NavToUrlUsingIEW(szGalleryUrl, TRUE);
  1381. }
  1382. }
  1383. }
  1384. }
  1385. void CCompPropSheetPage::_OnGetCurSel(int *piIndex)
  1386. {
  1387. if (_hwndLV)
  1388. {
  1389. *piIndex = ListView_GetNextItem(_hwndLV, -1, LVNI_ALL | LVNI_SELECTED);
  1390. }
  1391. else
  1392. {
  1393. *piIndex = -1;
  1394. }
  1395. }
  1396. INT_PTR CCompPropSheetPage::_CustomizeDlgProcHelper(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam, INT iPage)
  1397. {
  1398. CCompPropSheetPage * pThis;
  1399. if (WM_INITDIALOG == wMsg)
  1400. {
  1401. pThis = (CCompPropSheetPage *) ((PROPSHEETPAGE*)lParam)->lParam;
  1402. if (pThis)
  1403. {
  1404. SetWindowLongPtr(hDlg, DWLP_USER, (LPARAM) pThis);
  1405. }
  1406. }
  1407. else
  1408. {
  1409. pThis = (CCompPropSheetPage *)GetWindowLongPtr(hDlg, DWLP_USER);
  1410. }
  1411. if (pThis)
  1412. return pThis->_CustomizeDlgProc(hDlg, wMsg, wParam, lParam, iPage);
  1413. return DefWindowProc(hDlg, wMsg, wParam, lParam);
  1414. }
  1415. INT_PTR CALLBACK CCompPropSheetPage::CustomizeDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
  1416. {
  1417. return _CustomizeDlgProcHelper(hDlg, wMsg, wParam, lParam, CUSTOMIZE_DLGPROC);
  1418. }
  1419. INT_PTR CALLBACK CCompPropSheetPage::WebDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
  1420. {
  1421. return _CustomizeDlgProcHelper(hDlg, wMsg, wParam, lParam, CUSTOMIZE_WEB_DLGPROC);
  1422. }
  1423. BOOL_PTR CCompPropSheetPage::_CustomizeDlgProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam, INT iPage)
  1424. {
  1425. switch(uMsg)
  1426. {
  1427. case WM_INITDIALOG:
  1428. _OnInitDialog(hdlg, iPage);
  1429. break;
  1430. case WM_NOTIFY:
  1431. _OnNotify(hdlg, wParam, (LPNMHDR)lParam);
  1432. break;
  1433. case WM_COMMAND:
  1434. _OnCommand(hdlg, HIWORD(wParam), LOWORD(wParam), (HWND)lParam);
  1435. break;
  1436. case WM_SETTINGCHANGE:
  1437. //Check if this is a shell StateChange?
  1438. if(lstrcmpi((LPTSTR)(lParam), TEXT("ShellState")) == 0)
  1439. {
  1440. //Check if the StartPanel on/off state has changed.
  1441. SHELLSTATE ss = {0};
  1442. SHGetSetSettings(&ss, SSF_STARTPANELON, FALSE); //See if the StartPanel is on!
  1443. //See if the StartPanel on/off state has changed
  1444. if(BOOLIFY(ss.fStartPanelOn) != BOOLIFY((BOOL)_iStartPanelOn))
  1445. {
  1446. _iStartPanelOn = (ss.fStartPanelOn ? 1 : 0); //Save the new state.
  1447. //Refresh the UI based on the new state.
  1448. _UpdateDesktopIconsUI(hdlg);
  1449. }
  1450. }
  1451. // Intentional fallthrough....
  1452. case WM_SYSCOLORCHANGE:
  1453. case WM_DISPLAYCHANGE:
  1454. SHPropagateMessage(hdlg, uMsg, wParam, lParam, TRUE);
  1455. break;
  1456. case WM_DESTROY:
  1457. _OnDestroy(iPage);
  1458. break;
  1459. case WM_COMP_GETCURSEL:
  1460. _OnGetCurSel((int *)lParam);
  1461. break;
  1462. case WM_HELP:
  1463. WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, SZ_HELPFILE_DESKTOPITEMS, HELP_WM_HELP, (ULONG_PTR)(void *)aDesktopItemsHelpIDs);
  1464. break;
  1465. case WM_CONTEXTMENU:
  1466. WinHelp((HWND) wParam, SZ_HELPFILE_DESKTOPITEMS, HELP_CONTEXTMENU, (ULONG_PTR)(void *) aDesktopItemsHelpIDs);
  1467. break;
  1468. }
  1469. return FALSE;
  1470. }
  1471. HRESULT CCompPropSheetPage::_IsDirty(IN BOOL * pIsDirty)
  1472. {
  1473. HRESULT hr = E_INVALIDARG;
  1474. if (pIsDirty)
  1475. {
  1476. *pIsDirty = g_fDirtyAdvanced;
  1477. if (!*pIsDirty)
  1478. {
  1479. // Check if any of the icons have changed.
  1480. for (int nIndex = 0; nIndex < ARRAYSIZE(_IconData); nIndex++)
  1481. {
  1482. if ((_IconData[nIndex].iNewIndex != _IconData[nIndex].iOldIndex) ||
  1483. (StrCmpI(_IconData[nIndex].szNewFile, _IconData[nIndex].szOldFile)))
  1484. {
  1485. *pIsDirty = TRUE;
  1486. break;
  1487. }
  1488. }
  1489. }
  1490. hr = S_OK;
  1491. }
  1492. return hr;
  1493. }
  1494. HRESULT CCompPropSheetPage::DisplayAdvancedDialog(IN HWND hwndParent, IN IPropertyBag * pAdvPage, IN BOOL * pfEnableApply)
  1495. {
  1496. HRESULT hr = S_OK;
  1497. // Load State Into Advanced Dialog
  1498. *pfEnableApply = FALSE;
  1499. GetActiveDesktop(&g_pActiveDesk);
  1500. GetActiveDesktop(&g_pActiveDeskAdv);
  1501. ActiveDesktop_CopyState(g_pActiveDesk, g_pActiveDeskAdv);
  1502. hr = _LoadIconState(pAdvPage);
  1503. if (SUCCEEDED(hr))
  1504. {
  1505. hr = _LoadDeskIconState(pAdvPage);
  1506. if (SUCCEEDED(hr))
  1507. {
  1508. int iNumberOfPages = 2;
  1509. PROPSHEETPAGE psp = {0};
  1510. psp.dwSize = sizeof(psp);
  1511. psp.hInstance = HINST_THISDLL;
  1512. psp.dwFlags = PSP_DEFAULT;
  1513. psp.lParam = (LPARAM) this;
  1514. psp.pszTemplate = MAKEINTRESOURCE(IDD_CUSTOMIZE);
  1515. psp.pfnDlgProc = CCompPropSheetPage::CustomizeDlgProc;
  1516. HPROPSHEETPAGE rghpsp[2];
  1517. rghpsp[0] = CreatePropertySheetPage(&psp);
  1518. // Any of the following policies can disable the Web tab.
  1519. // 1. If no active desktop policy set, don't put up the property page
  1520. // 2. If policy is set to lock down active desktop, don't put up the
  1521. // property page
  1522. // 3. If policy is set to not allow components, don't put up the
  1523. // property page
  1524. if (((!SHRestricted(REST_FORCEACTIVEDESKTOPON)) && PolicyNoActiveDesktop()) || // 1.
  1525. (SHRestricted(REST_NOACTIVEDESKTOPCHANGES)) || // 2.
  1526. (SHRestricted(REST_NODESKCOMP)) || // 3.
  1527. (SHRestricted(REST_CLASSICSHELL))) // 4
  1528. {
  1529. // It's restricted, so don't add Web page.
  1530. iNumberOfPages = 1; //"General" page is the only page in this property sheet!
  1531. }
  1532. else
  1533. {
  1534. // No active desktop restriction! Go ahead and add the "Web" tab!
  1535. psp.pszTemplate = MAKEINTRESOURCE(IDD_CUSTOMIZE_WEB);
  1536. psp.pfnDlgProc = CCompPropSheetPage::WebDlgProc;
  1537. rghpsp[1] = CreatePropertySheetPage(&psp);
  1538. iNumberOfPages = 2; //"General" and "Web" are the two pages in this Property sheet!
  1539. }
  1540. PROPSHEETHEADER psh = {0};
  1541. psh.dwSize = sizeof(psh);
  1542. psh.dwFlags = PSH_NOAPPLYNOW;
  1543. psh.hwndParent = hwndParent;
  1544. psh.hInstance = HINST_THISDLL;
  1545. TCHAR szTitle[MAX_PATH];
  1546. LoadString(HINST_THISDLL, IDS_PROPSHEET_TITLE, szTitle, ARRAYSIZE(szTitle));
  1547. psh.pszCaption = szTitle;
  1548. psh.nPages = iNumberOfPages;
  1549. psh.phpage = rghpsp;
  1550. _fCustomizeDesktopOK = FALSE;
  1551. PropertySheet(&psh);
  1552. if (_fCustomizeDesktopOK)
  1553. {
  1554. // The user clicked OK, so merge modified state back into base dialog
  1555. _IsDirty(pfEnableApply);
  1556. // The user clicked Okay in the dialog so merge the dirty state from the
  1557. // advanced dialog into the base dialog.
  1558. MergeState();
  1559. _MergeIconState(pAdvPage);
  1560. _MergeDeskIconState(pAdvPage);
  1561. }
  1562. // If the user selected to open the component gallery in Web->New, then
  1563. // we want to close both the Advanced dlg and the base Dlg with "OK".
  1564. // This way we persist the changes they have made so far, and then the web
  1565. // page will allow them to add more.
  1566. if (TRUE == g_fLaunchGallery)
  1567. {
  1568. IThemeUIPages * pThemeUIPages;
  1569. HWND hwndBasePropDlg = GetParent(hwndParent);
  1570. PropSheet_PressButton(hwndBasePropDlg, PSBTN_OK);
  1571. hr = IUnknown_GetSite(pAdvPage, IID_PPV_ARG(IThemeUIPages, &pThemeUIPages));
  1572. if (SUCCEEDED(hr))
  1573. {
  1574. // We now want to tell the base dialog to close too.
  1575. hr = pThemeUIPages->ApplyPressed(TUIAP_CLOSE_DIALOG);
  1576. pThemeUIPages->Release();
  1577. }
  1578. }
  1579. }
  1580. }
  1581. ReleaseActiveDesktop(&g_pActiveDesk);
  1582. ReleaseActiveDesktop(&g_pActiveDeskAdv);
  1583. return hr;
  1584. }
  1585. ULONG CCompPropSheetPage::AddRef()
  1586. {
  1587. _cRef++;
  1588. return _cRef;
  1589. }
  1590. ULONG CCompPropSheetPage::Release()
  1591. {
  1592. ASSERT(_cRef > 0);
  1593. _cRef--;
  1594. if (_cRef > 0)
  1595. return _cRef;
  1596. delete this;
  1597. return 0;
  1598. }
  1599. HRESULT CCompPropSheetPage::QueryInterface(REFIID riid, void **ppvObj)
  1600. {
  1601. HRESULT hr = E_NOINTERFACE;
  1602. static const QITAB qit[] = {
  1603. QITABENT(CCompPropSheetPage, IObjectWithSite),
  1604. QITABENT(CCompPropSheetPage, IAdvancedDialog),
  1605. { 0 },
  1606. };
  1607. return QISearch(this, qit, riid, ppvObj);
  1608. }
  1609. CCompPropSheetPage::CCompPropSheetPage() : _iPreviousSelection(-1), _cRef(1)
  1610. {
  1611. _fInitialized = FALSE;
  1612. _fLaunchGallery = FALSE;
  1613. _punkSite = NULL;
  1614. _hWndList = NULL;
  1615. _hIconList = NULL;
  1616. _fLockDesktopItems = GetDesktopFlags() & COMPONENTS_LOCKED;
  1617. // We don't need to do any work here but it's a good cue to
  1618. // reset our state because the Advance dialog is opening.
  1619. g_fDirtyAdvanced = FALSE; // The advanced page isn't dirty yet.
  1620. g_fLaunchGallery = FALSE; // Will be true if they launch the gallery.
  1621. RegisterCompPreviewClass();
  1622. }
  1623. CCompPropSheetPage::~CCompPropSheetPage()
  1624. {
  1625. }
  1626. //
  1627. // The following function updates the registry such that the given icon can be hidden or shown
  1628. // on the desktop.
  1629. // This function is called from RegFldr.cpp to selectively hide RegItems like MyComputer,
  1630. // RecycleBin, MyDocuments and MyNetplaces Icons.
  1631. //
  1632. HRESULT ShowHideIconOnlyOnDesktop(const CLSID *pclsid, int StartIndex, int EndIndex, BOOL fHide)
  1633. {
  1634. HRESULT hr = S_OK;
  1635. int iStartPanel;
  1636. TCHAR szRegPath[MAX_PATH];
  1637. TCHAR szValueName[MAX_GUID_STRING_LEN];
  1638. SHStringFromGUID(*pclsid, szValueName, ARRAYSIZE(szValueName));
  1639. // i = 0 is for StartPanel off and i = 1 is for StartPanel ON!
  1640. for(iStartPanel = StartIndex; iStartPanel <= EndIndex; iStartPanel++)
  1641. {
  1642. //Get the proper registry path based on if StartPanel is ON/OFF
  1643. wsprintf(szRegPath, REGSTR_PATH_HIDDEN_DESKTOP_ICONS, c_apstrRegLocation[iStartPanel]);
  1644. //Write the setting to the registry!
  1645. DWORD dwHide = (DWORD)fHide;
  1646. LONG lRet = SHRegSetUSValue(szRegPath, szValueName, REG_DWORD, &dwHide, sizeof(dwHide), SHREGSET_FORCE_HKCU);
  1647. hr = HRESULT_FROM_WIN32(lRet);
  1648. if(FAILED(hr))
  1649. return hr; //If failed, return immediately.
  1650. }
  1651. return S_OK;
  1652. }