Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

571 lines
21 KiB

  1. #include "stdafx.h"
  2. #include <trayp.h>
  3. #include "utils.h"
  4. #include "..\deskfldr.h"
  5. #pragma hdrstop
  6. #define SZ_FOLDEROPTSTUBCLASS TEXT("MSGlobalFolderOptionsStub")
  7. void Cabinet_StateChanged(CABINETSTATE *pcs);
  8. const static DWORD aFolderOptsHelpIDs[] = { // Context Help IDs
  9. IDC_FCUS_SAME_WINDOW, IDH_BROWSE_SAME_WINDOW,
  10. IDC_FCUS_SEPARATE_WINDOWS, IDH_BROWSE_SEPARATE_WINDOWS,
  11. IDC_FCUS_WHENEVER_POSSIBLE, IDH_SHOW_WEB_WHEN_POSSIBLE,
  12. IDC_FCUS_WHEN_CHOOSE, IDH_SHOW_WEB_WHEN_CHOOSE,
  13. IDC_FCUS_SINGLECLICK, IDH_SINGLE_CLICK_MODE,
  14. IDC_FCUS_DOUBLECLICK, IDH_DOUBLE_CLICK_MODE,
  15. IDC_FCUS_ICON_IE, IDH_TITLES_LIKE_LINKS,
  16. IDC_FCUS_ICON_HOVER, IDH_TITLES_WHEN_POINT,
  17. IDC_FCUS_ICON_WEBVIEW, IDH_WEB_VIEW_GEN,
  18. IDC_FCUS_ICON_WINDOW, IDH_BROWSE_FOLDERS_GEN,
  19. IDC_FCUS_ICON_CLICKS, IDH_ICON_OPEN_GEN,
  20. IDC_FCUS_RESTORE_DEFAULTS, IDH_RESTORE_DEFAULTS_GEN,
  21. IDC_FCUS_WEBVIEW_GROUP_STATIC, -1, // Suppress help for this item.
  22. 0, 0
  23. };
  24. typedef struct
  25. {
  26. CABINETSTATE cs; // Cached "current" CabState.
  27. CFolderOptionsPsx *ppsx; // to talk to our propsheet sibling
  28. // The icons corresponding to the radio button selected are stored here.
  29. HICON ahIcon[IDC_FCUS_ICON_MAX - IDC_FCUS_WHENEVER_POSSIBLE + 1];
  30. } FOLDEROPTDATA;
  31. // Reads CabinetState and Default Folder Settings
  32. void ReadStateAndSettings(HWND hDlg)
  33. {
  34. FOLDEROPTDATA *pfod = (FOLDEROPTDATA *)GetWindowLongPtr(hDlg, DWLP_USER);
  35. pfod->ppsx->SetNeedRefresh(FALSE);
  36. //Get the current Cabinet State
  37. ReadCabinetState(&pfod->cs, sizeof(pfod->cs));
  38. }
  39. //
  40. // This function selects a given radio button among a set of radio buttons AND it sets the Icon
  41. // image corresponding to the radio button selected.
  42. void CheckRBtnAndSetIcon(HWND hDlg, int idStartBtn, int idEndBtn, int idSelectedBtn, FOLDEROPTDATA *pfod, BOOL fCheckBtn)
  43. {
  44. //
  45. // Check the radio button if required
  46. //
  47. if (fCheckBtn)
  48. CheckRadioButton(hDlg, idStartBtn, idEndBtn, idSelectedBtn);
  49. // Now, select the Icon corresponding to this selection
  50. // The following code assumes the order and sequence of the following IDs.
  51. // So, we verify that no one has broken them inadvertently by doing the following
  52. // compile time checks.
  53. COMPILETIME_ASSERT((IDC_FCUS_WHENEVER_POSSIBLE + 1) == IDC_FCUS_WHEN_CHOOSE);
  54. COMPILETIME_ASSERT((IDC_FCUS_WHEN_CHOOSE + 1) == IDC_FCUS_SAME_WINDOW);
  55. COMPILETIME_ASSERT((IDC_FCUS_SAME_WINDOW + 1) == IDC_FCUS_SEPARATE_WINDOWS);
  56. COMPILETIME_ASSERT((IDC_FCUS_SEPARATE_WINDOWS + 1) == IDC_FCUS_SINGLECLICK);
  57. COMPILETIME_ASSERT((IDC_FCUS_SINGLECLICK + 1) == IDC_FCUS_DOUBLECLICK);
  58. COMPILETIME_ASSERT((IDC_FCUS_DOUBLECLICK + 1) == IDC_FCUS_ICON_IE);
  59. COMPILETIME_ASSERT((IDC_FCUS_ICON_IE + 1) == IDC_FCUS_ICON_HOVER);
  60. COMPILETIME_ASSERT((IDC_FCUS_ICON_HOVER + 1) == IDC_FCUS_ICON_MAX);
  61. COMPILETIME_ASSERT((IDI_WEBVIEW_ON + 1) == IDI_WEBVIEW_OFF);
  62. COMPILETIME_ASSERT((IDI_WEBVIEW_OFF + 1) == IDI_SAME_WINDOW);
  63. COMPILETIME_ASSERT((IDI_SAME_WINDOW + 1) == IDI_SEPARATE_WINDOW);
  64. COMPILETIME_ASSERT((IDI_SEPARATE_WINDOW + 1)== IDI_SINGLE_CLICK);
  65. COMPILETIME_ASSERT((IDI_SINGLE_CLICK + 1) == IDI_DOUBLE_CLICK);
  66. COMPILETIME_ASSERT((IDC_FCUS_ICON_WEBVIEW + 1) == IDC_FCUS_ICON_WINDOW);
  67. COMPILETIME_ASSERT((IDC_FCUS_ICON_WINDOW + 1) == IDC_FCUS_ICON_CLICKS);
  68. ASSERT((IDC_FCUS_ICON_MAX - IDC_FCUS_WHENEVER_POSSIBLE + 1) == ARRAYSIZE(pfod->ahIcon));
  69. int iIndex = idSelectedBtn - IDC_FCUS_WHENEVER_POSSIBLE; //Calculate the index into the Icon Table
  70. ASSERT(iIndex < ARRAYSIZE(pfod->ahIcon));
  71. if (pfod->ahIcon[iIndex] == NULL)
  72. pfod->ahIcon[iIndex] = (HICON)LoadImage(HINST_THISDLL, MAKEINTRESOURCE(IDI_WEBVIEW_ON + iIndex), IMAGE_ICON, 0,0, LR_DEFAULTSIZE);
  73. // Set the Icon image corresponding to the Radio button selected.
  74. // This dialog is broken into sections of radio buttons. Each section has two and only two main
  75. // radio buttons and a corresponding icon. In order to associate the radio buttons with their
  76. // corresponding icon, all button ids and all icon ids are kept in order (hence the above COMPILETIME_ASSERTs),
  77. // such that the first and second radio buttons belong with the first icon, second and third radio buttons
  78. // belong with the second icon, and so on. Now, given a radio button id, get its position in the list of
  79. // all the radio buttons (that is the index assigment just above) and shift it right by one bit to get the index
  80. // of the corresponding icon. The shift is neccesary because there is only one icon every two radio buttons.
  81. SendDlgItemMessage(hDlg, IDC_FCUS_ICON_WEBVIEW + (iIndex >> 1), STM_SETICON, (WPARAM)(pfod->ahIcon[iIndex]), 0);
  82. }
  83. BOOL_PTR CALLBACK FolderOptionsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  84. {
  85. static BOOL fCheckedSingleClickDialog = FALSE;
  86. static BOOL fCheckedWebStyle = FALSE;
  87. int idSelectedBtn, i;
  88. FOLDEROPTDATA *pfod = (FOLDEROPTDATA *)GetWindowLongPtr(hDlg, DWLP_USER);
  89. switch (uMsg)
  90. {
  91. case WM_INITDIALOG:
  92. {
  93. pfod = (FOLDEROPTDATA *)LocalAlloc(LPTR, sizeof(*pfod));
  94. if (pfod)
  95. {
  96. BOOL fClassicShell, fForceActiveDesktopOn;
  97. SHELLSTATE ss = { 0 };
  98. //Set the Folder Options data
  99. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pfod);
  100. PROPSHEETPAGE *pps = (PROPSHEETPAGE *)lParam;
  101. pfod->ppsx = (CFolderOptionsPsx *)pps->lParam;
  102. ReadStateAndSettings(hDlg);
  103. // No need to initialize the array of icons with zeros
  104. // for(i = 0; i < ARRAYSIZE(pfod->ahIcon); i++)
  105. // pfod->ahIcon[i] = NULL;
  106. fClassicShell = SHRestricted(REST_CLASSICSHELL);
  107. fForceActiveDesktopOn = SHRestricted(REST_FORCEACTIVEDESKTOPON);
  108. SHGetSetSettings(&ss, SSF_DOUBLECLICKINWEBVIEW | SSF_WIN95CLASSIC | SSF_WEBVIEW, FALSE);
  109. // browse folder options
  110. CheckRBtnAndSetIcon(hDlg,
  111. IDC_FCUS_SAME_WINDOW,
  112. IDC_FCUS_SEPARATE_WINDOWS,
  113. pfod->cs.fNewWindowMode ? IDC_FCUS_SEPARATE_WINDOWS:IDC_FCUS_SAME_WINDOW, pfod, TRUE);
  114. // show folders as web pages
  115. CheckRBtnAndSetIcon(hDlg,
  116. IDC_FCUS_WHENEVER_POSSIBLE,
  117. IDC_FCUS_WHEN_CHOOSE,
  118. ss.fWebView && !fClassicShell? IDC_FCUS_WHENEVER_POSSIBLE : IDC_FCUS_WHEN_CHOOSE, pfod, TRUE);
  119. if (SHRestricted(REST_NOWEBVIEW) || fClassicShell)
  120. {
  121. EnableWindow(GetDlgItem(hDlg, IDC_FCUS_WHENEVER_POSSIBLE), FALSE);
  122. //EnableWindow(GetDlgItem(hDlg, IDC_FCUS_WHEN_CHOOSE), FALSE);
  123. //EnableWindow(GetDlgItem(hDlg, IDC_FCUS_WEBVIEW_GROUP_STATIC), FALSE);
  124. }
  125. // single/double click
  126. CheckRBtnAndSetIcon(hDlg,
  127. IDC_FCUS_SINGLECLICK,IDC_FCUS_DOUBLECLICK,
  128. !ss.fWin95Classic
  129. ? (ss.fDoubleClickInWebView ? IDC_FCUS_DOUBLECLICK:IDC_FCUS_SINGLECLICK)
  130. : IDC_FCUS_DOUBLECLICK, pfod, TRUE);
  131. if (fClassicShell)
  132. {
  133. EnableWindow(GetDlgItem(hDlg, IDC_FCUS_SINGLECLICK), FALSE);
  134. }
  135. // gray out icon underline behvaior when not in single click mode
  136. BOOL fChecked = IsDlgButtonChecked(hDlg, IDC_FCUS_SINGLECLICK);
  137. EnableWindow(GetDlgItem(hDlg, IDC_FCUS_ICON_IE), fChecked);
  138. EnableWindow(GetDlgItem(hDlg, IDC_FCUS_ICON_HOVER), fChecked);
  139. DWORD dwIconUnderline = ICON_IE;
  140. if (!fClassicShell)
  141. {
  142. DWORD cb = sizeof(dwIconUnderline);
  143. SHRegGetUSValue(TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"),
  144. TEXT("IconUnderline"),
  145. NULL,
  146. &dwIconUnderline,
  147. &cb,
  148. FALSE,
  149. &dwIconUnderline,
  150. cb);
  151. }
  152. // JANK : Fix for MIL bug #105236
  153. // Since these are sub radio buttons, they do not have an icon and therefore do not need
  154. // the CheckRBtnAndSetIcon call
  155. CheckRadioButton(hDlg, IDC_FCUS_ICON_IE, IDC_FCUS_ICON_HOVER,
  156. dwIconUnderline == ICON_IE ? IDC_FCUS_ICON_IE : IDC_FCUS_ICON_HOVER);
  157. /*
  158. CheckRBtnAndSetIcon(hDlg,
  159. IDC_FCUS_ICON_IE, IDC_FCUS_ICON_HOVER,
  160. dwIconUnderline == ICON_IE ? IDC_FCUS_ICON_IE : IDC_FCUS_ICON_HOVER, pfod, TRUE);
  161. */
  162. if (fClassicShell)
  163. {
  164. EnableWindow(GetDlgItem(hDlg, IDC_FCUS_ICON_HOVER), FALSE);
  165. }
  166. }
  167. else
  168. {
  169. // Can't use EndDialog because we weren't created by DialogBox()
  170. DestroyWindow(hDlg);
  171. }
  172. return TRUE;
  173. }
  174. case WM_NOTIFY:
  175. switch (((NMHDR *)lParam)->code)
  176. {
  177. case PSN_APPLY:
  178. {
  179. SHELLSTATE oldss = {0}, ss = { 0 };
  180. SHGetSetSettings(&oldss, SSF_DOUBLECLICKINWEBVIEW | SSF_WIN95CLASSIC | SSF_WEBVIEW, FALSE);
  181. BOOL fOldValue = BOOLIFY(pfod->cs.fNewWindowMode);
  182. if (IsDlgButtonChecked(hDlg, IDC_FCUS_SAME_WINDOW))
  183. pfod->cs.fNewWindowMode = FALSE;
  184. else
  185. pfod->cs.fNewWindowMode = TRUE;
  186. if (fOldValue != (pfod->cs.fNewWindowMode ? 1 : 0))
  187. Cabinet_StateChanged(&pfod->cs);
  188. if (IsDlgButtonChecked(hDlg, IDC_FCUS_WHENEVER_POSSIBLE))
  189. {
  190. ss.fWin95Classic = FALSE;
  191. ss.fWebView = TRUE;
  192. }
  193. else
  194. {
  195. ss.fWin95Classic = TRUE;
  196. ss.fWebView = FALSE;
  197. }
  198. if (IsDlgButtonChecked(hDlg, IDC_FCUS_SINGLECLICK))
  199. {
  200. ss.fDoubleClickInWebView = FALSE;
  201. ss.fWin95Classic = FALSE;
  202. }
  203. else
  204. {
  205. ss.fDoubleClickInWebView = TRUE;
  206. ss.fWin95Classic = FALSE;
  207. }
  208. DWORD dwIconUnderline, dwOldIconUnderline, dwDefaultIconUnderline;
  209. DWORD cb = sizeof(dwIconUnderline);
  210. //Get the current settings for "IconUnderline"
  211. dwDefaultIconUnderline = -1; // not ICON_IE or will not WM_WININICHANGE
  212. SHRegGetUSValue(TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"),
  213. TEXT("IconUnderline"), NULL, &dwOldIconUnderline, &cb,
  214. FALSE, &dwDefaultIconUnderline, sizeof(dwDefaultIconUnderline));
  215. if (IsDlgButtonChecked(hDlg, IDC_FCUS_ICON_IE))
  216. dwIconUnderline = ICON_IE;
  217. else
  218. dwIconUnderline = ICON_HOVER;
  219. if (dwOldIconUnderline != dwIconUnderline) //See if this setting has changed
  220. {
  221. cb = sizeof(dwIconUnderline);
  222. SHRegSetUSValue(TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"),
  223. TEXT("IconUnderline"), NULL, &dwIconUnderline, cb,
  224. SHREGSET_DEFAULT);
  225. SHSendMessageBroadcast(WM_WININICHANGE, 0, (LPARAM)TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\IconUnderline"));
  226. }
  227. DWORD dwMask = 0;
  228. if (ss.fWebView != oldss.fWebView)
  229. {
  230. dwMask |= SSF_WEBVIEW;
  231. }
  232. if (ss.fWin95Classic != oldss.fWin95Classic)
  233. {
  234. dwMask |= SSF_WIN95CLASSIC;
  235. }
  236. if (ss.fDoubleClickInWebView != oldss.fDoubleClickInWebView)
  237. {
  238. dwMask |= SSF_DOUBLECLICKINWEBVIEW;
  239. }
  240. if (dwMask)
  241. {
  242. SHGetSetSettings(&ss, dwMask, TRUE);
  243. }
  244. if (ss.fWebView != oldss.fWebView)
  245. {
  246. Cabinet_RefreshAll(Cabinet_UpdateWebViewEnum, (LPARAM)ss.fWebView);
  247. // Note: This refreshes as well.
  248. }
  249. if ((ss.fWin95Classic != oldss.fWin95Classic)
  250. || (ss.fDoubleClickInWebView != oldss.fDoubleClickInWebView))
  251. {
  252. Cabinet_RefreshAll(Cabinet_RefreshEnum, (LPARAM)0);
  253. }
  254. return TRUE;
  255. }
  256. case PSN_KILLACTIVE:
  257. // validate here
  258. // SetWindowLongPtr(hDlg, DWLP_MSGRESULT, !ValidateLink()); // don't allow close
  259. return TRUE;
  260. case PSN_SETACTIVE:
  261. if (pfod->ppsx->NeedRefresh())
  262. {
  263. ReadStateAndSettings(hDlg);
  264. }
  265. return TRUE;
  266. }
  267. break;
  268. case WM_HELP:
  269. WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, TEXT(SHELL_HLP),
  270. HELP_WM_HELP, (ULONG_PTR)(LPTSTR) aFolderOptsHelpIDs);
  271. break;
  272. case WM_CONTEXTMENU:
  273. WinHelp((HWND) wParam, TEXT(SHELL_HLP), HELP_CONTEXTMENU,
  274. (ULONG_PTR)(void *)aFolderOptsHelpIDs);
  275. break;
  276. case WM_COMMAND:
  277. idSelectedBtn = GET_WM_COMMAND_ID(wParam, lParam);
  278. switch (idSelectedBtn)
  279. {
  280. case IDC_FCUS_SINGLECLICK:
  281. case IDC_FCUS_DOUBLECLICK:
  282. if (GET_WM_COMMAND_CMD(wParam,lParam) == BN_CLICKED)
  283. {
  284. EnableWindow(GetDlgItem(hDlg, IDC_FCUS_ICON_IE), GET_WM_COMMAND_ID(wParam,lParam) == IDC_FCUS_SINGLECLICK);
  285. EnableWindow(GetDlgItem(hDlg, IDC_FCUS_ICON_HOVER), GET_WM_COMMAND_ID(wParam,lParam) == IDC_FCUS_SINGLECLICK);
  286. }
  287. //Fall through ...
  288. case IDC_FCUS_WHENEVER_POSSIBLE:
  289. case IDC_FCUS_WHEN_CHOOSE:
  290. case IDC_FCUS_SAME_WINDOW:
  291. case IDC_FCUS_SEPARATE_WINDOWS:
  292. // We do not need to Check the radio button; It is alreay checked. We just need to
  293. // set the corresponding Icon. Hence we pass FALSE.
  294. CheckRBtnAndSetIcon(hDlg, 0, 0, idSelectedBtn, pfod, FALSE);
  295. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
  296. break;
  297. case IDC_FCUS_ICON_IE:
  298. case IDC_FCUS_ICON_HOVER:
  299. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
  300. break;
  301. case IDC_FCUS_RESTORE_DEFAULTS:
  302. //Set the "factory settings" as the default.
  303. // Don't set the default web view option if web view is disabled via system policy.
  304. if (0 == SHRestricted(REST_NOWEBVIEW))
  305. {
  306. CheckRBtnAndSetIcon(hDlg, IDC_FCUS_WHENEVER_POSSIBLE, IDC_FCUS_WHEN_CHOOSE, IDC_FCUS_WHENEVER_POSSIBLE, pfod, TRUE);
  307. }
  308. CheckRBtnAndSetIcon(hDlg, IDC_FCUS_SAME_WINDOW, IDC_FCUS_SEPARATE_WINDOWS, IDC_FCUS_SAME_WINDOW, pfod, TRUE);
  309. CheckRBtnAndSetIcon(hDlg, IDC_FCUS_SINGLECLICK, IDC_FCUS_DOUBLECLICK, IDC_FCUS_DOUBLECLICK, pfod, TRUE);
  310. CheckRadioButton(hDlg, IDC_FCUS_ICON_IE, IDC_FCUS_ICON_HOVER, IDC_FCUS_ICON_IE);
  311. EnableWindow(GetDlgItem(hDlg, IDC_FCUS_ICON_IE), FALSE); //Disable
  312. EnableWindow(GetDlgItem(hDlg, IDC_FCUS_ICON_HOVER), FALSE); //Disable
  313. //Enable the "Apply" button because changes have happened.
  314. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0);
  315. break;
  316. }
  317. break;
  318. case WM_DESTROY:
  319. if (pfod)
  320. {
  321. //Cleanup the Icons array!
  322. for (i = 0; i < ARRAYSIZE(pfod->ahIcon); i++)
  323. {
  324. if (pfod->ahIcon[i])
  325. DestroyIcon(pfod->ahIcon[i]);
  326. }
  327. SetWindowLongPtr(hDlg, DWLP_USER, 0);
  328. LocalFree((HANDLE)pfod);
  329. }
  330. break;
  331. }
  332. return FALSE;
  333. }
  334. // Moved from defview.cpp, which never used these functions
  335. const TCHAR c_szExploreClass[] = TEXT("ExploreWClass");
  336. const TCHAR c_szIExploreClass[] = TEXT("IEFrame");
  337. const TCHAR c_szCabinetClass[] = TEXT("CabinetWClass");
  338. BOOL IsNamedWindow(HWND hwnd, LPCTSTR pszClass)
  339. {
  340. TCHAR szClass[32];
  341. GetClassName(hwnd, szClass, ARRAYSIZE(szClass));
  342. return lstrcmp(szClass, pszClass) == 0;
  343. }
  344. BOOL IsExplorerWindow(HWND hwnd)
  345. {
  346. return IsNamedWindow(hwnd, c_szExploreClass);
  347. }
  348. BOOL IsTrayWindow(HWND hwnd)
  349. {
  350. return IsNamedWindow(hwnd, TEXT(WNDCLASS_TRAYNOTIFY));
  351. }
  352. BOOL IsFolderWindow(HWND hwnd)
  353. {
  354. TCHAR szClass[32];
  355. GetClassName(hwnd, szClass, ARRAYSIZE(szClass));
  356. return (lstrcmp(szClass, c_szCabinetClass) == 0) || (lstrcmp(szClass, c_szIExploreClass) == 0);
  357. }
  358. BOOL CALLBACK Cabinet_GlobalStateEnum(HWND hwnd, LPARAM lParam)
  359. {
  360. if (IsFolderWindow(hwnd) || IsExplorerWindow(hwnd))
  361. {
  362. PostMessage(hwnd, CWM_GLOBALSTATECHANGE, 0, 0);
  363. }
  364. return TRUE;
  365. }
  366. void Cabinet_StateChanged(CABINETSTATE *pcs)
  367. {
  368. // Save the new settings away...
  369. WriteCabinetState(pcs);
  370. EnumWindows(Cabinet_GlobalStateEnum, 0);
  371. }
  372. HWND CreateGlobalFolderOptionsStubWindow(void)
  373. {
  374. WNDCLASS wc = {0};
  375. wc.lpfnWndProc = DefWindowProc;
  376. wc.hInstance = HINST_THISDLL;
  377. wc.hIcon = LoadIcon(HINST_THISDLL, MAKEINTRESOURCE(IDI_FOLDEROPTIONS));
  378. wc.lpszClassName = SZ_FOLDEROPTSTUBCLASS;
  379. RegisterClass(&wc);
  380. DWORD dwExStyle = WS_EX_TOOLWINDOW;
  381. if (IS_BIDI_LOCALIZED_SYSTEM())
  382. {
  383. dwExStyle |= dwExStyleRTLMirrorWnd;
  384. }
  385. return CreateWindowEx(dwExStyle, SZ_FOLDEROPTSTUBCLASS, c_szNULL, WS_OVERLAPPED, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, NULL, NULL, HINST_THISDLL, NULL);
  386. }
  387. BOOL CALLBACK AddPropSheetPage(HPROPSHEETPAGE hpage, LPARAM lParam)
  388. {
  389. PROPSHEETHEADER * ppsh = (PROPSHEETHEADER *)lParam;
  390. if (ppsh->nPages < MAXPROPPAGES)
  391. {
  392. ppsh->phpage[ppsh->nPages++] = hpage;
  393. return TRUE;
  394. }
  395. return FALSE;
  396. }
  397. void AddPropSheetCLSID(REFCLSID clsid, PROPSHEETHEADER *ppsh)
  398. {
  399. IShellPropSheetExt *psx;
  400. HRESULT hres = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IShellPropSheetExt, &psx));
  401. if (SUCCEEDED(hres))
  402. {
  403. psx->AddPages(AddPropSheetPage, (LPARAM)ppsh);
  404. psx->Release();
  405. }
  406. }
  407. DWORD CALLBACK GlobalFolderOptPropSheetThreadProc(void *)
  408. {
  409. HWND hwndStub = CreateGlobalFolderOptionsStubWindow();
  410. if (!SHRestricted(REST_NOFOLDEROPTIONS))
  411. {
  412. PROPSHEETHEADER psh = {0};
  413. HPROPSHEETPAGE rPages[MAXPROPPAGES];
  414. psh.dwSize = sizeof(psh);
  415. psh.dwFlags = PSH_DEFAULT;
  416. psh.hInstance = HINST_THISDLL;
  417. psh.hwndParent = hwndStub;
  418. psh.pszCaption = MAKEINTRESOURCE(IDS_FOLDEROPT_TITLE);
  419. psh.phpage = rPages;
  420. AddPropSheetCLSID(CLSID_ShellFldSetExt, &psh);
  421. AddPropSheetCLSID(CLSID_FileTypes, &psh);
  422. AddPropSheetCLSID(CLSID_OfflineFilesOptions, &psh);
  423. // Display the property sheet.
  424. PropertySheet(&psh);
  425. }
  426. else
  427. {
  428. SHRestrictedMessageBox(hwndStub);
  429. }
  430. // Clean up stub window.
  431. DestroyWindow(hwndStub);
  432. return 0;
  433. }
  434. BOOL CALLBACK FindFolderOptionsEnumProc(HWND hwnd, LPARAM lParam)
  435. {
  436. BOOL fRet = TRUE;
  437. HWND *phwnd = (HWND *)lParam;
  438. TCHAR szClass[MAX_PATH];
  439. GetClassName(hwnd, szClass, ARRAYSIZE(szClass));
  440. if (lstrcmp(szClass, SZ_FOLDEROPTSTUBCLASS) == 0)
  441. {
  442. *phwnd = hwnd;
  443. fRet = FALSE;
  444. }
  445. return fRet;
  446. }
  447. void DoGlobalFolderOptions(void)
  448. {
  449. HWND hwnd = NULL;
  450. EnumWindows(FindFolderOptionsEnumProc, (LPARAM)&hwnd);
  451. if (hwnd)
  452. {
  453. hwnd = GetLastActivePopup(hwnd);
  454. if (hwnd && IsWindow(hwnd))
  455. {
  456. SetForegroundWindow(hwnd);
  457. }
  458. }
  459. else
  460. {
  461. SHCreateThread(GlobalFolderOptPropSheetThreadProc, NULL, CTF_COINIT, NULL);
  462. }
  463. }
  464. // Public entry point for asking Explorer to launch Options stuff
  465. STDAPI_(void) Options_RunDLLA(HWND hwndStub, HINSTANCE hAppInstance, LPSTR pszCmdLine, int nCmdShow)
  466. {
  467. PostMessage(GetShellWindow(), CWM_SHOWFOLDEROPT, StrToIntA(pszCmdLine), (LPARAM)0);
  468. }
  469. STDAPI_(void) Options_RunDLLW(HWND hwndStub, HINSTANCE hAppInstance, LPWSTR pszCmdLine, int nCmdShow)
  470. {
  471. PostMessage(GetShellWindow(), CWM_SHOWFOLDEROPT, StrToIntW(pszCmdLine), (LPARAM)0);
  472. }