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.

830 lines
26 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: sethc.c
  3. *
  4. * Copyright (c) 1997, Microsoft Corporation
  5. *
  6. * SetHC -- exe to set or clear high contrast state.
  7. *
  8. * History:
  9. * 02-01-97 Fritz Sands Created
  10. * Bug fixes : a-anilk June 99
  11. \***************************************************************************/
  12. /***************************************************************************
  13. * Use the following define if for some reason we have to go back to using
  14. * a message loop to let shell have time to update the UI
  15. *
  16. #define NEED_MSG_PUMP
  17. **************************************************************************/
  18. #ifndef RC_INVOKED
  19. #include <nt.h>
  20. #include <ntrtl.h>
  21. #include <nturtl.h>
  22. #endif
  23. #include <windows.h>
  24. #include <winuserp.h>
  25. #include <cpl.h>
  26. #include <stdarg.h>
  27. #include <stdlib.h>
  28. #include <WININET.H>
  29. #include <shlobj.h>
  30. #include <objbase.h>
  31. #include <shlguid.h>
  32. #include <uxthemep.h>
  33. #include "access.h"
  34. #pragma hdrstop
  35. HINSTANCE g_hInstance;
  36. #ifdef DBG
  37. #define DBPRINTF MyOutputDebugString
  38. void MyOutputDebugString( LPCTSTR lpOutputString, ...);
  39. #else
  40. #define DBPRINTF 1 ? (void)0 : (void)
  41. #endif
  42. /*
  43. * High Contrast Stuff
  44. */
  45. #define HC_KEY TEXT("Control Panel\\Accessibility\\HighContrast")
  46. #define HIGHCONTRASTSCHEME TEXT("High Contrast Scheme")
  47. #define REGSTR_VAL_FLAGS TEXT("Flags")
  48. #define REGSTR_PATH_APPEARANCE TEXT("Control Panel\\Appearance")
  49. #define REGSTR_PATH_LOOKSCHEMES TEXT("Control Panel\\Appearance\\Schemes")
  50. #define APPEARANCESCHEME REGSTR_PATH_LOOKSCHEMES
  51. #define DEFSCHEMEKEY REGSTR_PATH_APPEARANCE
  52. #define DEFSCHEMENAME TEXT("Current")
  53. #define WHITEBLACK_HC TEXT("High Contrast Black (large)")
  54. #define CURHCSCHEME TEXT("Volatile HC Scheme")
  55. // the extension for an appearance filename
  56. #define THEME_EXT L".msstyles"
  57. // the following is a Windows Classic color scheme or a THEME_EXT file name
  58. #define PRE_HC_SCHEME TEXT("Pre-High Contrast Scheme")
  59. // the following is the color scheme when pre-HC was a .mstheme
  60. #define PRE_HC_THM_COLOR TEXT("Pre-High Contrast Color")
  61. // the following is the font size when pre-HC was a .mstheme
  62. #define PRE_HC_THM_SIZE TEXT("Pre-High Contrast Size")
  63. // the following is the wallpaper for pre-HC
  64. #define PRE_HC_WALLPAPER TEXT("Pre-High Contrast Wallpaper")
  65. // increase this value so we can store a theme filename
  66. #ifdef MAX_SCHEME_NAME_SIZE
  67. #undef MAX_SCHEME_NAME_SIZE
  68. #endif
  69. #define MAX_SCHEME_NAME_SIZE 512
  70. #define ARRAYSIZE(x) sizeof(x)/sizeof(x[0])
  71. /*
  72. * Note -- this must match the desktop applet
  73. */
  74. #define SCHEME_VERSION 2 // Ver 2 == Unicode
  75. typedef struct {
  76. SHORT version;
  77. WORD wDummy; // for alignment
  78. NONCLIENTMETRICS ncm;
  79. LOGFONT lfIconTitle;
  80. COLORREF rgb[COLOR_MAX];
  81. } SCHEMEDATA;
  82. typedef DWORD (WINAPI* PFNDIALOGRTN)(BOOL);
  83. PFNDIALOGRTN g_aRtn[] = {
  84. NULL,
  85. StickyKeysNotification, //ACCESS_STICKYKEYS
  86. FilterKeysNotification, //ACCESS_FILTERKEYS
  87. ToggleKeysNotification, //ACCESS_TOGGLEKEYS
  88. MouseKeysNotification, //ACCESS_MOUSEKEYS
  89. HighContNotification, //ACCESS_HIGHCONTRAST
  90. };
  91. /***************************************************************************
  92. * GetRegValue
  93. *
  94. * Passed the key, and the identifier, return the string data from the
  95. * registry.
  96. ***************************************************************************/
  97. long GetRegValue(LPWSTR RegKey, LPWSTR RegEntry, LPWSTR RegVal, long Size)
  98. {
  99. HKEY hReg; // Registry handle for schemes
  100. DWORD Type; // Type of value
  101. long retval;
  102. DWORD ccbSize = Size;
  103. RegVal[0] = 0; // in case something fails always return null-terminated
  104. retval = RegCreateKey(HKEY_CURRENT_USER, RegKey, &hReg);
  105. if (retval != ERROR_SUCCESS)
  106. return retval;
  107. retval = RegQueryValueEx(hReg,
  108. RegEntry,
  109. NULL,
  110. (LPDWORD)&Type,
  111. (LPBYTE)RegVal,
  112. &ccbSize);
  113. // 'ccbSize' is in bytes
  114. if (retval == ERROR_SUCCESS && Type == REG_SZ && ccbSize > 0)
  115. {
  116. ccbSize /= 2;
  117. RegVal[ccbSize - 1] = 0; // ensure null-termination
  118. }
  119. else
  120. {
  121. RegVal[0] = 0; // if reg type is not string don't return anything
  122. }
  123. RegCloseKey(hReg);
  124. return retval;
  125. }
  126. /***************************************************************************
  127. * SetRegValue
  128. *
  129. * Passed the key, and the identifier, set the string data from the
  130. * registry.
  131. ***************************************************************************/
  132. long SetRegValue(LPTSTR RegKey, LPWSTR RegEntry, LPVOID RegVal, long Size, DWORD Type)
  133. {
  134. HKEY hReg; // Registry handle for schemes
  135. DWORD Reserved = 0;
  136. long retval;
  137. if (RegCreateKey(HKEY_CURRENT_USER,RegKey, &hReg) != ERROR_SUCCESS)
  138. return 0;
  139. // A common error is to omit the `+1', so we just smash the correct
  140. // value into place regardless.
  141. if (Type == REG_SZ)
  142. Size = (lstrlen(RegVal) + 1) * sizeof(WCHAR);
  143. retval = RegSetValueEx(hReg,
  144. RegEntry,
  145. 0,
  146. Type,
  147. RegVal,
  148. Size);
  149. RegCloseKey(hReg);
  150. return retval;
  151. }
  152. /***************************************************************************
  153. * SaveAndRemoveWallpaper
  154. *
  155. * Gets the current wallpaper setting from the system and saves it in the
  156. * accessibility registry entries. No error return as there isn't anything
  157. * we can do.
  158. *
  159. * ISSUE we aren't getting all the active desktop properties; just wallpaper.
  160. * This isn't a regression in that we didn't even restore wallpaper in W2K.
  161. *
  162. ***************************************************************************/
  163. void SaveAndRemoveWallpaper()
  164. {
  165. WCHAR szWallpaper[MAX_SCHEME_NAME_SIZE] = {0};
  166. IActiveDesktop *p;
  167. HRESULT hr;
  168. hr = CoCreateInstance(
  169. &CLSID_ActiveDesktop
  170. , NULL
  171. , CLSCTX_INPROC_SERVER
  172. , &IID_IActiveDesktop
  173. , (void **)&p);
  174. if (SUCCEEDED(hr))
  175. {
  176. hr = p->lpVtbl->GetWallpaper(p, szWallpaper, MAX_SCHEME_NAME_SIZE, 0);
  177. if (SUCCEEDED(hr))
  178. {
  179. // save the current wallpaper setting
  180. SetRegValue(HC_KEY, PRE_HC_WALLPAPER, szWallpaper, 0, REG_SZ);
  181. // now remove the wallpaper, if necessary
  182. if (szWallpaper[0])
  183. {
  184. szWallpaper[0] = 0;
  185. hr = p->lpVtbl->SetWallpaper(p, szWallpaper, 0);
  186. if (SUCCEEDED(hr))
  187. hr = p->lpVtbl->ApplyChanges(p, AD_APPLY_ALL);
  188. }
  189. }
  190. p->lpVtbl->Release(p);
  191. }
  192. }
  193. /***************************************************************************
  194. * RestoreWallpaper
  195. *
  196. * Restores the pre-high contrast wallpaper setting. Reads the setting
  197. * stored in the accessibility registry entries and restores the system
  198. * setting. No error return as there isn't anything we can do.
  199. *
  200. ***************************************************************************/
  201. void RestoreWallpaper()
  202. {
  203. long lRv;
  204. TCHAR szWallpaper[MAX_SCHEME_NAME_SIZE] = {0};
  205. lRv = GetRegValue(HC_KEY, PRE_HC_WALLPAPER, szWallpaper, sizeof(szWallpaper));
  206. if (lRv == ERROR_SUCCESS && szWallpaper[0])
  207. {
  208. IActiveDesktop *p;
  209. HRESULT hr;
  210. hr = CoCreateInstance(
  211. &CLSID_ActiveDesktop
  212. , NULL
  213. , CLSCTX_INPROC_SERVER
  214. , &IID_IActiveDesktop
  215. , (void **)&p);
  216. if (SUCCEEDED(hr))
  217. {
  218. hr = p->lpVtbl->SetWallpaper(p, szWallpaper, 0);
  219. if (SUCCEEDED(hr))
  220. hr = p->lpVtbl->ApplyChanges(p, AD_APPLY_ALL);
  221. p->lpVtbl->Release(p);
  222. }
  223. }
  224. }
  225. /***************************************************************************
  226. * AppearanceRestored
  227. *
  228. * lpszName [in] the name of a theme file (mstheme).
  229. *
  230. * Function returns TRUE if lpszName is a theme file and it was restored
  231. * otherwise it returns FALSE. May return TRUE if restoring the theme
  232. * fails (not much we can do if theme api's fail).
  233. *
  234. ***************************************************************************/
  235. BOOL AppearanceRestored(LPCWSTR lpszName)
  236. {
  237. HRESULT hr;
  238. DWORD dwThemeFlags;
  239. int cch = lstrlen(lpszName) - lstrlen(THEME_EXT);
  240. TCHAR szColor[MAX_SCHEME_NAME_SIZE] = {0};
  241. TCHAR szSize[MAX_SCHEME_NAME_SIZE] = {0};
  242. if (cch <= 0 || lstrcmpi(&lpszName[cch], THEME_EXT))
  243. {
  244. DBPRINTF(TEXT("AppearanceRestored: %s is not a theme file\r\n"), lpszName);
  245. return FALSE; // this isn't a theme file
  246. }
  247. // This is a theme file, get the color and size parts of the theme
  248. GetRegValue(HC_KEY, PRE_HC_THM_COLOR, szColor, sizeof(szColor));
  249. GetRegValue(HC_KEY, PRE_HC_THM_SIZE, szSize, sizeof(szSize));
  250. // Load the theme file, color and size then apply it
  251. dwThemeFlags = AT_LOAD_SYSMETRICS | AT_SYNC_LOADMETRICS;
  252. hr = SetSystemVisualStyle(lpszName, szColor, szSize, dwThemeFlags);
  253. DBPRINTF(TEXT("AppearanceRestored: SetSystemVisualStyle(%s, %s, %s, 0x%x) returned 0x%x\r\n"),
  254. lpszName, szColor, szSize, dwThemeFlags, hr);
  255. return TRUE;
  256. }
  257. /***************************************************************************
  258. * DelRegValue
  259. *
  260. * Passed the key and the subkey, delete the subkey.
  261. *
  262. ***************************************************************************/
  263. long DelRegValue(LPTSTR RegKey, LPTSTR RegEntry)
  264. {
  265. HKEY hReg; // Registry handle for schemes
  266. DWORD Reserved = 0;
  267. long retval;
  268. retval = RegCreateKey(HKEY_CURRENT_USER,RegKey, &hReg);
  269. if (retval != ERROR_SUCCESS)
  270. return retval;
  271. retval = RegDeleteValue(hReg, RegEntry);
  272. RegCloseKey(hReg);
  273. return retval;
  274. }
  275. #define COLOR_MAX_400 (COLOR_INFOBK + 1)
  276. void FAR SetMagicColors(HDC, DWORD, WORD);
  277. /***************************************************************************
  278. *
  279. *
  280. * SetCurrentSchemeName
  281. *
  282. * Input: szName -> name of scheme or theme to become current
  283. * Output: Boolean success/failure
  284. *
  285. ***************************************************************************/
  286. typedef LONG (CALLBACK *APPLETPROC)(HWND, UINT, LPARAM, LPARAM);
  287. typedef BOOL (CALLBACK *SETSCHEME)(LPCTSTR);
  288. typedef BOOL (CALLBACK *SETSCHEMEA)(LPCSTR);
  289. BOOL SetCurrentSchemeName(LPCWSTR lpszName, BOOL fNoReg)
  290. {
  291. BOOL fRc = FALSE;
  292. if (fNoReg)
  293. {
  294. // Setting a non-persistent scheme; we come to this code path for
  295. // both setting or unsetting HC via hot keys
  296. HKEY hkSchemes;
  297. // For Whistler, because it may confuse users, we are always turning off
  298. // theming and any wallpaper. Otherwise, sometimes they'll loose these
  299. // settings (when they log off and log back on) and sometimes they won't
  300. // (when they use the hot keys to turn HC off).
  301. DBPRINTF(TEXT("SetCurrentSchemeName: To %s w/o persisting to registry\r\n"), lpszName);
  302. if (IsThemeActive())
  303. {
  304. DBPRINTF(TEXT("SetCurrentSchemeName: Turning off active Themes\r\n"));
  305. ApplyTheme(NULL, 0, NULL);
  306. }
  307. if (RegOpenKey(HKEY_CURRENT_USER, REGSTR_PATH_LOOKSCHEMES, &hkSchemes) == ERROR_SUCCESS) {
  308. SCHEMEDATA sd;
  309. DWORD dwType, dwSize;
  310. BOOL b;
  311. HDC hdc;
  312. int iColors[COLOR_MAX];
  313. int i;
  314. COLORREF rgbColors[COLOR_MAX];
  315. dwType = REG_BINARY;
  316. dwSize = sizeof(sd);
  317. if (RegQueryValueEx(hkSchemes, lpszName, NULL, &dwType, (LPBYTE)&sd, &dwSize) == ERROR_SUCCESS && dwType == REG_BINARY)
  318. {
  319. int n;
  320. if (sd.version != SCHEME_VERSION) {
  321. RegCloseKey(hkSchemes);
  322. return FALSE;
  323. }
  324. n = (int)(dwSize - (sizeof(sd) - sizeof(sd.rgb))) / sizeof(COLORREF);
  325. sd.ncm.cbSize = sizeof(NONCLIENTMETRICS);
  326. b = SystemParametersInfo(SPI_SETNONCLIENTMETRICS, sizeof(sd.ncm),
  327. (void far *)&sd.ncm,
  328. 0);
  329. b = SystemParametersInfo(SPI_SETICONTITLELOGFONT, sizeof(LOGFONT),
  330. (void far *)(LPLOGFONT)&sd.lfIconTitle,
  331. 0);
  332. if (n == COLOR_MAX_400)
  333. {
  334. sd.rgb[COLOR_HOTLIGHT] = sd.rgb[COLOR_ACTIVECAPTION];
  335. sd.rgb[COLOR_GRADIENTACTIVECAPTION] = RGB(0,0,0);
  336. sd.rgb[COLOR_GRADIENTINACTIVECAPTION] = RGB(0,0,0);
  337. }
  338. #if(WINVER >= 0x0501)
  339. // new Whistler colors
  340. sd.rgb[COLOR_MENUBAR] = sd.rgb[COLOR_MENU];
  341. sd.rgb[COLOR_MENUHILIGHT] = sd.rgb[COLOR_HIGHLIGHT];
  342. // reset "flatmenu" and "dropshadows" settings
  343. SystemParametersInfo(SPI_SETFLATMENU, 0, IntToPtr(FALSE), SPIF_SENDCHANGE);
  344. SystemParametersInfo(SPI_SETDROPSHADOW, 0, IntToPtr(FALSE), SPIF_SENDCHANGE);
  345. #endif /* WINVER >= 0x0501 */
  346. //
  347. // restore magic colors back to Win31 defaults.
  348. //
  349. hdc = GetDC(NULL);
  350. SetMagicColors(hdc, 0x00c0dcc0, 8); // money green
  351. SetMagicColors(hdc, 0x00f0caa6, 9); // IBM blue
  352. SetMagicColors(hdc, 0x00f0fbff, 246); // off white
  353. ReleaseDC(NULL, hdc);
  354. for (i=0; i<COLOR_MAX; i++)
  355. {
  356. iColors[i] = i;
  357. rgbColors[i] = sd.rgb[i] & 0x00FFFFFF;
  358. }
  359. SetSysColors(COLOR_MAX, iColors, rgbColors);
  360. SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETNONCLIENTMETRICS, 0, SMTO_ABORTIFHUNG, 5000, NULL);
  361. }
  362. RegCloseKey(hkSchemes);
  363. fRc = TRUE;
  364. }
  365. } else
  366. {
  367. /*
  368. * We need to persist this setting. First see if lpszName is a
  369. * theme file and restore it if it is
  370. */
  371. fRc = AppearanceRestored(lpszName);
  372. if (!fRc)
  373. {
  374. /*
  375. * The user is in "Windows Classic" appearance so use desk CPL to restore
  376. */
  377. HINSTANCE hinst = LoadLibrary(TEXT("DESK.CPL"));
  378. if (NULL != hinst)
  379. {
  380. APPLETPROC ap = (APPLETPROC)GetProcAddress((HMODULE)hinst, "CPlApplet");
  381. if (ap)
  382. {
  383. if (ap(0, CPL_INIT, 0, 0))
  384. {
  385. SETSCHEME ss = (SETSCHEME)GetProcAddress(hinst, "DeskSetCurrentSchemeW");
  386. if (ss)
  387. {
  388. fRc = ss(lpszName);
  389. DBPRINTF(TEXT("SetCurrentSchemeName: DeskSetCurrentSchemeW(%s) returned %d\r\n"), lpszName, fRc);
  390. }
  391. ap(0, CPL_EXIT, 0, 0);
  392. }
  393. }
  394. FreeLibrary(hinst);
  395. }
  396. }
  397. }
  398. return fRc;
  399. }
  400. /***************************************************************************
  401. *
  402. * GetCurrentSchemeName
  403. *
  404. * szBuf [out] Buffer to receive name of scheme (MAXSCHEMENAME) or theme file
  405. * ctchBuf [in] Size of szBuf
  406. * szColor [out] If szBuf is a theme file, the color scheme name
  407. * ctchColor [in] Size of szColor
  408. * szSize [out] If szBuf is a theme file, the font size
  409. * ctchSize [in] Size of szSize
  410. *
  411. * Returns the name of the current scheme. This will be either the name
  412. * of a theme file (if Professional visual style is on) or the name of
  413. * a color scheme (if Windows Classic visual style is on). If the
  414. * current scheme does not have a name, create one (ID_PRE_HC_SCHEME).
  415. *
  416. * If anything goes wrong, there isn't much we can do.
  417. *
  418. ***************************************************************************/
  419. void GetCurrentSchemeName(LPTSTR szBuf, long ctchBuf, LPTSTR szColor, long ctchColor, LPTSTR szSize, long ctchSize)
  420. {
  421. HRESULT hr;
  422. // First try to get a theme filename
  423. hr = GetCurrentThemeName(szBuf, ctchBuf, szColor, ctchColor, szSize, ctchSize);
  424. if (FAILED(hr))
  425. {
  426. // User is in Windows Classic appearance (visual style)
  427. szColor[0] = 0;
  428. szSize[0] = 0;
  429. if (GetRegValue(DEFSCHEMEKEY, DEFSCHEMENAME, szBuf, ctchBuf * sizeof(TCHAR))
  430. != ERROR_SUCCESS)
  431. {
  432. SCHEMEDATA scm;
  433. int i;
  434. /* Load the current scheme into scm */
  435. scm.version = SCHEME_VERSION;
  436. scm.wDummy = 0;
  437. scm.ncm.cbSize = sizeof(NONCLIENTMETRICS);
  438. SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
  439. sizeof(NONCLIENTMETRICS),
  440. &scm.ncm,
  441. 0);
  442. SystemParametersInfo(SPI_GETICONTITLELOGFONT,
  443. sizeof(LOGFONT),
  444. &scm.lfIconTitle,
  445. 0);
  446. for (i = 0; i < COLOR_MAX; i++) {
  447. scm.rgb[i] = GetSysColor(i);
  448. }
  449. /* Now give it a name */
  450. SetRegValue(APPEARANCESCHEME, PRE_HC_SCHEME, &scm, sizeof(scm), REG_BINARY);
  451. /*
  452. * NOTE -- PRE_HC_SCHEME in APPEARANCESCHEME is actual scheme data, NOT a scheme
  453. * name, This data has info about settings if the user did not have a
  454. * desktop scheme in place before switching to high contrast mode.
  455. */
  456. wcscpy(szBuf, PRE_HC_SCHEME);
  457. }
  458. }
  459. }
  460. /***************************************************************************
  461. *
  462. *
  463. * SetHighContrast
  464. *
  465. * Input: None
  466. * Output: None
  467. *
  468. * Outline:
  469. *
  470. ***************************************************************************/
  471. int SetHighContrast(BOOL fEnabledOld, BOOL fNoReg)
  472. {
  473. BOOL fOk = 0;
  474. TCHAR szBuf[MAX_SCHEME_NAME_SIZE];
  475. TCHAR szColor[MAX_SCHEME_NAME_SIZE];
  476. TCHAR szSize[MAX_SCHEME_NAME_SIZE];
  477. HIGHCONTRAST hc;
  478. szBuf[0] = TEXT('\0');
  479. if (!fEnabledOld)
  480. {
  481. /*
  482. * Get the current scheme information (create it if necessary)
  483. * Note -- we need to put this in the registry, even in "no registry"
  484. * cases, so we can restore the values.
  485. */
  486. GetCurrentSchemeName(szBuf, MAX_SCHEME_NAME_SIZE, szColor, MAX_SCHEME_NAME_SIZE, szSize, MAX_SCHEME_NAME_SIZE);
  487. DBPRINTF(TEXT("SetHighContrast: Save to registry ThemeFile=%s Color=%s Size=%s\r\n"), szBuf, szColor, szSize);
  488. SetRegValue(HC_KEY, PRE_HC_SCHEME, szBuf, 0, REG_SZ); /* Save it */
  489. SetRegValue(HC_KEY, PRE_HC_THM_COLOR, szColor, 0, REG_SZ);
  490. SetRegValue(HC_KEY, PRE_HC_THM_SIZE, szSize, 0, REG_SZ);
  491. /*
  492. * NOTE -- PRE_HC_SCHEME in HC_KEY is the NAME of the scheme (which may be a made-up
  493. * name) holding the settings before High Contrast was invoked.
  494. */
  495. }
  496. hc.cbSize = sizeof(hc);
  497. SystemParametersInfo(SPI_GETHIGHCONTRAST, sizeof hc, &hc, 0);
  498. if ((NULL != hc.lpszDefaultScheme) && (TEXT('\0') != *(hc.lpszDefaultScheme)))
  499. {
  500. lstrcpy(szBuf, hc.lpszDefaultScheme);
  501. }
  502. else
  503. {
  504. /*
  505. * Get the name of the HC scheme. By design, we have to look
  506. * in about fifty places... We get the default one first, then try
  507. * to get better and better ones. That way, when we're done, we have
  508. * the best one that succeeded.
  509. */
  510. lstrcpy(szBuf, WHITEBLACK_HC);
  511. GetRegValue(HC_KEY, HIGHCONTRASTSCHEME, szBuf, sizeof(szBuf));
  512. GetRegValue(DEFSCHEMEKEY, CURHCSCHEME, szBuf, sizeof(szBuf));
  513. }
  514. fOk = SetCurrentSchemeName(szBuf, fNoReg);
  515. if (fOk)
  516. SaveAndRemoveWallpaper();
  517. return (short)fOk;
  518. }
  519. /***************************************************************************
  520. *
  521. *
  522. * ClearHighContrast
  523. *
  524. * Input: None
  525. * Output: None
  526. *
  527. * Outline:
  528. *
  529. * If high contrast is currently on:
  530. *
  531. * Get the PRE_HC_SCHEME.
  532. *
  533. * If able to get it:
  534. *
  535. * Make it the current scheme.
  536. *
  537. * If the name is IDS_PRE_HC_SCHEME, then delete the scheme
  538. * data and set the current scheme name to null. (Clean up.)
  539. *
  540. * End if
  541. *
  542. * Set the key that says that high contrast is now off.
  543. *
  544. * End if
  545. *
  546. ***************************************************************************/
  547. BOOL FAR PASCAL ClearHighContrast(BOOL fNoReg)
  548. {
  549. BOOL fOk = FALSE;
  550. WCHAR szBuf[MAX_SCHEME_NAME_SIZE];
  551. szBuf[0] = '\0';
  552. if (ERROR_SUCCESS == GetRegValue(HC_KEY, PRE_HC_SCHEME, szBuf, sizeof(szBuf)))
  553. {
  554. DBPRINTF(TEXT("ClearHighContrast: Reset to pre-HC scheme %s\r\n"), szBuf);
  555. fOk = SetCurrentSchemeName(szBuf, fNoReg); // reset the scheme
  556. // If persisting this setting, wallpaper may need to be restored.
  557. // If clearing a temporary setting then, to avoid user confusion,
  558. // we turned theming and wallpaper off permanently. Otherwise,
  559. // sometimes they'll loose these settings (when they log off and
  560. // log back on) and sometimes they won't (when they use the hot
  561. // keys to turn HC off).
  562. if (!fNoReg)
  563. {
  564. RestoreWallpaper();
  565. if (lstrcmpi(szBuf, PRE_HC_SCHEME) == 0)
  566. {
  567. DelRegValue(APPEARANCESCHEME, PRE_HC_SCHEME);
  568. DBPRINTF(TEXT("DelRegValue(%s, %s)\r\n"), APPEARANCESCHEME, PRE_HC_SCHEME);
  569. DelRegValue(DEFSCHEMEKEY, DEFSCHEMENAME);
  570. DBPRINTF(TEXT("DelRegValue(%s, %s)\r\n"), DEFSCHEMEKEY, DEFSCHEMENAME);
  571. }
  572. }
  573. }
  574. return fOk;
  575. }
  576. #if NEED_MSG_PUMP
  577. /***************************************************************************\
  578. * WndProc
  579. *
  580. * Processes messages for the main window.
  581. \***************************************************************************/
  582. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  583. {
  584. switch (message)
  585. {
  586. case WM_TIMER:
  587. if (wParam == 1)
  588. {
  589. KillTimer(hWnd, wParam);
  590. DBPRINTF(TEXT("WM_TIMER\r\n"));
  591. DestroyWindow(hWnd);
  592. }
  593. break;
  594. case WM_DESTROY:
  595. PostQuitMessage(0);
  596. break;
  597. default:
  598. return DefWindowProc(hWnd, message, wParam, lParam);
  599. }
  600. return 0;
  601. }
  602. #endif
  603. /***************************************************************************\
  604. * WinMain
  605. *
  606. * History:
  607. * 02-01-97 Fritz Sands Created
  608. * 12-19-00 micw added windowing code so theming calls would work
  609. \***************************************************************************/
  610. int WINAPI WinMain(
  611. HINSTANCE hInstance,
  612. HINSTANCE hPrevInstance,
  613. LPSTR lpszCmdParam,
  614. int nCmdShow)
  615. {
  616. #if NEED_MSG_PUMP
  617. MSG msg;
  618. WNDCLASSEX wcex;
  619. LPTSTR pszWindowClass = TEXT("SetHC"); // message-only window doesn't need localization
  620. HWND hWnd;
  621. #endif
  622. UINT index;
  623. BOOL fSet, fWasSet, fNoReg;
  624. CoInitialize(NULL);
  625. // Safety checks to make sure that it is not run from command line
  626. // Should have 3 characters, And all of them numeric...:a-anilk
  627. if ( strlen(lpszCmdParam) != 3 )
  628. return 0;
  629. for ( index = 0; index < 3 ; index++ )
  630. {
  631. if ( lpszCmdParam[index] < '0' || lpszCmdParam[index] > '9' )
  632. {
  633. return 0;
  634. }
  635. }
  636. fSet = lpszCmdParam[0] - '0';
  637. fWasSet = lpszCmdParam[1] - '0';
  638. fNoReg = lpszCmdParam[2] - '0';
  639. DBPRINTF(TEXT("WinMain: fSet=%d fWasSet=%d fNoReg=%d\r\n"), fSet, fWasSet, fNoReg);
  640. // this is to deal with HighContrast, StickyKey, ToggleKey, FilterKey and MouseKeys
  641. if ( fSet == 2 )
  642. {
  643. // this is which Dialog will be displayed
  644. LONG lPopup = lpszCmdParam[1] - '0';
  645. // This indicate wheather we will actually display the dialog or just do the work without asking
  646. BOOL fNotify = lpszCmdParam[2] - '0';
  647. DBPRINTF(TEXT("WinMain: lPopup=%d fNotify=%d\r\n"), lPopup, fNotify );
  648. // Make sure we don't access outside the bounds of the funtion pointer array
  649. if ( lPopup < 1 || lPopup > 5 )
  650. return 0;
  651. // Index into a table of functions pointers and call the
  652. // funtion to bring up the right hotkey dialog.
  653. g_aRtn[lPopup]( fNotify );
  654. CoUninitialize();
  655. return 1;
  656. }
  657. #if NEED_MSG_PUMP
  658. // Create a message only window to process messages from theme api
  659. wcex.cbSize = sizeof(WNDCLASSEX);
  660. wcex.style = 0;
  661. wcex.lpfnWndProc = WndProc;
  662. wcex.cbClsExtra = 0;
  663. wcex.cbWndExtra = 0;
  664. wcex.hInstance = hInstance;
  665. wcex.hIcon = NULL;
  666. wcex.hCursor = NULL;
  667. wcex.hbrBackground = NULL;
  668. wcex.lpszMenuName = NULL;
  669. wcex.lpszClassName = pszWindowClass;
  670. wcex.hIconSm = NULL;
  671. RegisterClassEx(&wcex);
  672. hWnd = CreateWindow(pszWindowClass,NULL,0,0,0,0,0,HWND_MESSAGE,NULL,hInstance,NULL);
  673. if (!hWnd)
  674. {
  675. return 0;
  676. }
  677. #endif
  678. if (fSet)
  679. {
  680. SetHighContrast(fWasSet, fNoReg);
  681. }
  682. else
  683. {
  684. ClearHighContrast(fNoReg);
  685. }
  686. #if NEED_MSG_PUMP
  687. SetTimer(hWnd, 1, 4000, NULL);
  688. // The calls to set/unset visual style require that messages
  689. // be processed. When the timer goes we'll exit.
  690. while (GetMessage(&msg, NULL, 0, 0))
  691. {
  692. TranslateMessage(&msg);
  693. DispatchMessage(&msg);
  694. }
  695. #endif
  696. CoUninitialize();
  697. return 1;
  698. }
  699. #ifdef DEBUG
  700. void MyOutputDebugString( LPCTSTR lpOutputString, ...)
  701. {
  702. TCHAR achBuffer[500];
  703. /* create the output buffer */
  704. va_list args;
  705. va_start(args, lpOutputString);
  706. wvsprintf(achBuffer, lpOutputString, args);
  707. va_end(args);
  708. OutputDebugString(achBuffer);
  709. }
  710. #endif