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.

1348 lines
42 KiB

  1. //Copyright (c) 1997-2000 Microsoft Corporation
  2. #include "pch.hxx" // pch
  3. #pragma hdrstop
  4. #include "Schemes.h"
  5. #include <WININET.H>
  6. #include <initguid.h>
  7. #include <shlobj.h>
  8. #include <objbase.h>
  9. #include <shlguid.h>
  10. #include <uxthemep.h>
  11. #include "w95trace.h"
  12. // To use the old way of enumerating fonts to get the font list,
  13. // and reading schemes from the registry, remove the comments from
  14. // the two lines below
  15. //#define ENUMERATEFONTS
  16. //#define READSCHEMESFROMREGISTRY
  17. #define CPL_APPEARANCE_NEW_SCHEMES TEXT("Control Panel\\Appearance\\New Schemes")
  18. #define NEW_SCHEMES_SELECTEDSTYLE TEXT("SelectedStyle")
  19. #define NEW_SCHEMES_SELECTEDSIZE TEXT("SelectedSize")
  20. #define HC_KEY TEXT("Control Panel\\Accessibility\\HighContrast")
  21. #define HC_FLAGS TEXT("Flags")
  22. #define PRE_HC_WALLPAPER TEXT("Pre-High Contrast Wallpaper")
  23. #define SYSPARAMINFO(xxx) m_##xxx.cbSize = sizeof(m_##xxx);SystemParametersInfo(SPI_GET##xxx, sizeof(m_##xxx), &m_##xxx, 0)
  24. //
  25. // Helper functions
  26. //
  27. #define REG_SET_DWSZ(hk, key, dw) \
  28. { \
  29. TCHAR szValue[20]; \
  30. wsprintf(szValue, TEXT("%d"), dw); \
  31. RegSetValueEx(hk, key, NULL, REG_SZ, (LPCBYTE)szValue, (lstrlen(szValue)+1)*sizeof(TCHAR)); \
  32. }
  33. void WIZSCHEME::ApplyChanges(const WIZSCHEME &schemeNew, NONCLIENTMETRICS *pForceNCM, LOGFONT *pForcelfIcon)
  34. {
  35. //
  36. // If user has changed the color scheme then apply the new scheme. Since this is
  37. // a high contrast scheme, also set the high contrast bit. We have to do this
  38. // w/o using SystemParametersInfo(SPI_SETHIGHCONTRAST...) because that function
  39. // also sets non-client metrics that accwiz must deal with separately from color.
  40. //
  41. BOOL fThemingOn = SetTheme(
  42. schemeNew.m_szThemeName
  43. , schemeNew.m_szThemeColor
  44. , schemeNew.m_szThemeSize);
  45. SetWallpaper(schemeNew.m_szWallpaper); // set wallpaper to new scheme's value
  46. if (fThemingOn)
  47. {
  48. DBPRINTF(TEXT("ApplyChanges: Theming is being turned on\r\n"));
  49. SetHCFlag(FALSE); // manually set high contrast flag off
  50. // restore "flatmenu" and "dropshadows" settings
  51. SystemParametersInfo(SPI_SETFLATMENU, 0, IntToPtr(schemeNew.m_fFlatMenus), SPIF_SENDCHANGE);
  52. SystemParametersInfo(SPI_SETDROPSHADOW, 0, IntToPtr(schemeNew.m_fDropShadows), SPIF_SENDCHANGE);
  53. }
  54. else if (lstrcmpi(schemeNew.m_szSelectedStyle, m_szSelectedStyle))
  55. {
  56. DBPRINTF(TEXT("ApplyChanges: Theming is off or being turned off\r\n"));
  57. // Setting a high contrast scheme
  58. if (0 != memcmp(schemeNew.m_rgb, m_rgb, sizeof(m_rgb)))
  59. {
  60. SetHCFlag(TRUE); // first, manually set the high contrast flag
  61. // (requires logoff/logon to take affect)
  62. // reset "flatmenu" and "dropshadows" settings
  63. SystemParametersInfo(SPI_SETFLATMENU, 0, IntToPtr(FALSE), SPIF_SENDCHANGE);
  64. SystemParametersInfo(SPI_SETDROPSHADOW, 0, IntToPtr(FALSE), SPIF_SENDCHANGE);
  65. // update the color scheme
  66. int rgInts[COLOR_MAX_97_NT5]; // then set UI elements to selected color scheme
  67. for(int i=0;i<COLOR_MAX_97_NT5;i++)
  68. {
  69. rgInts[i] = i;
  70. }
  71. SetSysColors(COLOR_MAX_97_NT5, rgInts, schemeNew.m_rgb);
  72. // The following code updates the registry HKCU\Control Panel\Colors to
  73. // reflect the new scheme so its available when the user logs on again
  74. HKEY hk;
  75. if (RegCreateKey(HKEY_CURRENT_USER, szRegStr_Colors, &hk) == ERROR_SUCCESS)
  76. {
  77. TCHAR szRGB[32];
  78. for (i = 0; i < COLOR_MAX_97_NT5; i++)
  79. {
  80. COLORREF rgb;
  81. rgb = schemeNew.m_rgb[i];
  82. wsprintf(szRGB, TEXT("%d %d %d"), GetRValue(rgb), GetGValue(rgb), GetBValue(rgb));
  83. WriteProfileString(g_szColors, s_pszColorNames[i], szRGB); // update win.ini
  84. RegSetValueEx(hk // update registry
  85. , s_pszColorNames[i]
  86. , 0L, REG_SZ
  87. , (LPBYTE)szRGB
  88. , sizeof(TCHAR) * (lstrlen(szRGB)+1));
  89. }
  90. RegCloseKey(hk);
  91. }
  92. // The W2K color schemes changed with WinXP. The old schemes (which we still use)
  93. // are still there but display CPL uses a new method for selecting colors. These
  94. // colors are under HKCU\Control Panel\Appearance\New Schemes. The "SelectedStyle"
  95. // string value is the current scheme. The number (0 thru 21) corresponds to the
  96. // order of the old colors under HKCU\Control Panel\Appearance\Schemes (excluding
  97. // those schemes with (large) and (extra large)). The details for the scheme are
  98. // subkeys (0 thru nn) under "New Schemes". In order for display CPL to show the
  99. // correct current scheme after we've been run, we need to update "SelectedStyle"
  100. // and "SelectedSize" (under the subkey specified in "SelectedStyle") with the
  101. // correct index and size numbers. Display CPL uses a much more robust way of
  102. // determining the legacy index but we only support four colors so we shouldn't
  103. // need all the extra code.
  104. if (RegOpenKeyEx(
  105. HKEY_CURRENT_USER,
  106. CPL_APPEARANCE_NEW_SCHEMES,
  107. 0, KEY_ALL_ACCESS,
  108. &hk) == ERROR_SUCCESS)
  109. {
  110. long lRv = RegSetValueEx(
  111. hk,
  112. NEW_SCHEMES_SELECTEDSTYLE,
  113. 0, REG_SZ,
  114. (LPCBYTE)schemeNew.m_szSelectedStyle,
  115. (lstrlen(schemeNew.m_szSelectedStyle)+1)*sizeof(TCHAR));
  116. RegCloseKey(hk);
  117. // If we've changed color then the size must be updated for that scheme
  118. UpdateSelectedSize(schemeNew.m_nSelectedSize, schemeNew.m_szSelectedStyle);
  119. }
  120. }
  121. else if (schemeNew.m_nSelectedSize >= 0 && schemeNew.m_nSelectedSize != m_nSelectedSize)
  122. {
  123. // Also update size if it changed but the color scheme didn't
  124. UpdateSelectedSize(schemeNew.m_nSelectedSize, schemeNew.m_szSelectedStyle);
  125. }
  126. }
  127. //
  128. // Apply any other changes
  129. //
  130. #define APPLY_SCHEME_CURRENT(xxx) if(0 != memcmp(&schemeNew.m_##xxx, &m_##xxx, sizeof(schemeNew.m_##xxx))) SystemParametersInfo(SPI_SET##xxx, sizeof(schemeNew.m_##xxx), (PVOID)&schemeNew.m_##xxx, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE)
  131. APPLY_SCHEME_CURRENT(FILTERKEYS);
  132. APPLY_SCHEME_CURRENT(MOUSEKEYS);
  133. APPLY_SCHEME_CURRENT(STICKYKEYS);
  134. APPLY_SCHEME_CURRENT(TOGGLEKEYS);
  135. APPLY_SCHEME_CURRENT(SOUNDSENTRY);
  136. APPLY_SCHEME_CURRENT(ACCESSTIMEOUT);
  137. // APPLY_SCHEME_CURRENT(SERIALKEYS);
  138. // Check Show Sounds
  139. if(schemeNew.m_bShowSounds != m_bShowSounds)
  140. SystemParametersInfo(SPI_SETSHOWSOUNDS, schemeNew.m_bShowSounds, NULL, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
  141. // Check Extra keyboard help
  142. if(schemeNew.m_bShowExtraKeyboardHelp != m_bShowExtraKeyboardHelp)
  143. {
  144. // Both required:
  145. SystemParametersInfo(SPI_SETKEYBOARDPREF, schemeNew.m_bShowExtraKeyboardHelp, NULL, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
  146. SystemParametersInfo(SPI_SETKEYBOARDCUES, 0, IntToPtr(schemeNew.m_bShowExtraKeyboardHelp), SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
  147. }
  148. // Check swap mouse buttons
  149. if(schemeNew.m_bSwapMouseButtons != m_bSwapMouseButtons)
  150. SwapMouseButton(schemeNew.m_bSwapMouseButtons);
  151. // Check Mouse Trails
  152. if(schemeNew.m_nMouseTrails != m_nMouseTrails)
  153. SystemParametersInfo(SPI_SETMOUSETRAILS, schemeNew.m_nMouseTrails, NULL, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
  154. // Check Mouse Speed
  155. if(schemeNew.m_nMouseSpeed != m_nMouseSpeed)
  156. SystemParametersInfo(SPI_SETMOUSESPEED, 0, IntToPtr(schemeNew.m_nMouseSpeed), SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
  157. // Reset cursor width and blink time
  158. if (schemeNew.m_dwCaretWidth != m_dwCaretWidth)
  159. SystemParametersInfo(SPI_SETCARETWIDTH, 0, IntToPtr(schemeNew.m_dwCaretWidth), SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
  160. if (schemeNew.m_uCursorBlinkTime != m_uCursorBlinkTime)
  161. {
  162. // Set the blink rate for this session
  163. SetCaretBlinkTime(schemeNew.m_uCursorBlinkTime);
  164. // and persist it to the registry
  165. RegSetStrDW(HKEY_CURRENT_USER, CONTROL_PANEL_DESKTOP, CURSOR_BLINK_RATE, schemeNew.m_uCursorBlinkTime);
  166. }
  167. // Check icon size
  168. if(schemeNew.m_nIconSize != m_nIconSize)
  169. WIZSCHEME::SetShellLargeIconSize(schemeNew.m_nIconSize);
  170. // Check cursor scheme
  171. if(schemeNew.m_nCursorScheme != m_nCursorScheme)
  172. ApplyCursorScheme(schemeNew.m_nCursorScheme);
  173. // NonClientMetric changes
  174. {
  175. NONCLIENTMETRICS ncmOrig;
  176. LOGFONT lfOrig;
  177. GetNonClientMetrics(&ncmOrig, &lfOrig);
  178. if(pForceNCM)
  179. {
  180. // If they gave us a NCM, they must also give us a LOGFONT for the icon
  181. _ASSERTE(pForcelfIcon);
  182. // We were given an Original NCM to use
  183. if(0 != memcmp(pForceNCM, &ncmOrig, sizeof(ncmOrig)))
  184. SystemParametersInfo(SPI_SETNONCLIENTMETRICS, sizeof(*pForceNCM), pForceNCM, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
  185. if(0 != memcmp(pForcelfIcon, &lfOrig, sizeof(lfOrig)))
  186. SystemParametersInfo(SPI_SETICONTITLELOGFONT, sizeof(*pForcelfIcon), pForcelfIcon, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
  187. }
  188. else
  189. {
  190. // Note: This part of apply changes does not look at schemeCurrent - it only looks
  191. // at what we are applying
  192. schemeNew.m_PortableNonClientMetrics.ApplyChanges();
  193. }
  194. }
  195. *this = schemeNew;
  196. }
  197. // Set the high contrast flag on or off based on fSet
  198. void WIZSCHEME::SetHCFlag(BOOL fSetOn)
  199. {
  200. //
  201. // This key is cached in the OS so setting it outside of
  202. // SystemParametersInfo(SPI_SETHIGHCONTRAST doesn't take
  203. // effect until the user logs off and on again. Is there
  204. // a way to cause the cache to be refreshed?
  205. //
  206. HKEY hk;
  207. if (RegOpenKeyEx(HKEY_CURRENT_USER, HC_KEY, 0, KEY_ALL_ACCESS, &hk) == ERROR_SUCCESS)
  208. {
  209. TCHAR szValue[20];
  210. DWORD dwSize = sizeof(szValue)*sizeof(TCHAR);
  211. if (RegQueryValueEx(hk, HC_FLAGS, NULL, NULL, (LPBYTE)szValue, &dwSize) == ERROR_SUCCESS)
  212. {
  213. DWORD dwValue = _ttol(szValue);
  214. if (fSetOn && !(dwValue & HCF_HIGHCONTRASTON))
  215. {
  216. dwValue |= HCF_HIGHCONTRASTON;
  217. REG_SET_DWSZ(hk, HC_FLAGS, dwValue)
  218. }
  219. else if (!fSetOn && (dwValue & HCF_HIGHCONTRASTON))
  220. {
  221. dwValue &= ~HCF_HIGHCONTRASTON;
  222. REG_SET_DWSZ(hk, HC_FLAGS, dwValue)
  223. }
  224. }
  225. RegCloseKey(hk);
  226. }
  227. }
  228. /***************************************************************************
  229. * SaveWallpaper
  230. *
  231. * Saves the current wallpaper setting from the system.
  232. *
  233. * ISSUE we aren't getting all the active desktop properties; just wallpaper.
  234. * This isn't a regression in that we didn't even restore wallpaper in W2K.
  235. *
  236. ***************************************************************************/
  237. void WIZSCHEME::SaveWallpaper()
  238. {
  239. IActiveDesktop *p;
  240. HRESULT hr = CoCreateInstance(
  241. CLSID_ActiveDesktop
  242. , NULL
  243. , CLSCTX_INPROC_SERVER
  244. , IID_IActiveDesktop
  245. , (void **)&p);
  246. if (SUCCEEDED(hr) && p)
  247. {
  248. hr = p->GetWallpaper(m_szWallpaper, MAX_THEME_SZ, 0);
  249. p->Release();
  250. }
  251. DBPRINTF(TEXT("SaveWallpaper: m_szWallpaper = %s (hr = 0x%x)\r\n"), m_szWallpaper, hr);
  252. }
  253. /***************************************************************************
  254. * SetWallpaper
  255. *
  256. * Restores the pre-high contrast wallpaper setting. Reads the setting
  257. * stored in the accessibility registry entries and restores the system
  258. * setting. No error return as there isn't anything we can do.
  259. *
  260. ***************************************************************************/
  261. void WIZSCHEME::SetWallpaper(LPCTSTR pszWallpaper)
  262. {
  263. if (lstrcmpi(m_szWallpaper, pszWallpaper))
  264. {
  265. IActiveDesktop *p;
  266. LPCTSTR psz = (pszWallpaper)?pszWallpaper:TEXT("");
  267. HRESULT hr = CoCreateInstance(
  268. CLSID_ActiveDesktop
  269. , NULL
  270. , CLSCTX_INPROC_SERVER
  271. , IID_IActiveDesktop
  272. , (void **)&p);
  273. if (SUCCEEDED(hr) && p)
  274. {
  275. hr = p->SetWallpaper(psz, 0);
  276. if (SUCCEEDED(hr))
  277. p->ApplyChanges(AD_APPLY_ALL);
  278. p->Release();
  279. }
  280. DBPRINTF(TEXT("SetWallpaper: psz = %s (hr = 0x%x)\r\n"), psz, hr);
  281. }
  282. }
  283. /***************************************************************************
  284. * SaveTheme
  285. *
  286. * Saves the theme file settings that are active before accwiz was run.
  287. *
  288. ***************************************************************************/
  289. void WIZSCHEME::SaveTheme()
  290. {
  291. HRESULT hr = E_FAIL;
  292. if (IsThemeActive())
  293. {
  294. hr = GetCurrentThemeName(
  295. m_szThemeName, MAX_THEME_SZ
  296. , m_szThemeColor, MAX_THEME_SZ
  297. , m_szThemeSize, MAX_THEME_SZ);
  298. }
  299. if (FAILED(hr))
  300. {
  301. // themes is not turned on
  302. m_szThemeName[0] = 0;
  303. m_szThemeColor[0] = 0;
  304. m_szThemeSize[0] = 0;
  305. }
  306. //---- save off "flatmenu" and "dropshadows" settings ---
  307. SystemParametersInfo(SPI_GETFLATMENU, 0, (PVOID)&m_fFlatMenus, 0);
  308. SystemParametersInfo(SPI_GETDROPSHADOW, 0, (PVOID)&m_fDropShadows, 0);
  309. DBPRINTF(TEXT("SaveTheme: m_szThemeName = %s m_szThemeColor = %s m_szThemeSize = %s (hr = 0x%x)\r\n"), m_szThemeName, m_szThemeColor, m_szThemeSize, hr);
  310. }
  311. /***************************************************************************
  312. * SetTheme
  313. *
  314. * If a theme name, color and size is passed then sets it
  315. * else turns off theming.
  316. *
  317. * Returns TRUE if a theme was set else FALSE it themes were turned off.
  318. *
  319. ***************************************************************************/
  320. BOOL WIZSCHEME::SetTheme(LPCTSTR pszThemeName, LPCTSTR pszThemeColor, LPCTSTR pszThemeSize)
  321. {
  322. BOOL fRet = FALSE; // didn't turn themes on
  323. // only attempt to do anything if the new theme differs from current
  324. if ( lstrcmpi(m_szThemeName, pszThemeName)
  325. || lstrcmpi(m_szThemeColor, pszThemeColor)
  326. || lstrcmpi(m_szThemeSize, pszThemeSize) )
  327. {
  328. HRESULT hr;
  329. if (pszThemeName[0] && pszThemeColor[0] && pszThemeSize[0])
  330. {
  331. HTHEMEFILE hThemeFile;
  332. hr = OpenThemeFile(pszThemeName, pszThemeColor, pszThemeSize, &hThemeFile, TRUE);
  333. if (SUCCEEDED(hr))
  334. {
  335. hr = ApplyTheme(hThemeFile, AT_LOAD_SYSMETRICS | AT_SYNC_LOADMETRICS, NULL);
  336. CloseThemeFile(hThemeFile);
  337. fRet = TRUE; // turned themes on
  338. }
  339. DBPRINTF(TEXT("SetTheme: pszThemeName = %s pszThemeColor = %s pszThemeSize = %s(hr = 0x%x)\r\n"), pszThemeName, pszThemeColor, pszThemeSize, hr);
  340. }
  341. else if (IsThemeActive())
  342. {
  343. hr = ApplyTheme(NULL, 0, NULL);
  344. DBPRINTF(TEXT("SetTheme: Themes are now off hr = 0x%x\r\n"), hr);
  345. }
  346. }
  347. return fRet;
  348. }
  349. /***************************************************************************
  350. * UpdateSelectedSize
  351. *
  352. * Updates the SelectedSize under a "New Scheme" entry.
  353. *
  354. * NOTE: AccWiz doesn't use the font metrics from the registry so
  355. * it doesn't actually give fonts that are "normal", "large"
  356. * and "extra large" as display and access CPLs know them.
  357. * The closest sizes are "normal" and "large".
  358. *
  359. ***************************************************************************/
  360. void WIZSCHEME::UpdateSelectedSize(int nSelectedSize, LPCTSTR pszSelectedStyle)
  361. {
  362. LPTSTR pszSelectedSize;
  363. LPTSTR aszSelectedSizes[] = {TEXT("0")/*normal*/, TEXT("2")/*large*/, TEXT("1")/*extra large*/};
  364. switch (nSelectedSize)
  365. {
  366. case 0: pszSelectedSize = aszSelectedSizes[0]; break; // normal text size
  367. case 1: pszSelectedSize = aszSelectedSizes[0]; break; // normal text size
  368. case 2: pszSelectedSize = aszSelectedSizes[1]; break; // large text size
  369. default: pszSelectedSize = 0; break;
  370. }
  371. if (pszSelectedSize)
  372. {
  373. HKEY hk;
  374. if (RegOpenKeyEx(HKEY_CURRENT_USER,
  375. CPL_APPEARANCE_NEW_SCHEMES,
  376. 0, KEY_ALL_ACCESS,
  377. &hk) == ERROR_SUCCESS)
  378. {
  379. HKEY hkSub;
  380. if (RegOpenKeyEx(hk, pszSelectedStyle, 0, KEY_ALL_ACCESS, &hkSub) == ERROR_SUCCESS)
  381. {
  382. RegSetValueEx(hkSub,
  383. NEW_SCHEMES_SELECTEDSIZE,
  384. 0, REG_SZ,
  385. (LPCBYTE)pszSelectedSize,
  386. (lstrlen(pszSelectedSize)+1)*sizeof(TCHAR));
  387. RegCloseKey(hkSub);
  388. }
  389. }
  390. RegCloseKey(hk);
  391. }
  392. }
  393. /***************************************************************************
  394. * SetStyleNSize
  395. *
  396. * Helper for legacy schemes - figures out SelectedStyle and SelectedSize
  397. * from the legacy scheme's data.
  398. *
  399. ***************************************************************************/
  400. void WIZSCHEME::SetStyleNSize()
  401. {
  402. int cStdSchemes = GetSchemeCount();
  403. int i;
  404. // Init the fields this function will be setting
  405. m_szSelectedStyle[0] = 0;
  406. m_nSelectedSize = 0;
  407. // Figure out the SelectedStyle by finding the best-match for
  408. // colors between what accwiz supports now and what it had in
  409. // previous versions. After finding the best match, copy the
  410. // latest colors in; this fixes some bugs with old colors.
  411. SCHEMEDATALOCAL sdlTemp;
  412. int iBestColorFit = -1; // guarrantee we'll find one
  413. int cBestMatch = 0;
  414. for (i=0;i<cStdSchemes;i++)
  415. {
  416. int cMatches = 0;
  417. sdlTemp = GetScheme(i);
  418. // assumption: sizeof(m_rgb) > sizeof(sdlTemp.rgb)
  419. for (int cColor = 0;cColor < sdlTemp.nColorsUsed; cColor++)
  420. {
  421. if (sdlTemp.rgb[cColor] == m_rgb[cColor])
  422. {
  423. cMatches++;
  424. }
  425. }
  426. if (cBestMatch < cMatches)
  427. {
  428. iBestColorFit = i;
  429. cBestMatch = cMatches;
  430. }
  431. // if its an exact match just use it
  432. if (cMatches == sdlTemp.nColorsUsed)
  433. break;
  434. }
  435. // load up the SelectedStyle
  436. sdlTemp = GetScheme(iBestColorFit);
  437. LoadString(g_hInstDll, sdlTemp.nNameStringId+100
  438. , m_szSelectedStyle
  439. , ARRAYSIZE(m_szSelectedStyle));
  440. // fix up any color problems
  441. memcpy(m_rgb, sdlTemp.rgb, sizeof(sdlTemp.rgb));
  442. // Figure out the SelectedSize based on reverse-compute minimum
  443. // font size and hard-coded limits from the Welcome page
  444. HDC hDC = GetDC(NULL);
  445. if (hDC)
  446. {
  447. long lMinFontSize = ((-m_PortableNonClientMetrics.m_lfCaptionFont_lfHeight)*72)/GetDeviceCaps(hDC, LOGPIXELSY);
  448. ReleaseDC(NULL, hDC);
  449. if (lMinFontSize <=9)
  450. {
  451. m_nSelectedSize = 0;
  452. }
  453. else if (lMinFontSize <=12)
  454. {
  455. m_nSelectedSize = 1;
  456. }
  457. else if (lMinFontSize <=16)
  458. {
  459. m_nSelectedSize = 2;
  460. }
  461. }
  462. }
  463. void WIZSCHEME::LoadOriginal()
  464. {
  465. DBPRINTF(TEXT("LoadOriginal\r\n"));
  466. //
  467. // Save off current UI element colors, theme information, and wallpaper setting
  468. //
  469. for(int i=0;i<COLOR_MAX_97_NT5;i++)
  470. m_rgb[i] = GetSysColor(i);
  471. SaveTheme();
  472. SaveWallpaper();
  473. //
  474. // Save off the rest of the UI settings
  475. //
  476. SYSPARAMINFO(FILTERKEYS);
  477. SYSPARAMINFO(MOUSEKEYS);
  478. SYSPARAMINFO(STICKYKEYS);
  479. SYSPARAMINFO(TOGGLEKEYS);
  480. SYSPARAMINFO(SOUNDSENTRY);
  481. SYSPARAMINFO(ACCESSTIMEOUT);
  482. m_bShowSounds = GetSystemMetrics(SM_SHOWSOUNDS);
  483. SystemParametersInfo(SPI_GETKEYBOARDPREF, 0, &m_bShowExtraKeyboardHelp, 0);
  484. m_bSwapMouseButtons = GetSystemMetrics(SM_SWAPBUTTON);
  485. SystemParametersInfo(SPI_GETMOUSETRAILS, 0, &m_nMouseTrails, 0);
  486. SystemParametersInfo(SPI_GETMOUSESPEED,0, &m_nMouseSpeed, 0);
  487. SystemParametersInfo(SPI_GETCARETWIDTH, 0 , &m_dwCaretWidth, 0);
  488. m_uCursorBlinkTime = RegQueryStrDW(
  489. DEFAULT_BLINK_RATE
  490. , HKEY_CURRENT_USER
  491. , CONTROL_PANEL_DESKTOP
  492. , CURSOR_BLINK_RATE);
  493. m_nIconSize = SetShellLargeIconSize(0); // This just gets the current size
  494. m_nCursorScheme = 0; // We are always using the 'current' cursor scheme =)
  495. m_PortableNonClientMetrics.LoadOriginal();
  496. // Save off current "New Schemes" settings if we aren't themed
  497. if (IsThemeActive())
  498. {
  499. LoadString(g_hInstDll, IDS_SCHEME_CURRENTCOLORSCHEME+100, m_szSelectedStyle, MAX_NUM_SZ);
  500. m_nSelectedSize = 0;
  501. }
  502. else
  503. {
  504. HKEY hk;
  505. if (RegOpenKeyEx(HKEY_CURRENT_USER, CPL_APPEARANCE_NEW_SCHEMES, 0, KEY_READ, &hk) == ERROR_SUCCESS)
  506. {
  507. DWORD ccb = ARRAYSIZE(m_szSelectedStyle)*sizeof(TCHAR);
  508. m_szSelectedStyle[0] = 0;
  509. if (RegQueryValueEx(hk, NEW_SCHEMES_SELECTEDSTYLE, 0, NULL, (LPBYTE)m_szSelectedStyle, &ccb) == ERROR_SUCCESS && ccb > 2)
  510. {
  511. HKEY hkSub;
  512. if (RegOpenKeyEx(hk, m_szSelectedStyle, 0, KEY_READ, &hkSub) == ERROR_SUCCESS)
  513. {
  514. TCHAR szSize[MAX_NUM_SZ] = {0};
  515. ccb = ARRAYSIZE(szSize)*sizeof(TCHAR);
  516. DBPRINTF(TEXT("RegQueryValueEx(NEW_SCHEMES_SELECTEDSIZE=%s,,,ccb=%d)\r\n"), NEW_SCHEMES_SELECTEDSIZE, ccb);
  517. RegQueryValueEx(hkSub, NEW_SCHEMES_SELECTEDSIZE, 0, NULL, (LPBYTE)szSize, &ccb);
  518. m_nSelectedSize = (szSize[0] && ccb > 2) ? _wtoi(szSize) : -1;
  519. DBPRINTF(TEXT("szSize=%d ccb=%d m_nSelectedSize=%d\r\n"), szSize, ccb, m_nSelectedSize);
  520. RegCloseKey(hkSub);
  521. }
  522. }
  523. RegCloseKey(hk);
  524. }
  525. }
  526. }
  527. /////////////////////////////////////////////////////////////////////
  528. // New way of enumerating fonts
  529. #ifndef ENUMERATEFONTS
  530. static LPCTSTR g_lpszFontNames[] =
  531. {
  532. __TEXT("Arial"),
  533. __TEXT("MS Sans Serif"),
  534. __TEXT("Tahoma"),
  535. __TEXT("Times New Roman")
  536. };
  537. int GetFontCount()
  538. {
  539. return ARRAYSIZE(g_lpszFontNames);
  540. }
  541. void GetFontLogFont(int nIndex, LOGFONT *pLogFont)
  542. {
  543. _ASSERTE(nIndex < ARRAYSIZE(g_lpszFontNames));
  544. memset(pLogFont, 0, sizeof(*pLogFont));
  545. lstrcpy(pLogFont->lfFaceName, g_lpszFontNames[nIndex]);
  546. }
  547. #endif // ENUMERATEFONTS
  548. //
  549. /////////////////////////////////////////////////////////////////////
  550. /////////////////////////////////////////////////////////////////////
  551. // New way of storing schemes as hard coded values
  552. // CONSIDER - this isn't a very robust way to do this; see sethc
  553. #ifndef READSCHEMESFROMREGISTRY
  554. #include "resource.h"
  555. static SCHEMEDATALOCAL g_rgSchemeData[] =
  556. {
  557. {
  558. IDS_SCHEME_HIGHCONTRASTBLACKALTERNATE,
  559. {NULL},
  560. #if(WINVER >= 0x0501)
  561. 31,
  562. #elif(WINVER == 0x0500)
  563. 29,
  564. #else
  565. 25,
  566. #endif
  567. {
  568. RGB( 0, 0, 0), // Scrollbar
  569. RGB( 0, 0, 0), // Background
  570. RGB( 0, 0, 255), // ActiveTitle
  571. RGB( 0, 255, 255), // InactiveTitle
  572. RGB( 0, 0, 0), // Menu
  573. RGB( 0, 0, 0), // Window
  574. RGB(255, 255, 255), // WindowFrame
  575. RGB(255, 255, 255), // MenuText
  576. RGB(255, 255, 0), // WindowText
  577. RGB(255, 255, 255), // TitleText
  578. RGB( 0, 0, 255), // ActiveBorder
  579. RGB( 0, 255, 255), // InactiveBorder
  580. RGB( 0, 0, 0), // AppWorkspace
  581. RGB( 0, 128, 0), // Hilight
  582. RGB(255, 255, 255), // HilightText
  583. RGB( 0, 0, 0), // ButtonFace
  584. RGB(128, 128, 128), // ButtonShadow
  585. RGB( 0, 255, 0), // GrayText
  586. RGB(255, 255, 255), // ButtonText
  587. RGB( 0, 0, 0), // InactiveTitleText
  588. RGB(192, 192, 192), // ButtonHilight
  589. RGB(255, 255, 255), // ButtonDkShadow
  590. RGB(255, 255, 255), // ButtonLight
  591. RGB(255, 255, 0), // InfoText
  592. RGB( 0, 0, 0), // InfoWindow
  593. #if(WINVER >= 0x0500)
  594. RGB(192, 192, 192), // ButtonAlternateFace
  595. RGB(128, 0, 128), // HotTrackingColor
  596. RGB( 0, 0, 255), // GradientActiveTitle
  597. RGB( 0, 255, 255), // GradientInactiveTitle
  598. #if(WINVER >= 0x0501)
  599. RGB(128, 0, 128), // MenuHighlighted
  600. RGB( 0, 0, 0) // MenuBar
  601. #endif /* WINVER >= 0x0501 */
  602. #endif /* WINVER >= 0x0500 */
  603. }
  604. },
  605. {
  606. IDS_SCHEME_HIGHCONTRASTWHITEALTERNATE,
  607. {NULL},
  608. #if(WINVER >= 0x0501)
  609. 31,
  610. #elif(WINVER == 0x0500)
  611. 29,
  612. #else
  613. 25,
  614. #endif
  615. {
  616. RGB( 0, 0, 0), // Scrollbar
  617. RGB( 0, 0, 0), // Background
  618. RGB( 0, 255, 255), // ActiveTitle
  619. RGB( 0, 0, 255), // InactiveTitle
  620. RGB( 0, 0, 0), // Menu
  621. RGB( 0, 0, 0), // Window
  622. RGB(255, 255, 255), // WindowFrame
  623. RGB( 0, 255, 0), // MenuText
  624. RGB( 0, 255, 0), // WindowText
  625. RGB( 0, 0, 0), // TitleText
  626. RGB( 0, 255, 255), // ActiveBorder
  627. RGB( 0, 0, 255), // InactiveBorder
  628. RGB(255, 251, 240), // AppWorkspace
  629. RGB( 0, 0, 255), // Hilight
  630. RGB(255, 255, 255), // HilightText
  631. RGB( 0, 0, 0), // ButtonFace
  632. RGB(128, 128, 128), // ButtonShadow
  633. RGB( 0, 255, 0), // GrayText
  634. RGB( 0, 255, 0), // ButtonText
  635. RGB(255, 255, 255), // InactiveTitleText
  636. RGB(192, 192, 192), // ButtonHilight
  637. RGB(255, 255, 255), // ButtonDkShadow
  638. RGB(255, 255, 255), // ButtonLight
  639. RGB( 0, 0, 0), // InfoText
  640. RGB(255, 255, 0), // InfoWindow
  641. #if(WINVER >= 0x0500)
  642. RGB(192, 192, 192), // ButtonAlternateFace
  643. RGB(128, 0, 128), // HotTrackingColor
  644. RGB( 0, 255, 255), // GradientActiveTitle
  645. RGB( 0, 0, 255), // GradientInactiveTitle
  646. #if(WINVER >= 0x0501)
  647. RGB(128, 0, 128), // MenuHighlighted
  648. RGB( 0, 0, 0) // MenuBar
  649. #endif /* WINVER >= 0x0501 */
  650. #endif /* WINVER >= 0x0500 */
  651. }
  652. },
  653. {
  654. IDS_SCHEME_HIGHCONTRASTBLACK,
  655. {NULL},
  656. #if(WINVER >= 0x0501)
  657. 31,
  658. #elif(WINVER == 0x0500)
  659. 29,
  660. #else
  661. 25,
  662. #endif
  663. {
  664. RGB( 0, 0, 0), // Scrollbar
  665. RGB( 0, 0, 0), // Background
  666. RGB(128, 0, 128), // ActiveTitle
  667. RGB( 0, 128, 0), // InactiveTitle
  668. RGB( 0, 0, 0), // Menu
  669. RGB( 0, 0, 0), // Window
  670. RGB(255, 255, 255), // WindowFrame
  671. RGB(255, 255, 255), // MenuText
  672. RGB(255, 255, 255), // WindowText
  673. RGB(255, 255, 255), // TitleText
  674. RGB(255, 255, 0), // ActiveBorder
  675. RGB( 0, 128, 0), // InactiveBorder
  676. RGB( 0, 0, 0), // AppWorkspace
  677. RGB(128, 0, 128), // Hilight
  678. RGB(255, 255, 255), // HilightText
  679. RGB( 0, 0, 0), // ButtonFace
  680. RGB(128, 128, 128), // ButtonShadow
  681. RGB( 0, 255, 0), // GrayText
  682. RGB(255, 255, 255), // ButtonText
  683. RGB(255, 255, 255), // InactiveTitleText
  684. RGB(192, 192, 192), // ButtonHilight
  685. RGB(255, 255, 255), // ButtonDkShadow
  686. RGB(255, 255, 255), // ButtonLight
  687. RGB(255, 255, 255), // InfoText
  688. RGB( 0, 0, 0), // InfoWindow
  689. #if(WINVER >= 0x0500)
  690. RGB(192, 192, 192), // ButtonAlternateFace
  691. RGB(128, 0, 128), // HotTrackingColor
  692. RGB(128, 0, 128), // GradientActiveTitle
  693. RGB( 0, 128, 0), // GradientInactiveTitle
  694. #if(WINVER >= 0x0501)
  695. RGB(128, 0, 128), // MenuHighlighted
  696. RGB( 0, 0, 0) // MenuBar
  697. #endif /* WINVER >= 0x0501 */
  698. #endif /* WINVER >= 0x0500 */
  699. }
  700. },
  701. {
  702. IDS_SCHEME_HIGHCONTRASTWHITE,
  703. {NULL},
  704. #if(WINVER >= 0x0501)
  705. 31,
  706. #elif(WINVER == 0x0500)
  707. 29,
  708. #else
  709. 25,
  710. #endif
  711. {
  712. RGB(255, 255, 255), // Scrollbar
  713. RGB(255, 255, 255), // Background
  714. RGB( 0, 0, 0), // ActiveTitle
  715. RGB(255, 255, 255), // InactiveTitle
  716. RGB(255, 255, 255), // Menu
  717. RGB(255, 255, 255), // Window
  718. RGB( 0, 0, 0), // WindowFrame
  719. RGB( 0, 0, 0), // MenuText (enabled menu text FlatMenuMode = TRUE)
  720. RGB( 0, 0, 0), // WindowText
  721. RGB(255, 255, 255), // TitleText
  722. RGB(128, 128, 128), // ActiveBorder
  723. RGB(192, 192, 192), // InactiveBorder
  724. RGB(128, 128, 128), // AppWorkspace
  725. RGB( 0, 0, 0), // Hilight (and enabled menu highlighted background FlatMenuMode = FALSE)
  726. RGB(255, 255, 255), // HilightText (and menu highlighted text FlatMenuMode = FALSE)
  727. RGB(255, 255, 255), // ButtonFace
  728. RGB(128, 128, 128), // ButtonShadow
  729. RGB( 0, 255, 0), // GrayText (disabled menu text highlighted = green)
  730. RGB( 0, 0, 0), // ButtonText
  731. RGB( 0, 0, 0), // InactiveTitleText
  732. RGB(192, 192, 192), // ButtonHilight (disabled menu text = grey)
  733. RGB( 0, 0, 0), // ButtonDkShadow
  734. RGB(192, 192, 192), // ButtonLight
  735. RGB( 0, 0, 0), // InfoText
  736. RGB(255, 255, 255), // InfoWindow
  737. #if(WINVER >= 0x0500)
  738. RGB(192, 192, 192), // ButtonAlternateFace
  739. RGB( 0, 0, 0), // HotTrackingColor
  740. RGB( 0, 0, 0), // GradientActiveTitle
  741. RGB(255, 255, 255), // GradientInactiveTitle
  742. #if(WINVER >= 0x0501)
  743. RGB( 0, 0, 0), // MenuHighlighted (enabled menu highlighted background FlatMenuMode = TRUE)
  744. RGB(255, 255, 255) // MenuBar
  745. #endif /* WINVER >= 0x0501 */
  746. #endif /* WINVER >= 0x0500 */
  747. }
  748. }
  749. };
  750. int GetSchemeCount()
  751. {
  752. return ARRAYSIZE(g_rgSchemeData);
  753. }
  754. // GetSchemeName is only called to initialize the color scheme list box
  755. void GetSchemeName(int nIndex, LPTSTR lpszName, int nLen) // JMC: HACK - You must allocate enough space
  756. {
  757. _ASSERTE(nIndex < ARRAYSIZE(g_rgSchemeData));
  758. LoadString(g_hInstDll, g_rgSchemeData[nIndex].nNameStringId, lpszName, nLen); // return the name
  759. LoadString(g_hInstDll, g_rgSchemeData[nIndex].nNameStringId+100
  760. , g_rgSchemeData[nIndex].szNameIndexId
  761. , ARRAYSIZE(g_rgSchemeData[nIndex].szNameIndexId)); // get the "SelectedStyle" index
  762. }
  763. SCHEMEDATALOCAL &GetScheme(int nIndex)
  764. {
  765. _ASSERTE(nIndex < ARRAYSIZE(g_rgSchemeData));
  766. return g_rgSchemeData[nIndex];
  767. }
  768. #endif // READSCHEMESFROMREGISTRY
  769. //
  770. /////////////////////////////////////////////////////////////////////
  771. /////////////////////////////////////////////////////////////////////
  772. // Below this point in the file, we have the old way we use
  773. // to enumerate fonts and schemes.
  774. /////////////////////////////////////////////////////////////////////
  775. // Old way of enumerating fonts
  776. #ifdef ENUMERATEFONTS
  777. // Global Variables
  778. static ENUMLOGFONTEX g_rgFonts[200]; // JMC: HACK - At Most 200 Fonts
  779. static int g_nFontCount = 0;
  780. static BOOL bFontsAlreadyInit = FALSE;
  781. void Font_Init();
  782. int GetFontCount()
  783. {
  784. if(!bFontsAlreadyInit)
  785. Font_Init();
  786. return g_nFontCount;
  787. }
  788. void GetFontLogFont(int nIndex, LOGFONT *pLogFont)
  789. {
  790. if(!bFontsAlreadyInit)
  791. Font_Init();
  792. *pLogFont = g_rgFonts[nIndex].elfLogFont;
  793. }
  794. int CALLBACK EnumFontFamExProc(
  795. ENUMLOGFONTEX *lpelfe, // pointer to logical-font data
  796. NEWTEXTMETRICEX *lpntme, // pointer to physical-font data
  797. int FontType, // type of font
  798. LPARAM lParam // application-defined data
  799. )
  800. {
  801. if(g_nFontCount>200)
  802. return 0; // JMC: HACK - Stop enumerating if more than 200 families
  803. // Don't use if we already have this font name
  804. BOOL bHave = FALSE;
  805. for(int i=0;i<g_nFontCount;i++)
  806. if(0 == lstrcmp((TCHAR *)g_rgFonts[i].elfFullName, (TCHAR *)lpelfe->elfFullName))
  807. {
  808. bHave = TRUE;
  809. break;
  810. }
  811. if(!bHave)
  812. g_rgFonts[g_nFontCount++] = *lpelfe;
  813. return 1;
  814. }
  815. void Font_Init()
  816. {
  817. // Only do the stuff in this function once.
  818. if(bFontsAlreadyInit)
  819. return;
  820. bFontsAlreadyInit = TRUE;
  821. LOGFONT lf;
  822. memset(&lf, 0, sizeof(lf));
  823. // lf.lfCharSet = DEFAULT_CHARSET;
  824. lf.lfCharSet = OEM_CHARSET;
  825. HDC hdc = GetDC(NULL);
  826. EnumFontFamiliesEx(hdc, &lf, (FONTENUMPROC)EnumFontFamExProc, 0, 0);
  827. ReleaseDC(NULL, hdc);
  828. // JMC: Make sure there is at least one font
  829. }
  830. #endif ENUMERATEFONTS
  831. //
  832. /////////////////////////////////////////////////////////////////////
  833. /////////////////////////////////////////////////////////////////////
  834. // Old way of reading schemes from the registry
  835. #ifdef READSCHEMESFROMREGISTRY
  836. extern PTSTR s_pszColorNames[]; // JMC: HACK
  837. // Scheme data for Windows 95
  838. typedef struct {
  839. SHORT version;
  840. // NONCLIENTMETRICSA ncm;
  841. // LOGFONTA lfIconTitle;
  842. BYTE rgDummy[390]; // This is the size of NONCLIENTMETRICSA and LOGFONTA in 16 bit Windows!!!
  843. COLORREF rgb[COLOR_MAX_95_NT4];
  844. } SCHEMEDATA_95;
  845. // New scheme data for Windows 97
  846. typedef struct {
  847. SHORT version;
  848. // NONCLIENTMETRICSA ncm;
  849. // LOGFONTA lfIconTitle;
  850. BYTE rgDummy[390]; // This is the size of NONCLIENTMETRICSA and LOGFONTA in 16 bit Windows!!!
  851. COLORREF rgb[COLOR_MAX_97_NT5];
  852. } SCHEMEDATA_97;
  853. // Scheme data for Windows NT 4.0
  854. typedef struct {
  855. SHORT version;
  856. WORD wDummy; // for alignment
  857. NONCLIENTMETRICSW ncm;
  858. LOGFONTW lfIconTitle;
  859. COLORREF rgb[COLOR_MAX_95_NT4];
  860. } SCHEMEDATA_NT4;
  861. // Scheme data for Windows NT 5.0
  862. typedef struct {
  863. SHORT version;
  864. WORD wDummy; // for alignment
  865. NONCLIENTMETRICSW ncm;
  866. LOGFONTW lfIconTitle;
  867. COLORREF rgb[COLOR_MAX_97_NT5];
  868. } SCHEMEDATA_NT5;
  869. static SCHEMEDATALOCAL g_rgSchemeData[100]; // JMC: HACK - At Most 100 schemes
  870. static TCHAR g_rgSchemeNames[100][100];
  871. static int g_nSchemeCount = 0;
  872. static BOOL bSchemesAlreadyInit = FALSE;
  873. void Scheme_Init();
  874. int GetSchemeCount()
  875. {
  876. Scheme_Init();
  877. return g_nSchemeCount;
  878. }
  879. void GetSchemeName(int nIndex, LPTSTR lpszName, int nLen) // JMC: HACK - You must allocate enough space
  880. {
  881. Scheme_Init();
  882. _tcsncpy(lpszName, g_rgSchemeNames[i], nLen - 1);
  883. lpstName[nLen - 1] = 0; // Guarantee NULL termination
  884. }
  885. SCHEMEDATALOCAL &GetScheme(int nIndex)
  886. {
  887. Scheme_Init();
  888. return g_rgSchemeData[nIndex];
  889. }
  890. void Scheme_Init()
  891. {
  892. // Only do the stuff in this function once.
  893. if(bSchemesAlreadyInit)
  894. return;
  895. bSchemesAlreadyInit = TRUE;
  896. HKEY hkSchemes;
  897. DWORD dw, dwSize;
  898. TCHAR szBuf[100];
  899. g_nSchemeCount = 0;
  900. if (RegOpenKey(HKEY_CURRENT_USER, REGSTR_PATH_LOOKSCHEMES, &hkSchemes) != ERROR_SUCCESS)
  901. return;
  902. for (dw=0; ; dw++)
  903. {
  904. if(g_nSchemeCount>99)
  905. break; //JMC: HACK - At Most 100 schemes
  906. dwSize = ARRAYSIZE(szBuf);
  907. if (RegEnumValue(hkSchemes, dw, szBuf, &dwSize, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
  908. break; // Bail if no more values
  909. DWORD dwType;
  910. DWORD dwSize;
  911. RegQueryValueEx(hkSchemes, szBuf, NULL, &dwType, NULL, &dwSize);
  912. if(dwType == REG_BINARY)
  913. {
  914. // Always copy the current name to the name array - if there
  915. // is an error in the data, we just won't upcount g_nSchemeCount
  916. lstrcpy(g_rgSchemeNames[g_nSchemeCount], szBuf);
  917. // Find out which type of scheme this is, and convert to the
  918. // SCHEMEDATALOCAL type
  919. switch(dwSize)
  920. {
  921. case sizeof(SCHEMEDATA_95):
  922. {
  923. SCHEMEDATA_95 sd;
  924. RegQueryValueEx(hkSchemes, szBuf, NULL, &dwType, (BYTE *)&sd, &dwSize);
  925. if(1 != sd.version)
  926. break; // We have the wrong version even though the size was correct
  927. // Copy the color information from the registry info to g_rgSchemeData
  928. g_rgSchemeData[g_nSchemeCount].nColorsUsed = COLOR_MAX_95_NT4;
  929. // Copy the color array
  930. for(int i=0;i<g_rgSchemeData[g_nSchemeCount].nColorsUsed;i++)
  931. g_rgSchemeData[g_nSchemeCount].rgb[i] = sd.rgb[i];
  932. g_nSchemeCount++;
  933. }
  934. break;
  935. case sizeof(SCHEMEDATA_NT4):
  936. {
  937. SCHEMEDATA_NT4 sd;
  938. RegQueryValueEx(hkSchemes, szBuf, NULL, &dwType, (BYTE *)&sd, &dwSize);
  939. if(2 != sd.version)
  940. break; // We have the wrong version even though the size was correct
  941. // Copy the color information from the registry info to g_rgSchemeData
  942. g_rgSchemeData[g_nSchemeCount].nColorsUsed = COLOR_MAX_95_NT4;
  943. // Copy the color array
  944. for(int i=0;i<g_rgSchemeData[g_nSchemeCount].nColorsUsed;i++)
  945. g_rgSchemeData[g_nSchemeCount].rgb[i] = sd.rgb[i];
  946. g_nSchemeCount++;
  947. }
  948. break;
  949. case sizeof(SCHEMEDATA_97):
  950. {
  951. SCHEMEDATA_97 sd;
  952. RegQueryValueEx(hkSchemes, szBuf, NULL, &dwType, (BYTE *)&sd, &dwSize);
  953. if(3 != sd.version)
  954. break; // We have the wrong version even though the size was correct
  955. // Copy the color information from the registry info to g_rgSchemeData
  956. g_rgSchemeData[g_nSchemeCount].nColorsUsed = COLOR_MAX_97_NT5;
  957. // Copy the color array
  958. for(int i=0;i<g_rgSchemeData[g_nSchemeCount].nColorsUsed;i++)
  959. g_rgSchemeData[g_nSchemeCount].rgb[i] = sd.rgb[i];
  960. g_nSchemeCount++;
  961. }
  962. break;
  963. case sizeof(SCHEMEDATA_NT5):
  964. {
  965. SCHEMEDATA_NT5 sd;
  966. RegQueryValueEx(hkSchemes, szBuf, NULL, &dwType, (BYTE *)&sd, &dwSize);
  967. if(2 != sd.version)
  968. break; // We have the wrong version even though the size was correct
  969. // Copy the color information from the registry info to g_rgSchemeData
  970. g_rgSchemeData[g_nSchemeCount].nColorsUsed = COLOR_MAX_97_NT5;
  971. // Copy the color array
  972. for(int i=0;i<g_rgSchemeData[g_nSchemeCount].nColorsUsed;i++)
  973. g_rgSchemeData[g_nSchemeCount].rgb[i] = sd.rgb[i];
  974. g_nSchemeCount++;
  975. }
  976. break;
  977. default:
  978. // We had an unknown sized structure in the registry - IGNORE IT
  979. #ifdef _DEBUG
  980. TCHAR sz[200];
  981. wsprintf(sz, __TEXT("Scheme - %s, size = %i, sizeof(95) = %i, sizeof(NT4) = %i, sizeof(97) = %i, sizeof(NT5) = %i"), szBuf, dwSize,
  982. sizeof(SCHEMEDATA_95),
  983. sizeof(SCHEMEDATA_NT4),
  984. sizeof(SCHEMEDATA_97),
  985. sizeof(SCHEMEDATA_NT5)
  986. );
  987. MessageBox(NULL, sz, NULL, MB_OK);
  988. #endif // _DEBUG
  989. break;
  990. }
  991. }
  992. }
  993. RegCloseKey(hkSchemes);
  994. }
  995. #endif // READSCHEMESFROMREGISTRY
  996. void PORTABLE_NONCLIENTMETRICS::ApplyChanges() const
  997. {
  998. NONCLIENTMETRICS ncmOrig;
  999. LOGFONT lfIconOrig;
  1000. GetNonClientMetrics(&ncmOrig, &lfIconOrig);
  1001. NONCLIENTMETRICS ncmNew;
  1002. LOGFONT lfIconNew;
  1003. ZeroMemory(&ncmNew, sizeof(ncmNew));
  1004. ZeroMemory(&lfIconNew, sizeof(lfIconNew));
  1005. ncmNew.cbSize = sizeof(ncmNew);
  1006. ncmNew.iBorderWidth = m_iBorderWidth;
  1007. ncmNew.iScrollWidth = m_iScrollWidth;
  1008. ncmNew.iScrollHeight = m_iScrollHeight;
  1009. ncmNew.iCaptionWidth = m_iCaptionWidth;
  1010. ncmNew.iCaptionHeight = m_iCaptionHeight;
  1011. ncmNew.lfCaptionFont.lfHeight = m_lfCaptionFont_lfHeight;
  1012. ncmNew.lfCaptionFont.lfWeight = m_lfCaptionFont_lfWeight;
  1013. ncmNew.iSmCaptionWidth = m_iSmCaptionWidth;
  1014. ncmNew.iSmCaptionHeight = m_iSmCaptionHeight;
  1015. ncmNew.lfSmCaptionFont.lfHeight = m_lfSmCaptionFont_lfHeight;
  1016. ncmNew.lfSmCaptionFont.lfWeight = m_lfSmCaptionFont_lfWeight;
  1017. ncmNew.iMenuWidth = m_iMenuWidth;
  1018. ncmNew.iMenuHeight = m_iMenuHeight;
  1019. ncmNew.lfMenuFont.lfHeight = m_lfMenuFont_lfHeight;
  1020. ncmNew.lfMenuFont.lfWeight = m_lfMenuFont_lfWeight;
  1021. ncmNew.lfStatusFont.lfHeight = m_lfStatusFont_lfHeight;
  1022. ncmNew.lfStatusFont.lfWeight = m_lfStatusFont_lfWeight;
  1023. ncmNew.lfMessageFont.lfHeight = m_lfMessageFont_lfHeight;
  1024. ncmNew.lfMessageFont.lfWeight = m_lfMessageFont_lfWeight;
  1025. lfIconNew.lfHeight = m_lfIconWindowsDefault_lfHeight;
  1026. lfIconNew.lfWeight = m_lfIconWindowsDefault_lfWeight;
  1027. // Fill in fonts
  1028. if(m_nFontFaces)
  1029. {
  1030. TCHAR lfFaceName[LF_FACESIZE];
  1031. LoadString(g_hInstDll, IDS_SYSTEMFONTNAME, lfFaceName, ARRAYSIZE(lfFaceName));
  1032. BYTE lfCharSet;
  1033. TCHAR szCharSet[20];
  1034. if(LoadString(g_hInstDll,IDS_FONTCHARSET, szCharSet,sizeof(szCharSet)/sizeof(TCHAR))) {
  1035. lfCharSet = (BYTE)_tcstoul(szCharSet,NULL,10);
  1036. } else {
  1037. lfCharSet = 0; // Default
  1038. }
  1039. ncmNew.lfCaptionFont.lfCharSet = lfCharSet;
  1040. ncmNew.lfSmCaptionFont.lfCharSet = lfCharSet;
  1041. ncmNew.lfMenuFont.lfCharSet = lfCharSet;
  1042. ncmNew.lfStatusFont.lfCharSet = lfCharSet;
  1043. ncmNew.lfMessageFont.lfCharSet = lfCharSet;
  1044. lfIconNew.lfCharSet = lfCharSet;
  1045. lstrcpy(ncmNew.lfCaptionFont.lfFaceName, lfFaceName);
  1046. lstrcpy(ncmNew.lfSmCaptionFont.lfFaceName, lfFaceName);
  1047. lstrcpy(ncmNew.lfMenuFont.lfFaceName, lfFaceName);
  1048. lstrcpy(ncmNew.lfStatusFont.lfFaceName, lfFaceName);
  1049. lstrcpy(ncmNew.lfMessageFont.lfFaceName, lfFaceName);
  1050. lstrcpy(lfIconNew.lfFaceName, lfFaceName);
  1051. }
  1052. else
  1053. {
  1054. ncmNew.lfCaptionFont.lfCharSet = ncmOrig.lfCaptionFont.lfCharSet;
  1055. ncmNew.lfSmCaptionFont.lfCharSet = ncmOrig.lfSmCaptionFont.lfCharSet;
  1056. ncmNew.lfMenuFont.lfCharSet = ncmOrig.lfMenuFont.lfCharSet;
  1057. ncmNew.lfStatusFont.lfCharSet = ncmOrig.lfStatusFont.lfCharSet;
  1058. ncmNew.lfMessageFont.lfCharSet = ncmOrig.lfMessageFont.lfCharSet;
  1059. lfIconNew.lfCharSet = lfIconOrig.lfCharSet;
  1060. lstrcpy(ncmNew.lfCaptionFont.lfFaceName, ncmOrig.lfCaptionFont.lfFaceName);
  1061. lstrcpy(ncmNew.lfSmCaptionFont.lfFaceName, ncmOrig.lfSmCaptionFont.lfFaceName);
  1062. lstrcpy(ncmNew.lfMenuFont.lfFaceName, ncmOrig.lfMenuFont.lfFaceName);
  1063. lstrcpy(ncmNew.lfStatusFont.lfFaceName, ncmOrig.lfStatusFont.lfFaceName);
  1064. lstrcpy(ncmNew.lfMessageFont.lfFaceName, ncmOrig.lfMessageFont.lfFaceName);
  1065. lstrcpy(lfIconNew.lfFaceName, lfIconOrig.lfFaceName);
  1066. }
  1067. if(0 != memcmp(&ncmNew, &ncmOrig, sizeof(ncmOrig)))
  1068. SystemParametersInfo(SPI_SETNONCLIENTMETRICS, sizeof(ncmNew), (PVOID)&ncmNew, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
  1069. if(0 != memcmp(&lfIconNew, &lfIconOrig, sizeof(lfIconOrig)))
  1070. SystemParametersInfo(SPI_SETICONTITLELOGFONT, sizeof(lfIconNew), &lfIconNew, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
  1071. }
  1072. // Helpers for setting/getting numeric string reg entry
  1073. void WINAPI RegQueryStr(
  1074. LPTSTR lpDefault,
  1075. HKEY hkey,
  1076. LPTSTR lpSubKey,
  1077. LPTSTR lpValueName,
  1078. LPTSTR lpszValue,
  1079. DWORD cbData) // note this is bytes, not characters.
  1080. {
  1081. DWORD dwType;
  1082. lstrcpy(lpszValue, lpDefault);
  1083. if (ERROR_SUCCESS == RegOpenKeyEx(hkey, lpSubKey, 0, KEY_QUERY_VALUE, &hkey))
  1084. {
  1085. RegQueryValueEx(hkey, lpValueName, NULL, &dwType, (PBYTE) lpszValue, &cbData);
  1086. RegCloseKey(hkey);
  1087. }
  1088. }
  1089. BOOL RegSetStr(
  1090. HKEY hkey,
  1091. LPCTSTR lpSection,
  1092. LPCTSTR lpKeyName,
  1093. LPCTSTR lpString)
  1094. {
  1095. BOOL fRet = FALSE;
  1096. LONG lErr;
  1097. DWORD dwDisposition;
  1098. lErr = RegCreateKeyEx(
  1099. hkey,
  1100. lpSection,
  1101. 0,
  1102. NULL,
  1103. REG_OPTION_NON_VOLATILE,
  1104. KEY_SET_VALUE,
  1105. NULL,
  1106. &hkey,
  1107. &dwDisposition);
  1108. if (ERROR_SUCCESS == lErr)
  1109. {
  1110. if (NULL != lpString)
  1111. {
  1112. lErr = RegSetValueEx(
  1113. hkey,
  1114. lpKeyName,
  1115. 0,
  1116. REG_SZ,
  1117. (CONST BYTE *)lpString,
  1118. (lstrlen(lpString) + 1) * sizeof(*lpString));
  1119. }
  1120. else
  1121. {
  1122. lErr = RegSetValueEx(
  1123. hkey,
  1124. lpKeyName,
  1125. 0,
  1126. REG_SZ,
  1127. (CONST BYTE *)__TEXT(""),
  1128. 1 * sizeof(*lpString));
  1129. }
  1130. if (ERROR_SUCCESS == lErr)
  1131. {
  1132. fRet = TRUE;
  1133. }
  1134. RegCloseKey(hkey);
  1135. }
  1136. return(fRet);
  1137. }
  1138. DWORD WINAPI RegQueryStrDW(
  1139. DWORD dwDefault,
  1140. HKEY hkey,
  1141. LPTSTR lpSubKey,
  1142. LPTSTR lpValueName)
  1143. {
  1144. DWORD dwRet = dwDefault;
  1145. TCHAR szTemp[40];
  1146. TCHAR szDefault[40];
  1147. wsprintf(szDefault, TEXT("%d"), dwDefault);
  1148. RegQueryStr(szDefault, hkey, lpSubKey, lpValueName, szTemp, sizeof(szTemp));
  1149. dwRet = _ttol(szTemp);
  1150. return dwRet;
  1151. }
  1152. BOOL RegSetStrDW(HKEY hkey, LPTSTR lpSection, LPCTSTR lpKeyName, DWORD dwValue)
  1153. {
  1154. TCHAR szTemp[40];
  1155. wsprintf(szTemp, TEXT("%d"), dwValue);
  1156. return RegSetStr(hkey, lpSection, lpKeyName, szTemp);
  1157. }
  1158. //
  1159. /////////////////////////////////////////////////////////////////////