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.

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