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.

674 lines
18 KiB

  1. /*
  2. * general - Dialog box property sheet for "general ui tweaks"
  3. */
  4. #include "tweakui.h"
  5. #pragma BEGIN_CONST_DATA
  6. KL const c_klSmooth = { &c_hkCU, c_tszRegPathDesktop, c_tszSmoothScroll };
  7. KL const c_klEngine = { &g_hkCUSMIE, c_tszSearchUrl, 0 };
  8. KL const c_klPaintVersion =
  9. { &c_hkCU, c_tszRegPathDesktop, c_tszPaintDesktop };
  10. /* SOMEDAY
  11. Software\Microsoft\Internet Explorer\RestrictUI::Toolbar, ::History
  12. IE\Toolbar\::BackBitmap
  13. */
  14. const static DWORD CODESEG rgdwHelp[] = {
  15. IDC_EFFECTGROUP, IDH_GROUP,
  16. // IDC_ANIMATE, IDH_ANIMATE,
  17. // IDC_SMOOTHSCROLL, IDH_SMOOTHSCROLL,
  18. // IDC_BEEP, IDH_BEEP,
  19. IDC_IE3GROUP, IDH_GROUP,
  20. IDC_IE3TXT, IDH_IE3ENGINE,
  21. IDC_IE3ENGINETXT, IDH_IE3ENGINE,
  22. IDC_IE3ENGINE, IDH_IE3ENGINE,
  23. IDC_RUDEGROUP, IDH_GROUP,
  24. IDC_RUDE, IDH_RUDEAPP,
  25. IDC_RUDEFLASHINFINITE, IDH_RUDEAPPFLASH,
  26. IDC_RUDEFLASHFINITE, IDH_RUDEAPPFLASH,
  27. IDC_RUDEFLASHCOUNT, IDH_RUDEAPPFLASH,
  28. IDC_RUDEFLASHUD, IDH_RUDEAPPFLASH,
  29. IDC_RUDEFLASHTXT, IDH_RUDEAPPFLASH,
  30. 0, 0,
  31. };
  32. #pragma END_CONST_DATA
  33. /*
  34. * Instanced. We're a cpl so have only one instance, but I declare
  35. * all the instance stuff in one place so it's easy to convert this
  36. * code to multiple-instance if ever we need to.
  37. */
  38. typedef struct GDII { /* general_dialog instance info */
  39. DWORD dwForegroundLock; /* Original foreground lock */
  40. TCHAR tszUrl[1024]; /* Search URL */
  41. } GDII, *PGDII;
  42. GDII gdii;
  43. #define pgdii (&gdii)
  44. #define DestroyCursor(hcur) SafeDestroyIcon((HICON)(hcur))
  45. /*****************************************************************************
  46. *
  47. * General_GetAni
  48. *
  49. * Determine whether minimize animations are enabled.
  50. *
  51. * Always returns exactly 0 or 1.
  52. *
  53. *****************************************************************************/
  54. BOOL PASCAL
  55. General_GetAni(LPARAM lParam, LPVOID pvRef)
  56. {
  57. ANIMATIONINFO anii;
  58. anii.cbSize = sizeof(anii);
  59. SystemParametersInfo(SPI_GETANIMATION, sizeof(anii), &anii, 0);
  60. return anii.iMinAnimate != 0;
  61. }
  62. /*****************************************************************************
  63. *
  64. * General_SetAni
  65. *
  66. * Set the new animation flag.
  67. *
  68. *****************************************************************************/
  69. BOOL PASCAL
  70. General_SetAni(BOOL f, LPARAM lParam, LPVOID pvRef)
  71. {
  72. BOOL fRc;
  73. ANIMATIONINFO anii;
  74. anii.cbSize = sizeof(anii);
  75. anii.iMinAnimate = f;
  76. fRc = SystemParametersInfo(SPI_SETANIMATION, sizeof(anii), &anii,
  77. SPIF_UPDATEINIFILE);
  78. if (fRc && pvRef) {
  79. LPBOOL pf = (LPBOOL)pvRef;
  80. *pf = TRUE;
  81. }
  82. return fRc;
  83. }
  84. /*****************************************************************************
  85. *
  86. * General_GetSmooth
  87. *
  88. * Determine whether smooth scrolling is enabled.
  89. *
  90. * Always returns exactly 0 or 1.
  91. *
  92. *****************************************************************************/
  93. BOOL PASCAL
  94. General_GetSmooth(LPARAM lParam, LPVOID pvRef)
  95. {
  96. if (g_fSmoothScroll) {
  97. return GetDwordPkl(&c_klSmooth, 1) != 0;
  98. } else {
  99. return -1;
  100. }
  101. }
  102. /*****************************************************************************
  103. *
  104. * General_SetSmooth
  105. *
  106. * Set the new smooth-scroll flag.
  107. *
  108. *****************************************************************************/
  109. BOOL PASCAL
  110. General_SetSmooth(BOOL f, LPARAM lParam, LPVOID pvRef)
  111. {
  112. BOOL fRc = SetDwordPkl(&c_klSmooth, f);
  113. if (fRc && pvRef) {
  114. LPBOOL pf = (LPBOOL)pvRef;
  115. *pf = TRUE;
  116. }
  117. return fRc;
  118. }
  119. /*****************************************************************************
  120. *
  121. * General_GetPntVer
  122. *
  123. * Determine whether we should paint the version on the desktop.
  124. *
  125. * Always returns exactly 0 or 1.
  126. *
  127. *****************************************************************************/
  128. BOOL PASCAL
  129. General_GetPntVer(LPARAM lParam, LPVOID pvRef)
  130. {
  131. if (g_fMemphis) {
  132. return GetIntPkl(0, &c_klPaintVersion) != 0;
  133. } else if (g_fNT5) {
  134. return GetDwordPkl(&c_klPaintVersion, 0) != 0;
  135. } else {
  136. return -1;
  137. }
  138. }
  139. /*****************************************************************************
  140. *
  141. * General_SetPntVer
  142. *
  143. * Set the PaintVersion flag.
  144. *
  145. *****************************************************************************/
  146. BOOL PASCAL
  147. General_SetPntVer(BOOL f, LPARAM lParam, LPVOID pvRef)
  148. {
  149. BOOL fRc = FALSE;
  150. if (g_fMemphis) {
  151. fRc = SetIntPkl(f, &c_klPaintVersion);
  152. } else if (g_fNT5) {
  153. fRc = SetDwordPkl2(&c_klPaintVersion, f);
  154. }
  155. if (fRc && pvRef) {
  156. LPBOOL pf = (LPBOOL)pvRef;
  157. *pf = TRUE;
  158. }
  159. return fRc;
  160. }
  161. /*****************************************************************************
  162. *
  163. * General_GetSpi
  164. *
  165. * Return the setting of an SPI.
  166. *
  167. *****************************************************************************/
  168. BOOL PASCAL
  169. General_GetSpi(LPARAM lParam, LPVOID pvRef)
  170. {
  171. BOOL f;
  172. if (SystemParametersInfo((UINT)lParam, 0, &f, 0)) {
  173. return f;
  174. } else {
  175. return -1;
  176. }
  177. }
  178. /*****************************************************************************
  179. *
  180. * General_SetSpiW
  181. *
  182. * Set the SPI value in the wParam. Only SPI_SETBEEP needs this.
  183. *
  184. *****************************************************************************/
  185. BOOL
  186. General_SetSpiW(BOOL f, LPARAM lParam, LPVOID pvRef)
  187. {
  188. return SystemParametersInfo((UINT)(lParam+1), f, NULL, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
  189. }
  190. /*****************************************************************************
  191. *
  192. * General_SetSpi
  193. *
  194. * Set the SPI value in the lParam.
  195. *
  196. *****************************************************************************/
  197. BOOL
  198. General_SetSpi(BOOL f, LPARAM lParam, LPVOID pvRef)
  199. {
  200. return SystemParametersInfo((UINT)(lParam+1), 0, IntToPtr(f), SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
  201. }
  202. #pragma BEGIN_CONST_DATA
  203. /*
  204. * Note that this needs to be in sync with the IDS_GENERALEFFECTS
  205. * strings.
  206. *
  207. * Note that SPI_GETGRADIENTCAPTIONS is not needed, because the
  208. * standard Control Panel.Desktop.Appearance lets you munge the
  209. * gradient flag.
  210. *
  211. * SPI_SETACTIVEWINDOWTRACKING is handled over on the Mouse tab.
  212. */
  213. CHECKLISTITEM c_rgcliGeneral[] = {
  214. { General_GetAni, General_SetAni, 0, },
  215. { General_GetSmooth, General_SetSmooth, 0, },
  216. { General_GetSpi, General_SetSpiW, SPI_GETBEEP },
  217. { General_GetSpi, General_SetSpi, SPI_GETMENUANIMATION },
  218. { General_GetSpi, General_SetSpi, SPI_GETCOMBOBOXANIMATION },
  219. { General_GetSpi, General_SetSpi, SPI_GETLISTBOXSMOOTHSCROLLING },
  220. { General_GetSpi, General_SetSpi, SPI_GETKEYBOARDCUES },
  221. { General_GetSpi, General_SetSpi, SPI_GETHOTTRACKING },
  222. { General_GetSpi, General_SetSpi, SPI_GETMENUFADE },
  223. { General_GetSpi, General_SetSpi, SPI_GETSELECTIONFADE },
  224. { General_GetSpi, General_SetSpi, SPI_GETTOOLTIPANIMATION },
  225. { General_GetSpi, General_SetSpi, SPI_GETTOOLTIPFADE },
  226. { General_GetSpi, General_SetSpi, SPI_GETCURSORSHADOW },
  227. { General_GetPntVer, General_SetPntVer, 0, },
  228. };
  229. #pragma END_CONST_DATA
  230. /*****************************************************************************
  231. *
  232. * General_SetDirty
  233. *
  234. * Make a control dirty.
  235. *
  236. *****************************************************************************/
  237. void INLINE
  238. General_SetDirty(HWND hdlg)
  239. {
  240. Common_SetDirty(hdlg);
  241. }
  242. /*****************************************************************************
  243. *
  244. * General_Engine_OnEditChange
  245. *
  246. * Enable the OK button if the URL contains exactly one %s.
  247. *
  248. *****************************************************************************/
  249. void PASCAL
  250. General_Engine_OnEditChange(HWND hdlg)
  251. {
  252. TCHAR tszUrl[cA(pgdii->tszUrl)];
  253. PTSTR ptsz;
  254. int cPercentS;
  255. GetDlgItemText(hdlg, IDC_SEARCHURL, tszUrl, cA(tszUrl));
  256. /*
  257. * All appearances of "%" must be followed by "%" or "s".
  258. */
  259. cPercentS = 0;
  260. ptsz = tszUrl;
  261. while ((ptsz = ptszStrChr(ptsz, TEXT('%'))) != 0) {
  262. if (ptsz[1] == TEXT('%')) {
  263. ptsz += 2;
  264. } else if (ptsz[1] == TEXT('s')) {
  265. cPercentS++;
  266. ptsz += 2;
  267. } else {
  268. cPercentS = 0; break; /* Percent-mumble */
  269. }
  270. }
  271. EnableWindow(GetDlgItem(hdlg, IDOK), cPercentS == 1);
  272. }
  273. /*****************************************************************************
  274. *
  275. * General_Engine_OnOk
  276. *
  277. * Save the answer.
  278. *
  279. *****************************************************************************/
  280. void INLINE
  281. General_Engine_OnOk(HWND hdlg)
  282. {
  283. GetDlgItemText(hdlg, IDC_SEARCHURL, pgdii->tszUrl, cA(pgdii->tszUrl));
  284. }
  285. /*****************************************************************************
  286. *
  287. * General_Engine_OnCommand
  288. *
  289. * If the edit control changed, update the OK button.
  290. *
  291. *****************************************************************************/
  292. void PASCAL
  293. General_Engine_OnCommand(HWND hdlg, int id, UINT codeNotify)
  294. {
  295. switch (id) {
  296. case IDCANCEL:
  297. EndDialog(hdlg, 0); break;
  298. case IDOK:
  299. General_Engine_OnOk(hdlg);
  300. EndDialog(hdlg, 1);
  301. break;
  302. case IDC_SEARCHURL:
  303. if (codeNotify == EN_CHANGE) General_Engine_OnEditChange(hdlg);
  304. break;
  305. }
  306. }
  307. /*****************************************************************************
  308. *
  309. * General_Engine_OnInitDialog
  310. *
  311. * Shove the current engine URL in so the user can edit it.
  312. *
  313. *****************************************************************************/
  314. void PASCAL
  315. General_Engine_OnInitDialog(HWND hdlg)
  316. {
  317. SetDlgItemTextLimit(hdlg, IDC_SEARCHURL, pgdii->tszUrl, cA(pgdii->tszUrl));
  318. General_Engine_OnEditChange(hdlg);
  319. }
  320. /*****************************************************************************
  321. *
  322. * General_Engine_DlgProc
  323. *
  324. * Dialog procedure.
  325. *
  326. *****************************************************************************/
  327. INT_PTR EXPORT
  328. General_Engine_DlgProc(HWND hdlg, UINT wm, WPARAM wParam, LPARAM lParam)
  329. {
  330. switch (wm) {
  331. case WM_INITDIALOG: General_Engine_OnInitDialog(hdlg); break;
  332. case WM_COMMAND:
  333. General_Engine_OnCommand(hdlg,
  334. (int)GET_WM_COMMAND_ID(wParam, lParam),
  335. (UINT)GET_WM_COMMAND_CMD(wParam, lParam));
  336. break;
  337. default: return 0; /* Unhandled */
  338. }
  339. return 1; /* Handled */
  340. }
  341. /*****************************************************************************
  342. *
  343. * General_UpdateEngine
  344. *
  345. * If the person selected "Custom", then pop up the customize dialog.
  346. *
  347. * At any rate, put the matching URL into pgdii->tszUrl.
  348. *
  349. *****************************************************************************/
  350. void PASCAL
  351. General_UpdateEngine(HWND hdlg)
  352. {
  353. int ieng = (int)Misc_Combo_GetCurItemData(GetDlgItem(hdlg, IDC_IE3ENGINE));
  354. if (ieng == 0) {
  355. if (DialogBox(hinstCur, MAKEINTRESOURCE(IDD_SEARCHURL), hdlg,
  356. General_Engine_DlgProc)) {
  357. } else {
  358. goto skip;
  359. }
  360. } else {
  361. LoadString(hinstCur, IDS_URL+ieng, pgdii->tszUrl, cA(pgdii->tszUrl));
  362. }
  363. General_SetDirty(hdlg);
  364. skip:;
  365. }
  366. /*****************************************************************************
  367. *
  368. * General_Reset
  369. *
  370. * Reset all controls to initial values. This also marks
  371. * the control as clean.
  372. *
  373. * Note: This doesn't really work any more.
  374. *
  375. *****************************************************************************/
  376. BOOL PASCAL
  377. General_Reset(HWND hdlg)
  378. {
  379. HWND hwnd;
  380. UINT i;
  381. TCHAR tsz[256];
  382. GetStrPkl(pgdii->tszUrl, cbX(pgdii->tszUrl), &c_klEngine);
  383. if (pgdii->tszUrl[0] && !g_fIE5) {
  384. hwnd = GetDlgItem(hdlg, IDC_IE3ENGINE);
  385. ComboBox_ResetContent(hwnd);
  386. for (i = 0; LoadString(hinstCur, IDS_ENGINE+i, tsz, cA(tsz)); i++) {
  387. int iItem = ComboBox_AddString(hwnd, tsz);
  388. ComboBox_SetItemData(hwnd, iItem, i);
  389. if (i) LoadString(hinstCur, IDS_URL+i, tsz, cA(tsz));
  390. if (i == 0 || lstrcmpi(tsz, pgdii->tszUrl) == 0) {
  391. ComboBox_SetCurSel(hwnd, iItem);
  392. }
  393. }
  394. } else {
  395. AdjustDlgItems(hdlg, IDC_IE3FIRST, IDC_IE3LAST, ADI_DISABLE | ADI_HIDE);
  396. MoveDlgItems(hdlg, IDC_IE3GROUP, IDC_RUDEFIRST, IDC_RUDELAST);
  397. }
  398. DWORD dw;
  399. if (SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &dw, 0)) {
  400. if (dw) {
  401. pgdii->dwForegroundLock = dw;
  402. } else {
  403. /* Default foreground lock timeout differs based on platform */
  404. pgdii->dwForegroundLock = g_fNT ? 200000 : 15000;
  405. }
  406. CheckDlgButton(hdlg, IDC_RUDE, dw != 0);
  407. if (SystemParametersInfo(SPI_GETFOREGROUNDFLASHCOUNT, 0, &dw, 0)) {
  408. if (dw) {
  409. CheckDlgButton(hdlg, IDC_RUDEFLASHFINITE, TRUE);
  410. SetDlgItemInt(hdlg, IDC_RUDEFLASHCOUNT, dw, 0);
  411. } else {
  412. /* WindMill and NT default to 3 */
  413. CheckDlgButton(hdlg, IDC_RUDEFLASHINFINITE, TRUE);
  414. SetDlgItemInt(hdlg, IDC_RUDEFLASHCOUNT, 3, 0);
  415. }
  416. } else {
  417. /* Win98 had the flash count hard-coded to 2 */
  418. SetDlgItemInt(hdlg, IDC_RUDEFLASHCOUNT, 2, 0);
  419. EnableDlgItems(hdlg, IDC_RUDEFLASHFIRST, IDC_RUDEFLASHLAST, FALSE);
  420. }
  421. } else {
  422. AdjustDlgItems(hdlg, IDC_RUDEFIRST, IDC_RUDELAST, ADI_DISABLE | ADI_HIDE);
  423. }
  424. Common_SetClean(hdlg);
  425. return 1;
  426. }
  427. /*****************************************************************************
  428. *
  429. * General_Apply
  430. *
  431. * Write the changes to the registry.
  432. *
  433. *****************************************************************************/
  434. void NEAR PASCAL
  435. General_OnApply(HWND hdlg)
  436. {
  437. BOOL fSendWinIniChange = 0;
  438. int i;
  439. Checklist_OnApply(hdlg, c_rgcliGeneral, &fSendWinIniChange, FALSE);
  440. if (fSendWinIniChange) {
  441. SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
  442. (LPARAM)(LPCTSTR)c_tszWindows);
  443. }
  444. if (pgdii->tszUrl[0]) {
  445. SetStrPkl(&c_klEngine, pgdii->tszUrl);
  446. }
  447. BOOL f = IsDlgButtonChecked(hdlg, IDC_RUDE);
  448. if (SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,
  449. IntToPtr(f ? pgdii->dwForegroundLock : 0),
  450. SPIF_UPDATEINIFILE | SPIF_SENDCHANGE)) {
  451. int cFlash;
  452. if (IsDlgButtonChecked(hdlg, IDC_RUDEFLASHINFINITE)) {
  453. cFlash = 0; f = TRUE;
  454. } else {
  455. cFlash = (int)GetDlgItemInt(hdlg, IDC_RUDEFLASHCOUNT, &f, FALSE);
  456. }
  457. if (f && SystemParametersInfo(SPI_SETFOREGROUNDFLASHCOUNT, 0, IntToPtr(cFlash),
  458. SPIF_UPDATEINIFILE | SPIF_SENDCHANGE)) {
  459. /* Happy joy */
  460. }
  461. }
  462. General_Reset(hdlg);
  463. }
  464. /*****************************************************************************
  465. *
  466. * General_OnCommand
  467. *
  468. * Ooh, we got a command.
  469. *
  470. *****************************************************************************/
  471. void PASCAL
  472. General_OnCommand(HWND hdlg, int id, UINT codeNotify)
  473. {
  474. switch (id) {
  475. case IDC_ANIMATE:
  476. case IDC_SMOOTHSCROLL:
  477. case IDC_BEEP:
  478. case IDC_RUDE:
  479. case IDC_RUDEFLASHINFINITE:
  480. case IDC_RUDEFLASHFINITE:
  481. if (codeNotify == BN_CLICKED) General_SetDirty(hdlg);
  482. break;
  483. case IDC_IE3ENGINE:
  484. if (codeNotify == CBN_SELCHANGE) General_UpdateEngine(hdlg);
  485. break;
  486. case IDC_RUDEFLASHCOUNT:
  487. if (codeNotify == EN_CHANGE) {
  488. General_SetDirty(hdlg);
  489. }
  490. break;
  491. }
  492. }
  493. #if 0
  494. /*****************************************************************************
  495. *
  496. * General_OnNotify
  497. *
  498. * Ooh, we got a notification.
  499. *
  500. *****************************************************************************/
  501. BOOL PASCAL
  502. General_OnNotify(HWND hdlg, NMHDR FAR *pnm)
  503. {
  504. switch (pnm->code) {
  505. case PSN_APPLY:
  506. General_Apply(hdlg);
  507. break;
  508. }
  509. return 0;
  510. }
  511. #endif
  512. /*****************************************************************************
  513. *
  514. * General_OnInitDialog
  515. *
  516. * Initialize the controls.
  517. *
  518. *****************************************************************************/
  519. BOOL NEAR PASCAL
  520. General_OnInitDialog(HWND hwnd)
  521. {
  522. HWND hdlg = GetParent(hwnd);
  523. ZeroMemory(pgdii, cbX(*pgdii));
  524. Checklist_OnInitDialog(hwnd, c_rgcliGeneral, cA(c_rgcliGeneral),
  525. IDS_GENERALEFFECTS, 0);
  526. SendDlgItemMessage(hdlg, IDC_RUDEFLASHUD,
  527. UDM_SETRANGE, 0, MAKELPARAM(999, 1));
  528. General_Reset(hdlg);
  529. return 1;
  530. }
  531. /*****************************************************************************
  532. *
  533. * General_OnWhatsThis
  534. *
  535. *****************************************************************************/
  536. void PASCAL
  537. General_OnWhatsThis(HWND hwnd, int iItem)
  538. {
  539. LV_ITEM lvi;
  540. Misc_LV_GetItemInfo(hwnd, &lvi, iItem, LVIF_PARAM);
  541. WinHelp(hwnd, c_tszMyHelp, HELP_CONTEXTPOPUP,
  542. IDH_ANIMATE + lvi.lParam);
  543. }
  544. /*****************************************************************************
  545. *
  546. * Oh yeah, we need this too.
  547. *
  548. *****************************************************************************/
  549. #pragma BEGIN_CONST_DATA
  550. LVCI lvciGeneral[] = {
  551. { IDC_WHATSTHIS, General_OnWhatsThis },
  552. { 0, 0 },
  553. };
  554. LVV lvvGeneral = {
  555. General_OnCommand,
  556. 0, /* General_OnInitContextMenu */
  557. 0, /* General_Dirtify */
  558. 0, /* General_GetIcon */
  559. General_OnInitDialog,
  560. General_OnApply,
  561. 0, /* General_OnDestroy */
  562. 0, /* General_OnSelChange */
  563. 6, /* iMenu */
  564. rgdwHelp,
  565. 0, /* Double-click action */
  566. lvvflCanCheck, /* We need check boxes */
  567. lvciGeneral,
  568. };
  569. #pragma END_CONST_DATA
  570. /*****************************************************************************
  571. *
  572. * Our window procedure.
  573. *
  574. *****************************************************************************/
  575. INT_PTR EXPORT
  576. General_DlgProc(HWND hdlg, UINT wm, WPARAM wParam, LPARAM lParam)
  577. {
  578. return LV_DlgProc(&lvvGeneral, hdlg, wm, wParam, lParam);
  579. }