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
1355 lines
48 KiB
//Copyright (c) 1997-2000 Microsoft Corporation
|
|
#include "pch.hxx" // pch
|
|
#pragma hdrstop
|
|
|
|
#include "Schemes.h"
|
|
#include <WININET.H>
|
|
#include <initguid.h>
|
|
#include <shlobj.h>
|
|
#include <objbase.h>
|
|
#include <shlguid.h>
|
|
#include <uxthemep.h>
|
|
#include "w95trace.h"
|
|
|
|
// To use the old way of enumerating fonts to get the font list,
|
|
// and reading schemes from the registry, remove the comments from
|
|
// the two lines below
|
|
//#define ENUMERATEFONTS
|
|
//#define READSCHEMESFROMREGISTRY
|
|
|
|
#define CPL_APPEARANCE_NEW_SCHEMES TEXT("Control Panel\\Appearance\\New Schemes")
|
|
#define NEW_SCHEMES_SELECTEDSTYLE TEXT("SelectedStyle")
|
|
#define NEW_SCHEMES_SELECTEDSIZE TEXT("SelectedSize")
|
|
#define HC_KEY TEXT("Control Panel\\Accessibility\\HighContrast")
|
|
#define HC_FLAGS TEXT("Flags")
|
|
#define PRE_HC_WALLPAPER TEXT("Pre-High Contrast Wallpaper")
|
|
#define SYSPARAMINFO(xxx) m_##xxx.cbSize = sizeof(m_##xxx);SystemParametersInfo(SPI_GET##xxx, sizeof(m_##xxx), &m_##xxx, 0)
|
|
|
|
//
|
|
// Helper functions
|
|
//
|
|
|
|
#define REG_SET_DWSZ(hk, key, dw) \
|
|
{ \
|
|
TCHAR szValue[20]; \
|
|
wsprintf(szValue, TEXT("%d"), dw); \
|
|
RegSetValueEx(hk, key, NULL, REG_SZ, (LPCBYTE)szValue, (lstrlen(szValue)+1)*sizeof(TCHAR)); \
|
|
}
|
|
|
|
void WIZSCHEME::ApplyChanges(const WIZSCHEME &schemeNew, NONCLIENTMETRICS *pForceNCM, LOGFONT *pForcelfIcon)
|
|
{
|
|
//
|
|
// If user has changed the color scheme then apply the new scheme. Since this is
|
|
// a high contrast scheme, also set the high contrast bit. We have to do this
|
|
// w/o using SystemParametersInfo(SPI_SETHIGHCONTRAST...) because that function
|
|
// also sets non-client metrics that accwiz must deal with separately from color.
|
|
//
|
|
|
|
BOOL fThemingOn = SetTheme(
|
|
schemeNew.m_szThemeName
|
|
, schemeNew.m_szThemeColor
|
|
, schemeNew.m_szThemeSize);
|
|
|
|
SetWallpaper(schemeNew.m_szWallpaper); // set wallpaper to new scheme's value
|
|
|
|
if (fThemingOn)
|
|
{
|
|
DBPRINTF(TEXT("ApplyChanges: Theming is being turned on\r\n"));
|
|
SetHCFlag(FALSE); // manually set high contrast flag off
|
|
|
|
// restore "flatmenu" and "dropshadows" settings
|
|
SystemParametersInfo(SPI_SETFLATMENU, 0, IntToPtr(schemeNew.m_fFlatMenus), SPIF_SENDCHANGE);
|
|
SystemParametersInfo(SPI_SETDROPSHADOW, 0, IntToPtr(schemeNew.m_fDropShadows), SPIF_SENDCHANGE);
|
|
}
|
|
else if (lstrcmpi(schemeNew.m_szSelectedStyle, m_szSelectedStyle))
|
|
{
|
|
DBPRINTF(TEXT("ApplyChanges: Theming is off or being turned off\r\n"));
|
|
// Setting a high contrast scheme
|
|
|
|
if (0 != memcmp(schemeNew.m_rgb, m_rgb, sizeof(m_rgb)))
|
|
{
|
|
SetHCFlag(TRUE); // first, manually set the high contrast flag
|
|
// (requires logoff/logon to take affect)
|
|
|
|
// reset "flatmenu" and "dropshadows" settings
|
|
SystemParametersInfo(SPI_SETFLATMENU, 0, IntToPtr(FALSE), SPIF_SENDCHANGE);
|
|
SystemParametersInfo(SPI_SETDROPSHADOW, 0, IntToPtr(FALSE), SPIF_SENDCHANGE);
|
|
|
|
// update the color scheme
|
|
int rgInts[COLOR_MAX_97_NT5]; // then set UI elements to selected color scheme
|
|
for(int i=0;i<COLOR_MAX_97_NT5;i++)
|
|
{
|
|
rgInts[i] = i;
|
|
}
|
|
|
|
SetSysColors(COLOR_MAX_97_NT5, rgInts, schemeNew.m_rgb);
|
|
|
|
// The following code updates the registry HKCU\Control Panel\Colors to
|
|
// reflect the new scheme so its available when the user logs on again
|
|
|
|
HKEY hk;
|
|
if (RegCreateKeyEx(HKEY_CURRENT_USER, szRegStr_Colors, 0,
|
|
TEXT(""), 0, KEY_SET_VALUE, NULL, &hk, NULL) == ERROR_SUCCESS)
|
|
{
|
|
TCHAR szRGB[32];
|
|
for (i = 0; i < COLOR_MAX_97_NT5; i++)
|
|
{
|
|
COLORREF rgb;
|
|
rgb = schemeNew.m_rgb[i];
|
|
wsprintf(szRGB, TEXT("%d %d %d"), GetRValue(rgb), GetGValue(rgb), GetBValue(rgb));
|
|
|
|
WriteProfileString(g_szColors, s_pszColorNames[i], szRGB); // update win.ini
|
|
RegSetValueEx(hk // update registry
|
|
, s_pszColorNames[i]
|
|
, 0L, REG_SZ
|
|
, (LPBYTE)szRGB
|
|
, sizeof(TCHAR) * (lstrlen(szRGB)+1));
|
|
}
|
|
|
|
RegCloseKey(hk);
|
|
}
|
|
|
|
// The W2K color schemes changed with WinXP. The old schemes (which we still use)
|
|
// are still there but display CPL uses a new method for selecting colors. These
|
|
// colors are under HKCU\Control Panel\Appearance\New Schemes. The "SelectedStyle"
|
|
// string value is the current scheme. The number (0 thru 21) corresponds to the
|
|
// order of the old colors under HKCU\Control Panel\Appearance\Schemes (excluding
|
|
// those schemes with (large) and (extra large)). The details for the scheme are
|
|
// subkeys (0 thru nn) under "New Schemes". In order for display CPL to show the
|
|
// correct current scheme after we've been run, we need to update "SelectedStyle"
|
|
// and "SelectedSize" (under the subkey specified in "SelectedStyle") with the
|
|
// correct index and size numbers. Display CPL uses a much more robust way of
|
|
// determining the legacy index but we only support four colors so we shouldn't
|
|
// need all the extra code.
|
|
|
|
if (RegOpenKeyEx(
|
|
HKEY_CURRENT_USER,
|
|
CPL_APPEARANCE_NEW_SCHEMES,
|
|
0, KEY_ALL_ACCESS,
|
|
&hk) == ERROR_SUCCESS)
|
|
{
|
|
long lRv = RegSetValueEx(
|
|
hk,
|
|
NEW_SCHEMES_SELECTEDSTYLE,
|
|
0, REG_SZ,
|
|
(LPCBYTE)schemeNew.m_szSelectedStyle,
|
|
(lstrlen(schemeNew.m_szSelectedStyle)+1)*sizeof(TCHAR));
|
|
|
|
RegCloseKey(hk);
|
|
|
|
// If we've changed color then the size must be updated for that scheme
|
|
UpdateSelectedSize(schemeNew.m_nSelectedSize, schemeNew.m_szSelectedStyle);
|
|
}
|
|
}
|
|
else if (schemeNew.m_nSelectedSize >= 0 && schemeNew.m_nSelectedSize != m_nSelectedSize)
|
|
{
|
|
// Also update size if it changed but the color scheme didn't
|
|
UpdateSelectedSize(schemeNew.m_nSelectedSize, schemeNew.m_szSelectedStyle);
|
|
}
|
|
}
|
|
//
|
|
// Apply any other changes
|
|
//
|
|
|
|
#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)
|
|
|
|
APPLY_SCHEME_CURRENT(FILTERKEYS);
|
|
APPLY_SCHEME_CURRENT(MOUSEKEYS);
|
|
APPLY_SCHEME_CURRENT(STICKYKEYS);
|
|
APPLY_SCHEME_CURRENT(TOGGLEKEYS);
|
|
APPLY_SCHEME_CURRENT(SOUNDSENTRY);
|
|
APPLY_SCHEME_CURRENT(ACCESSTIMEOUT);
|
|
// APPLY_SCHEME_CURRENT(SERIALKEYS);
|
|
|
|
// Check Show Sounds
|
|
if(schemeNew.m_bShowSounds != m_bShowSounds)
|
|
SystemParametersInfo(SPI_SETSHOWSOUNDS, schemeNew.m_bShowSounds, NULL, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
|
|
|
|
// Check Extra keyboard help
|
|
if(schemeNew.m_bShowExtraKeyboardHelp != m_bShowExtraKeyboardHelp)
|
|
{
|
|
// Both required:
|
|
SystemParametersInfo(SPI_SETKEYBOARDPREF, schemeNew.m_bShowExtraKeyboardHelp, NULL, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
|
|
SystemParametersInfo(SPI_SETKEYBOARDCUES, 0, IntToPtr(schemeNew.m_bShowExtraKeyboardHelp), SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
|
|
}
|
|
|
|
// Check swap mouse buttons
|
|
if(schemeNew.m_bSwapMouseButtons != m_bSwapMouseButtons)
|
|
SwapMouseButton(schemeNew.m_bSwapMouseButtons);
|
|
|
|
// Check Mouse Trails
|
|
if(schemeNew.m_nMouseTrails != m_nMouseTrails)
|
|
SystemParametersInfo(SPI_SETMOUSETRAILS, schemeNew.m_nMouseTrails, NULL, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
|
|
|
|
// Check Mouse Speed
|
|
if(schemeNew.m_nMouseSpeed != m_nMouseSpeed)
|
|
SystemParametersInfo(SPI_SETMOUSESPEED, 0, IntToPtr(schemeNew.m_nMouseSpeed), SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
|
|
|
|
// Reset cursor width and blink time
|
|
if (schemeNew.m_dwCaretWidth != m_dwCaretWidth)
|
|
SystemParametersInfo(SPI_SETCARETWIDTH, 0, IntToPtr(schemeNew.m_dwCaretWidth), SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
|
|
|
|
if (schemeNew.m_uCursorBlinkTime != m_uCursorBlinkTime)
|
|
{
|
|
// Set the blink rate for this session
|
|
SetCaretBlinkTime(schemeNew.m_uCursorBlinkTime);
|
|
|
|
// and persist it to the registry
|
|
RegSetStrDW(HKEY_CURRENT_USER, CONTROL_PANEL_DESKTOP, CURSOR_BLINK_RATE, schemeNew.m_uCursorBlinkTime);
|
|
}
|
|
|
|
// Check icon size
|
|
if(schemeNew.m_nIconSize != m_nIconSize)
|
|
WIZSCHEME::SetShellLargeIconSize(schemeNew.m_nIconSize);
|
|
|
|
// Check cursor scheme
|
|
if(schemeNew.m_nCursorScheme != m_nCursorScheme)
|
|
ApplyCursorScheme(schemeNew.m_nCursorScheme);
|
|
|
|
// NonClientMetric changes
|
|
{
|
|
NONCLIENTMETRICS ncmOrig;
|
|
LOGFONT lfOrig;
|
|
GetNonClientMetrics(&ncmOrig, &lfOrig);
|
|
if(pForceNCM)
|
|
{
|
|
// If they gave us a NCM, they must also give us a LOGFONT for the icon
|
|
_ASSERTE(pForcelfIcon);
|
|
// We were given an Original NCM to use
|
|
if(0 != memcmp(pForceNCM, &ncmOrig, sizeof(ncmOrig)))
|
|
SystemParametersInfo(SPI_SETNONCLIENTMETRICS, sizeof(*pForceNCM), pForceNCM, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
|
|
if(0 != memcmp(pForcelfIcon, &lfOrig, sizeof(lfOrig)))
|
|
SystemParametersInfo(SPI_SETICONTITLELOGFONT, sizeof(*pForcelfIcon), pForcelfIcon, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
|
|
}
|
|
else
|
|
{
|
|
// Note: This part of apply changes does not look at schemeCurrent - it only looks
|
|
// at what we are applying
|
|
schemeNew.m_PortableNonClientMetrics.ApplyChanges();
|
|
}
|
|
}
|
|
|
|
|
|
*this = schemeNew;
|
|
}
|
|
|
|
// Set the high contrast flag on or off based on fSet
|
|
void WIZSCHEME::SetHCFlag(BOOL fSetOn)
|
|
{
|
|
//
|
|
// This key is cached in the OS so setting it outside of
|
|
// SystemParametersInfo(SPI_SETHIGHCONTRAST doesn't take
|
|
// effect until the user logs off and on again. Is there
|
|
// a way to cause the cache to be refreshed?
|
|
//
|
|
HKEY hk;
|
|
if (RegOpenKeyEx(HKEY_CURRENT_USER, HC_KEY, 0, KEY_ALL_ACCESS, &hk) == ERROR_SUCCESS)
|
|
{
|
|
TCHAR szValue[20];
|
|
DWORD dwSize = sizeof(szValue);
|
|
ZeroMemory(szValue, dwSize);
|
|
|
|
if (RegQueryValueEx(hk, HC_FLAGS, NULL, NULL, (LPBYTE)szValue, &dwSize) == ERROR_SUCCESS)
|
|
{
|
|
szValue[ARRAYSIZE(szValue)-1] = TEXT('\0'); // ensure NUL termination
|
|
DWORD dwValue = _ttol(szValue);
|
|
|
|
if (fSetOn && !(dwValue & HCF_HIGHCONTRASTON))
|
|
{
|
|
dwValue |= HCF_HIGHCONTRASTON;
|
|
REG_SET_DWSZ(hk, HC_FLAGS, dwValue)
|
|
}
|
|
else if (!fSetOn && (dwValue & HCF_HIGHCONTRASTON))
|
|
{
|
|
dwValue &= ~HCF_HIGHCONTRASTON;
|
|
REG_SET_DWSZ(hk, HC_FLAGS, dwValue)
|
|
}
|
|
}
|
|
RegCloseKey(hk);
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
* SaveWallpaper
|
|
*
|
|
* Saves the current wallpaper setting from the system.
|
|
*
|
|
* ISSUE we aren't getting all the active desktop properties; just wallpaper.
|
|
* This isn't a regression in that we didn't even restore wallpaper in W2K.
|
|
*
|
|
***************************************************************************/
|
|
void WIZSCHEME::SaveWallpaper()
|
|
{
|
|
IActiveDesktop *p;
|
|
HRESULT hr = CoCreateInstance(
|
|
CLSID_ActiveDesktop
|
|
, NULL
|
|
, CLSCTX_INPROC_SERVER
|
|
, IID_IActiveDesktop
|
|
, (void **)&p);
|
|
if (SUCCEEDED(hr) && p)
|
|
{
|
|
hr = p->GetWallpaper(m_szWallpaper, MAX_THEME_SZ, 0);
|
|
p->Release();
|
|
}
|
|
DBPRINTF(TEXT("SaveWallpaper: m_szWallpaper = %s (hr = 0x%x)\r\n"), m_szWallpaper, hr);
|
|
}
|
|
|
|
/***************************************************************************
|
|
* SetWallpaper
|
|
*
|
|
* Restores the pre-high contrast wallpaper setting. Reads the setting
|
|
* stored in the accessibility registry entries and restores the system
|
|
* setting. No error return as there isn't anything we can do.
|
|
*
|
|
***************************************************************************/
|
|
void WIZSCHEME::SetWallpaper(LPCTSTR pszWallpaper)
|
|
{
|
|
if (lstrcmpi(m_szWallpaper, pszWallpaper))
|
|
{
|
|
IActiveDesktop *p;
|
|
LPCTSTR psz = (pszWallpaper)?pszWallpaper:TEXT("");
|
|
|
|
HRESULT hr = CoCreateInstance(
|
|
CLSID_ActiveDesktop
|
|
, NULL
|
|
, CLSCTX_INPROC_SERVER
|
|
, IID_IActiveDesktop
|
|
, (void **)&p);
|
|
if (SUCCEEDED(hr) && p)
|
|
{
|
|
hr = p->SetWallpaper(psz, 0);
|
|
if (SUCCEEDED(hr))
|
|
p->ApplyChanges(AD_APPLY_ALL);
|
|
|
|
p->Release();
|
|
}
|
|
DBPRINTF(TEXT("SetWallpaper: psz = %s (hr = 0x%x)\r\n"), psz, hr);
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
* SaveTheme
|
|
*
|
|
* Saves the theme file settings that are active before accwiz was run.
|
|
*
|
|
***************************************************************************/
|
|
void WIZSCHEME::SaveTheme()
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
if (IsThemeActive())
|
|
{
|
|
hr = GetCurrentThemeName(
|
|
m_szThemeName, MAX_THEME_SZ
|
|
, m_szThemeColor, MAX_THEME_SZ
|
|
, m_szThemeSize, MAX_THEME_SZ);
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
// themes is not turned on
|
|
m_szThemeName[0] = 0;
|
|
m_szThemeColor[0] = 0;
|
|
m_szThemeSize[0] = 0;
|
|
}
|
|
|
|
//---- save off "flatmenu" and "dropshadows" settings ---
|
|
SystemParametersInfo(SPI_GETFLATMENU, 0, (PVOID)&m_fFlatMenus, 0);
|
|
SystemParametersInfo(SPI_GETDROPSHADOW, 0, (PVOID)&m_fDropShadows, 0);
|
|
|
|
DBPRINTF(TEXT("SaveTheme: m_szThemeName = %s m_szThemeColor = %s m_szThemeSize = %s (hr = 0x%x)\r\n"), m_szThemeName, m_szThemeColor, m_szThemeSize, hr);
|
|
}
|
|
|
|
/***************************************************************************
|
|
* SetTheme
|
|
*
|
|
* If a theme name, color and size is passed then sets it
|
|
* else turns off theming.
|
|
*
|
|
* Returns TRUE if a theme was set else FALSE it themes were turned off.
|
|
*
|
|
***************************************************************************/
|
|
BOOL WIZSCHEME::SetTheme(LPCTSTR pszThemeName, LPCTSTR pszThemeColor, LPCTSTR pszThemeSize)
|
|
{
|
|
BOOL fRet = FALSE; // didn't turn themes on
|
|
|
|
// only attempt to do anything if the new theme differs from current
|
|
if ( lstrcmpi(m_szThemeName, pszThemeName)
|
|
|| lstrcmpi(m_szThemeColor, pszThemeColor)
|
|
|| lstrcmpi(m_szThemeSize, pszThemeSize) )
|
|
{
|
|
HRESULT hr;
|
|
if (pszThemeName[0] && pszThemeColor[0] && pszThemeSize[0])
|
|
{
|
|
hr = SetSystemVisualStyle(pszThemeName, pszThemeColor, pszThemeSize,
|
|
AT_LOAD_SYSMETRICS | AT_SYNC_LOADMETRICS);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
fRet = TRUE; // turned themes on
|
|
}
|
|
DBPRINTF(TEXT("SetTheme: pszThemeName = %s pszThemeColor = %s pszThemeSize = %s(hr = 0x%x)\r\n"), pszThemeName, pszThemeColor, pszThemeSize, hr);
|
|
}
|
|
else if (IsThemeActive())
|
|
{
|
|
hr = ApplyTheme(NULL, 0, NULL);
|
|
DBPRINTF(TEXT("SetTheme: Themes are now off hr = 0x%x\r\n"), hr);
|
|
}
|
|
}
|
|
|
|
return fRet;
|
|
}
|
|
|
|
/***************************************************************************
|
|
* UpdateSelectedSize
|
|
*
|
|
* Updates the SelectedSize under a "New Scheme" entry.
|
|
*
|
|
* NOTE: AccWiz doesn't use the font metrics from the registry so
|
|
* it doesn't actually give fonts that are "normal", "large"
|
|
* and "extra large" as display and access CPLs know them.
|
|
* The closest sizes are "normal" and "large".
|
|
*
|
|
***************************************************************************/
|
|
void WIZSCHEME::UpdateSelectedSize(int nSelectedSize, LPCTSTR pszSelectedStyle)
|
|
{
|
|
LPTSTR pszSelectedSize;
|
|
LPTSTR aszSelectedSizes[] = {TEXT("0")/*normal*/, TEXT("2")/*large*/, TEXT("1")/*extra large*/};
|
|
|
|
switch (nSelectedSize)
|
|
{
|
|
case 0: pszSelectedSize = aszSelectedSizes[0]; break; // normal text size
|
|
case 1: pszSelectedSize = aszSelectedSizes[0]; break; // normal text size
|
|
case 2: pszSelectedSize = aszSelectedSizes[1]; break; // large text size
|
|
default: pszSelectedSize = 0; break;
|
|
}
|
|
|
|
if (pszSelectedSize)
|
|
{
|
|
HKEY hk;
|
|
if (RegOpenKeyEx(HKEY_CURRENT_USER,
|
|
CPL_APPEARANCE_NEW_SCHEMES,
|
|
0, KEY_ALL_ACCESS,
|
|
&hk) == ERROR_SUCCESS)
|
|
{
|
|
HKEY hkSub;
|
|
if (RegOpenKeyEx(hk, pszSelectedStyle, 0, KEY_ALL_ACCESS, &hkSub) == ERROR_SUCCESS)
|
|
{
|
|
RegSetValueEx(hkSub,
|
|
NEW_SCHEMES_SELECTEDSIZE,
|
|
0, REG_SZ,
|
|
(LPCBYTE)pszSelectedSize,
|
|
(lstrlen(pszSelectedSize)+1)*sizeof(TCHAR));
|
|
|
|
RegCloseKey(hkSub);
|
|
}
|
|
|
|
RegCloseKey(hk);
|
|
}
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
* SetStyleNSize
|
|
*
|
|
* Helper for legacy schemes - figures out SelectedStyle and SelectedSize
|
|
* from the legacy scheme's data.
|
|
*
|
|
***************************************************************************/
|
|
void WIZSCHEME::SetStyleNSize()
|
|
{
|
|
int cStdSchemes = GetSchemeCount();
|
|
int i;
|
|
|
|
// Init the fields this function will be setting
|
|
|
|
m_szSelectedStyle[0] = 0;
|
|
m_nSelectedSize = 0;
|
|
|
|
// Figure out the SelectedStyle by finding the best-match for
|
|
// colors between what accwiz supports now and what it had in
|
|
// previous versions. After finding the best match, copy the
|
|
// latest colors in; this fixes some bugs with old colors.
|
|
|
|
SCHEMEDATALOCAL sdlTemp;
|
|
int iBestColorFit = -1; // guarrantee we'll find one
|
|
int cBestMatch = 0;
|
|
|
|
for (i=0;i<cStdSchemes;i++)
|
|
{
|
|
int cMatches = 0;
|
|
sdlTemp = GetScheme(i);
|
|
|
|
// assumption: sizeof(m_rgb) > sizeof(sdlTemp.rgb)
|
|
for (int cColor = 0;cColor < sdlTemp.nColorsUsed; cColor++)
|
|
{
|
|
if (sdlTemp.rgb[cColor] == m_rgb[cColor])
|
|
{
|
|
cMatches++;
|
|
}
|
|
}
|
|
|
|
if (cBestMatch < cMatches)
|
|
{
|
|
iBestColorFit = i;
|
|
cBestMatch = cMatches;
|
|
}
|
|
|
|
// if its an exact match just use it
|
|
if (cMatches == sdlTemp.nColorsUsed)
|
|
break;
|
|
}
|
|
|
|
// load up the SelectedStyle
|
|
sdlTemp = GetScheme(iBestColorFit);
|
|
LoadString(g_hInstDll, sdlTemp.nNameStringId+100
|
|
, m_szSelectedStyle
|
|
, ARRAYSIZE(m_szSelectedStyle));
|
|
|
|
// fix up any color problems
|
|
memcpy(m_rgb, sdlTemp.rgb, sizeof(sdlTemp.rgb));
|
|
|
|
// Figure out the SelectedSize based on reverse-compute minimum
|
|
// font size and hard-coded limits from the Welcome page
|
|
|
|
HDC hDC = GetDC(NULL);
|
|
if (hDC)
|
|
{
|
|
long lMinFontSize = ((-m_PortableNonClientMetrics.m_lfCaptionFont_lfHeight)*72)/GetDeviceCaps(hDC, LOGPIXELSY);
|
|
ReleaseDC(NULL, hDC);
|
|
|
|
if (lMinFontSize <=9)
|
|
{
|
|
m_nSelectedSize = 0;
|
|
}
|
|
else if (lMinFontSize <=12)
|
|
{
|
|
m_nSelectedSize = 1;
|
|
}
|
|
else if (lMinFontSize <=16)
|
|
{
|
|
m_nSelectedSize = 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
void WIZSCHEME::LoadOriginal()
|
|
{
|
|
DBPRINTF(TEXT("LoadOriginal\r\n"));
|
|
//
|
|
// Save off current UI element colors, theme information, and wallpaper setting
|
|
//
|
|
|
|
for(int i=0;i<COLOR_MAX_97_NT5;i++)
|
|
m_rgb[i] = GetSysColor(i);
|
|
|
|
SaveTheme();
|
|
SaveWallpaper();
|
|
|
|
//
|
|
// Save off the rest of the UI settings
|
|
//
|
|
|
|
SYSPARAMINFO(FILTERKEYS);
|
|
SYSPARAMINFO(MOUSEKEYS);
|
|
SYSPARAMINFO(STICKYKEYS);
|
|
SYSPARAMINFO(TOGGLEKEYS);
|
|
SYSPARAMINFO(SOUNDSENTRY);
|
|
SYSPARAMINFO(ACCESSTIMEOUT);
|
|
|
|
m_bShowSounds = GetSystemMetrics(SM_SHOWSOUNDS);
|
|
SystemParametersInfo(SPI_GETKEYBOARDPREF, 0, &m_bShowExtraKeyboardHelp, 0);
|
|
m_bSwapMouseButtons = GetSystemMetrics(SM_SWAPBUTTON);
|
|
SystemParametersInfo(SPI_GETMOUSETRAILS, 0, &m_nMouseTrails, 0);
|
|
SystemParametersInfo(SPI_GETMOUSESPEED,0, &m_nMouseSpeed, 0);
|
|
SystemParametersInfo(SPI_GETCARETWIDTH, 0 , &m_dwCaretWidth, 0);
|
|
m_uCursorBlinkTime = RegQueryStrDW(
|
|
DEFAULT_BLINK_RATE
|
|
, HKEY_CURRENT_USER
|
|
, CONTROL_PANEL_DESKTOP
|
|
, CURSOR_BLINK_RATE);
|
|
m_nIconSize = SetShellLargeIconSize(0); // This just gets the current size
|
|
m_nCursorScheme = 0; // We are always using the 'current' cursor scheme =)
|
|
|
|
m_PortableNonClientMetrics.LoadOriginal();
|
|
|
|
// Save off current "New Schemes" settings if we aren't themed
|
|
|
|
if (IsThemeActive())
|
|
{
|
|
LoadString(g_hInstDll, IDS_SCHEME_CURRENTCOLORSCHEME+100, m_szSelectedStyle, MAX_NUM_SZ);
|
|
m_nSelectedSize = 0;
|
|
}
|
|
else
|
|
{
|
|
HKEY hk;
|
|
if (RegOpenKeyEx(HKEY_CURRENT_USER, CPL_APPEARANCE_NEW_SCHEMES, 0, KEY_READ, &hk) == ERROR_SUCCESS)
|
|
{
|
|
DWORD ccb = sizeof(m_szSelectedStyle);
|
|
m_szSelectedStyle[0] = 0;
|
|
if (RegQueryValueEx(hk, NEW_SCHEMES_SELECTEDSTYLE, 0, NULL, (LPBYTE)m_szSelectedStyle, &ccb) == ERROR_SUCCESS && ccb > 2)
|
|
{
|
|
HKEY hkSub;
|
|
m_szSelectedStyle[ARRAYSIZE(m_szSelectedStyle)-1] = TEXT('\0');
|
|
if (RegOpenKeyEx(hk, m_szSelectedStyle, 0, KEY_READ, &hkSub) == ERROR_SUCCESS)
|
|
{
|
|
TCHAR szSize[MAX_NUM_SZ] = {0};
|
|
ccb = sizeof(szSize);
|
|
DBPRINTF(TEXT("RegQueryValueEx(NEW_SCHEMES_SELECTEDSIZE=%s,,,ccb=%d)\r\n"), NEW_SCHEMES_SELECTEDSIZE, ccb);
|
|
ZeroMemory(szSize,sizeof szSize);
|
|
RegQueryValueEx(hkSub, NEW_SCHEMES_SELECTEDSIZE, 0, NULL, (LPBYTE)szSize, &ccb);
|
|
szSize[ARRAYSIZE(szSize)-1] = TEXT('\0');
|
|
|
|
m_nSelectedSize = (szSize[0] && ccb > 2) ? _wtoi(szSize) : -1;
|
|
DBPRINTF(TEXT("szSize=%d ccb=%d m_nSelectedSize=%d\r\n"), szSize, ccb, m_nSelectedSize);
|
|
RegCloseKey(hkSub);
|
|
}
|
|
}
|
|
RegCloseKey(hk);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// New way of enumerating fonts
|
|
|
|
#ifndef ENUMERATEFONTS
|
|
|
|
static LPCTSTR g_lpszFontNames[] =
|
|
{
|
|
__TEXT("Arial"),
|
|
__TEXT("MS Sans Serif"),
|
|
__TEXT("Tahoma"),
|
|
__TEXT("Times New Roman")
|
|
};
|
|
|
|
int GetFontCount()
|
|
{
|
|
return ARRAYSIZE(g_lpszFontNames);
|
|
}
|
|
|
|
void GetFontLogFont(int nIndex, LOGFONT *pLogFont)
|
|
{
|
|
_ASSERTE(nIndex < ARRAYSIZE(g_lpszFontNames));
|
|
memset(pLogFont, 0, sizeof(*pLogFont));
|
|
lstrcpy(pLogFont->lfFaceName, g_lpszFontNames[nIndex]);
|
|
}
|
|
|
|
|
|
#endif // ENUMERATEFONTS
|
|
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// New way of storing schemes as hard coded values
|
|
|
|
// CONSIDER - this isn't a very robust way to do this; see sethc
|
|
|
|
#ifndef READSCHEMESFROMREGISTRY
|
|
|
|
#include "resource.h"
|
|
|
|
static SCHEMEDATALOCAL g_rgSchemeData[] =
|
|
{
|
|
{
|
|
IDS_SCHEME_HIGHCONTRASTBLACKALTERNATE,
|
|
{NULL},
|
|
#if(WINVER >= 0x0501)
|
|
31,
|
|
#elif(WINVER == 0x0500)
|
|
29,
|
|
#else
|
|
25,
|
|
#endif
|
|
{
|
|
RGB( 0, 0, 0), // Scrollbar
|
|
RGB( 0, 0, 0), // Background
|
|
RGB( 0, 0, 255), // ActiveTitle
|
|
RGB( 0, 255, 255), // InactiveTitle
|
|
RGB( 0, 0, 0), // Menu
|
|
RGB( 0, 0, 0), // Window
|
|
RGB(255, 255, 255), // WindowFrame
|
|
RGB(255, 255, 255), // MenuText
|
|
RGB(255, 255, 0), // WindowText
|
|
RGB(255, 255, 255), // TitleText
|
|
RGB( 0, 0, 255), // ActiveBorder
|
|
RGB( 0, 255, 255), // InactiveBorder
|
|
RGB( 0, 0, 0), // AppWorkspace
|
|
RGB( 0, 128, 0), // Hilight
|
|
RGB(255, 255, 255), // HilightText
|
|
RGB( 0, 0, 0), // ButtonFace
|
|
RGB(128, 128, 128), // ButtonShadow
|
|
RGB( 0, 255, 0), // GrayText
|
|
RGB(255, 255, 255), // ButtonText
|
|
RGB( 0, 0, 0), // InactiveTitleText
|
|
RGB(192, 192, 192), // ButtonHilight
|
|
RGB(255, 255, 255), // ButtonDkShadow
|
|
RGB(255, 255, 255), // ButtonLight
|
|
RGB(255, 255, 0), // InfoText
|
|
RGB( 0, 0, 0), // InfoWindow
|
|
#if(WINVER >= 0x0500)
|
|
RGB(192, 192, 192), // ButtonAlternateFace
|
|
RGB(128, 0, 128), // HotTrackingColor
|
|
RGB( 0, 0, 255), // GradientActiveTitle
|
|
RGB( 0, 255, 255), // GradientInactiveTitle
|
|
#if(WINVER >= 0x0501)
|
|
RGB(128, 0, 128), // MenuHighlighted
|
|
RGB( 0, 0, 0) // MenuBar
|
|
#endif /* WINVER >= 0x0501 */
|
|
#endif /* WINVER >= 0x0500 */
|
|
}
|
|
},
|
|
{
|
|
IDS_SCHEME_HIGHCONTRASTWHITEALTERNATE,
|
|
{NULL},
|
|
#if(WINVER >= 0x0501)
|
|
31,
|
|
#elif(WINVER == 0x0500)
|
|
29,
|
|
#else
|
|
25,
|
|
#endif
|
|
{
|
|
RGB( 0, 0, 0), // Scrollbar
|
|
RGB( 0, 0, 0), // Background
|
|
RGB( 0, 255, 255), // ActiveTitle
|
|
RGB( 0, 0, 255), // InactiveTitle
|
|
RGB( 0, 0, 0), // Menu
|
|
RGB( 0, 0, 0), // Window
|
|
RGB(255, 255, 255), // WindowFrame
|
|
RGB( 0, 255, 0), // MenuText
|
|
RGB( 0, 255, 0), // WindowText
|
|
RGB( 0, 0, 0), // TitleText
|
|
RGB( 0, 255, 255), // ActiveBorder
|
|
RGB( 0, 0, 255), // InactiveBorder
|
|
RGB(255, 251, 240), // AppWorkspace
|
|
RGB( 0, 0, 255), // Hilight
|
|
RGB(255, 255, 255), // HilightText
|
|
RGB( 0, 0, 0), // ButtonFace
|
|
RGB(128, 128, 128), // ButtonShadow
|
|
RGB( 0, 255, 0), // GrayText
|
|
RGB( 0, 255, 0), // ButtonText
|
|
RGB(255, 255, 255), // InactiveTitleText
|
|
RGB(192, 192, 192), // ButtonHilight
|
|
RGB(255, 255, 255), // ButtonDkShadow
|
|
RGB(255, 255, 255), // ButtonLight
|
|
RGB( 0, 0, 0), // InfoText
|
|
RGB(255, 255, 0), // InfoWindow
|
|
#if(WINVER >= 0x0500)
|
|
RGB(192, 192, 192), // ButtonAlternateFace
|
|
RGB(128, 0, 128), // HotTrackingColor
|
|
RGB( 0, 255, 255), // GradientActiveTitle
|
|
RGB( 0, 0, 255), // GradientInactiveTitle
|
|
#if(WINVER >= 0x0501)
|
|
RGB(128, 0, 128), // MenuHighlighted
|
|
RGB( 0, 0, 0) // MenuBar
|
|
#endif /* WINVER >= 0x0501 */
|
|
#endif /* WINVER >= 0x0500 */
|
|
}
|
|
},
|
|
{
|
|
IDS_SCHEME_HIGHCONTRASTBLACK,
|
|
{NULL},
|
|
#if(WINVER >= 0x0501)
|
|
31,
|
|
#elif(WINVER == 0x0500)
|
|
29,
|
|
#else
|
|
25,
|
|
#endif
|
|
{
|
|
RGB( 0, 0, 0), // Scrollbar
|
|
RGB( 0, 0, 0), // Background
|
|
RGB(128, 0, 128), // ActiveTitle
|
|
RGB( 0, 128, 0), // InactiveTitle
|
|
RGB( 0, 0, 0), // Menu
|
|
RGB( 0, 0, 0), // Window
|
|
RGB(255, 255, 255), // WindowFrame
|
|
RGB(255, 255, 255), // MenuText
|
|
RGB(255, 255, 255), // WindowText
|
|
RGB(255, 255, 255), // TitleText
|
|
RGB(255, 255, 0), // ActiveBorder
|
|
RGB( 0, 128, 0), // InactiveBorder
|
|
RGB( 0, 0, 0), // AppWorkspace
|
|
RGB(128, 0, 128), // Hilight
|
|
RGB(255, 255, 255), // HilightText
|
|
RGB( 0, 0, 0), // ButtonFace
|
|
RGB(128, 128, 128), // ButtonShadow
|
|
RGB( 0, 255, 0), // GrayText
|
|
RGB(255, 255, 255), // ButtonText
|
|
RGB(255, 255, 255), // InactiveTitleText
|
|
RGB(192, 192, 192), // ButtonHilight
|
|
RGB(255, 255, 255), // ButtonDkShadow
|
|
RGB(255, 255, 255), // ButtonLight
|
|
RGB(255, 255, 255), // InfoText
|
|
RGB( 0, 0, 0), // InfoWindow
|
|
#if(WINVER >= 0x0500)
|
|
RGB(192, 192, 192), // ButtonAlternateFace
|
|
RGB(128, 0, 128), // HotTrackingColor
|
|
RGB(128, 0, 128), // GradientActiveTitle
|
|
RGB( 0, 128, 0), // GradientInactiveTitle
|
|
#if(WINVER >= 0x0501)
|
|
RGB(128, 0, 128), // MenuHighlighted
|
|
RGB( 0, 0, 0) // MenuBar
|
|
#endif /* WINVER >= 0x0501 */
|
|
#endif /* WINVER >= 0x0500 */
|
|
}
|
|
},
|
|
{
|
|
IDS_SCHEME_HIGHCONTRASTWHITE,
|
|
{NULL},
|
|
#if(WINVER >= 0x0501)
|
|
31,
|
|
#elif(WINVER == 0x0500)
|
|
29,
|
|
#else
|
|
25,
|
|
#endif
|
|
{
|
|
RGB(255, 255, 255), // Scrollbar
|
|
RGB(255, 255, 255), // Background
|
|
RGB( 0, 0, 0), // ActiveTitle
|
|
RGB(255, 255, 255), // InactiveTitle
|
|
RGB(255, 255, 255), // Menu
|
|
RGB(255, 255, 255), // Window
|
|
RGB( 0, 0, 0), // WindowFrame
|
|
RGB( 0, 0, 0), // MenuText (enabled menu text FlatMenuMode = TRUE)
|
|
RGB( 0, 0, 0), // WindowText
|
|
RGB(255, 255, 255), // TitleText
|
|
RGB(128, 128, 128), // ActiveBorder
|
|
RGB(192, 192, 192), // InactiveBorder
|
|
RGB(128, 128, 128), // AppWorkspace
|
|
RGB( 0, 0, 0), // Hilight (and enabled menu highlighted background FlatMenuMode = FALSE)
|
|
RGB(255, 255, 255), // HilightText (and menu highlighted text FlatMenuMode = FALSE)
|
|
RGB(255, 255, 255), // ButtonFace
|
|
RGB(128, 128, 128), // ButtonShadow
|
|
RGB( 0, 255, 0), // GrayText (disabled menu text highlighted = green)
|
|
RGB( 0, 0, 0), // ButtonText
|
|
RGB( 0, 0, 0), // InactiveTitleText
|
|
RGB(192, 192, 192), // ButtonHilight (disabled menu text = grey)
|
|
RGB( 0, 0, 0), // ButtonDkShadow
|
|
RGB(192, 192, 192), // ButtonLight
|
|
RGB( 0, 0, 0), // InfoText
|
|
RGB(255, 255, 255), // InfoWindow
|
|
#if(WINVER >= 0x0500)
|
|
RGB(192, 192, 192), // ButtonAlternateFace
|
|
RGB( 0, 0, 0), // HotTrackingColor
|
|
RGB( 0, 0, 0), // GradientActiveTitle
|
|
RGB(255, 255, 255), // GradientInactiveTitle
|
|
#if(WINVER >= 0x0501)
|
|
RGB( 0, 0, 0), // MenuHighlighted (enabled menu highlighted background FlatMenuMode = TRUE)
|
|
RGB(255, 255, 255) // MenuBar
|
|
#endif /* WINVER >= 0x0501 */
|
|
#endif /* WINVER >= 0x0500 */
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
int GetSchemeCount()
|
|
{
|
|
return ARRAYSIZE(g_rgSchemeData);
|
|
}
|
|
|
|
// GetSchemeName is only called to initialize the color scheme list box
|
|
void GetSchemeName(int nIndex, LPTSTR lpszName, int nLen) // JMC: HACK - You must allocate enough space
|
|
{
|
|
_ASSERTE(nIndex < ARRAYSIZE(g_rgSchemeData));
|
|
LoadString(g_hInstDll, g_rgSchemeData[nIndex].nNameStringId, lpszName, nLen); // return the name
|
|
LoadString(g_hInstDll, g_rgSchemeData[nIndex].nNameStringId+100
|
|
, g_rgSchemeData[nIndex].szNameIndexId
|
|
, ARRAYSIZE(g_rgSchemeData[nIndex].szNameIndexId)); // get the "SelectedStyle" index
|
|
}
|
|
|
|
SCHEMEDATALOCAL &GetScheme(int nIndex)
|
|
{
|
|
_ASSERTE(nIndex < ARRAYSIZE(g_rgSchemeData));
|
|
return g_rgSchemeData[nIndex];
|
|
}
|
|
|
|
|
|
#endif // READSCHEMESFROMREGISTRY
|
|
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// Below this point in the file, we have the old way we use
|
|
// to enumerate fonts and schemes.
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// Old way of enumerating fonts
|
|
#ifdef ENUMERATEFONTS
|
|
|
|
// Global Variables
|
|
static ENUMLOGFONTEX g_rgFonts[200]; // JMC: HACK - At Most 200 Fonts
|
|
static int g_nFontCount = 0;
|
|
static BOOL bFontsAlreadyInit = FALSE;
|
|
|
|
void Font_Init();
|
|
|
|
int GetFontCount()
|
|
{
|
|
if(!bFontsAlreadyInit)
|
|
Font_Init();
|
|
return g_nFontCount;
|
|
}
|
|
|
|
void GetFontLogFont(int nIndex, LOGFONT *pLogFont)
|
|
{
|
|
if(!bFontsAlreadyInit)
|
|
Font_Init();
|
|
*pLogFont = g_rgFonts[nIndex].elfLogFont;
|
|
}
|
|
|
|
|
|
int CALLBACK EnumFontFamExProc(
|
|
ENUMLOGFONTEX *lpelfe, // pointer to logical-font data
|
|
NEWTEXTMETRICEX *lpntme, // pointer to physical-font data
|
|
int FontType, // type of font
|
|
LPARAM lParam // application-defined data
|
|
)
|
|
{
|
|
if(g_nFontCount>200)
|
|
return 0; // JMC: HACK - Stop enumerating if more than 200 families
|
|
|
|
// Don't use if we already have this font name
|
|
BOOL bHave = FALSE;
|
|
for(int i=0;i<g_nFontCount;i++)
|
|
if(0 == lstrcmp((TCHAR *)g_rgFonts[i].elfFullName, (TCHAR *)lpelfe->elfFullName))
|
|
{
|
|
bHave = TRUE;
|
|
break;
|
|
}
|
|
if(!bHave)
|
|
g_rgFonts[g_nFontCount++] = *lpelfe;
|
|
return 1;
|
|
}
|
|
|
|
void Font_Init()
|
|
{
|
|
// Only do the stuff in this function once.
|
|
if(bFontsAlreadyInit)
|
|
return;
|
|
bFontsAlreadyInit = TRUE;
|
|
|
|
LOGFONT lf;
|
|
memset(&lf, 0, sizeof(lf));
|
|
// lf.lfCharSet = DEFAULT_CHARSET;
|
|
lf.lfCharSet = OEM_CHARSET;
|
|
HDC hdc = GetDC(NULL);
|
|
EnumFontFamiliesEx(hdc, &lf, (FONTENUMPROC)EnumFontFamExProc, 0, 0);
|
|
ReleaseDC(NULL, hdc);
|
|
// JMC: Make sure there is at least one font
|
|
}
|
|
|
|
#endif ENUMERATEFONTS
|
|
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// Old way of reading schemes from the registry
|
|
|
|
#ifdef READSCHEMESFROMREGISTRY
|
|
|
|
extern PTSTR s_pszColorNames[]; // JMC: HACK
|
|
|
|
|
|
// Scheme data for Windows 95
|
|
typedef struct {
|
|
SHORT version;
|
|
// NONCLIENTMETRICSA ncm;
|
|
// LOGFONTA lfIconTitle;
|
|
BYTE rgDummy[390]; // This is the size of NONCLIENTMETRICSA and LOGFONTA in 16 bit Windows!!!
|
|
COLORREF rgb[COLOR_MAX_95_NT4];
|
|
} SCHEMEDATA_95;
|
|
|
|
// New scheme data for Windows 97
|
|
typedef struct {
|
|
SHORT version;
|
|
// NONCLIENTMETRICSA ncm;
|
|
// LOGFONTA lfIconTitle;
|
|
BYTE rgDummy[390]; // This is the size of NONCLIENTMETRICSA and LOGFONTA in 16 bit Windows!!!
|
|
COLORREF rgb[COLOR_MAX_97_NT5];
|
|
} SCHEMEDATA_97;
|
|
|
|
// Scheme data for Windows NT 4.0
|
|
typedef struct {
|
|
SHORT version;
|
|
WORD wDummy; // for alignment
|
|
NONCLIENTMETRICSW ncm;
|
|
LOGFONTW lfIconTitle;
|
|
COLORREF rgb[COLOR_MAX_95_NT4];
|
|
} SCHEMEDATA_NT4;
|
|
|
|
// Scheme data for Windows NT 5.0
|
|
typedef struct {
|
|
SHORT version;
|
|
WORD wDummy; // for alignment
|
|
NONCLIENTMETRICSW ncm;
|
|
LOGFONTW lfIconTitle;
|
|
COLORREF rgb[COLOR_MAX_97_NT5];
|
|
} SCHEMEDATA_NT5;
|
|
|
|
static SCHEMEDATALOCAL g_rgSchemeData[100]; // JMC: HACK - At Most 100 schemes
|
|
static TCHAR g_rgSchemeNames[100][100];
|
|
static int g_nSchemeCount = 0;
|
|
static BOOL bSchemesAlreadyInit = FALSE;
|
|
|
|
void Scheme_Init();
|
|
|
|
int GetSchemeCount()
|
|
{
|
|
Scheme_Init();
|
|
return g_nSchemeCount;
|
|
}
|
|
|
|
void GetSchemeName(int nIndex, LPTSTR lpszName, int nLen) // JMC: HACK - You must allocate enough space
|
|
{
|
|
Scheme_Init();
|
|
_tcsncpy(lpszName, g_rgSchemeNames[i], nLen - 1);
|
|
lpstName[nLen - 1] = 0; // Guarantee NULL termination
|
|
}
|
|
|
|
SCHEMEDATALOCAL &GetScheme(int nIndex)
|
|
{
|
|
Scheme_Init();
|
|
return g_rgSchemeData[nIndex];
|
|
}
|
|
|
|
void Scheme_Init()
|
|
{
|
|
// Only do the stuff in this function once.
|
|
if(bSchemesAlreadyInit)
|
|
return;
|
|
bSchemesAlreadyInit = TRUE;
|
|
|
|
HKEY hkSchemes;
|
|
DWORD dw, dwSize;
|
|
TCHAR szBuf[100];
|
|
|
|
g_nSchemeCount = 0;
|
|
|
|
if (RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_LOOKSCHEMES, 0, KEY_READ_VALUE |
|
|
KEY_ENUMERATE_SUB_KEYS, &hkSchemes) != ERROR_SUCCESS)
|
|
return;
|
|
|
|
for (dw=0; ; dw++)
|
|
{
|
|
if(g_nSchemeCount>99)
|
|
break; //JMC: HACK - At Most 100 schemes
|
|
|
|
dwSize = ARRAYSIZE(szBuf);
|
|
if (RegEnumValue(hkSchemes, dw, szBuf, &dwSize, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
|
|
break; // Bail if no more values
|
|
|
|
DWORD dwType;
|
|
DWORD dwSize;
|
|
RegQueryValueEx(hkSchemes, szBuf, NULL, &dwType, NULL, &dwSize);
|
|
if(dwType == REG_BINARY)
|
|
{
|
|
// Always copy the current name to the name array - if there
|
|
// is an error in the data, we just won't upcount g_nSchemeCount
|
|
lstrcpy(g_rgSchemeNames[g_nSchemeCount], szBuf);
|
|
|
|
// Find out which type of scheme this is, and convert to the
|
|
// SCHEMEDATALOCAL type
|
|
switch(dwSize)
|
|
{
|
|
case sizeof(SCHEMEDATA_95):
|
|
{
|
|
SCHEMEDATA_95 sd;
|
|
RegQueryValueEx(hkSchemes, szBuf, NULL, &dwType, (BYTE *)&sd, &dwSize);
|
|
if(1 != sd.version)
|
|
break; // We have the wrong version even though the size was correct
|
|
|
|
// Copy the color information from the registry info to g_rgSchemeData
|
|
g_rgSchemeData[g_nSchemeCount].nColorsUsed = COLOR_MAX_95_NT4;
|
|
|
|
// Copy the color array
|
|
for(int i=0;i<g_rgSchemeData[g_nSchemeCount].nColorsUsed;i++)
|
|
g_rgSchemeData[g_nSchemeCount].rgb[i] = sd.rgb[i];
|
|
|
|
g_nSchemeCount++;
|
|
}
|
|
break;
|
|
case sizeof(SCHEMEDATA_NT4):
|
|
{
|
|
SCHEMEDATA_NT4 sd;
|
|
RegQueryValueEx(hkSchemes, szBuf, NULL, &dwType, (BYTE *)&sd, &dwSize);
|
|
if(2 != sd.version)
|
|
break; // We have the wrong version even though the size was correct
|
|
|
|
// Copy the color information from the registry info to g_rgSchemeData
|
|
g_rgSchemeData[g_nSchemeCount].nColorsUsed = COLOR_MAX_95_NT4;
|
|
|
|
// Copy the color array
|
|
for(int i=0;i<g_rgSchemeData[g_nSchemeCount].nColorsUsed;i++)
|
|
g_rgSchemeData[g_nSchemeCount].rgb[i] = sd.rgb[i];
|
|
|
|
g_nSchemeCount++;
|
|
}
|
|
break;
|
|
case sizeof(SCHEMEDATA_97):
|
|
{
|
|
SCHEMEDATA_97 sd;
|
|
RegQueryValueEx(hkSchemes, szBuf, NULL, &dwType, (BYTE *)&sd, &dwSize);
|
|
if(3 != sd.version)
|
|
break; // We have the wrong version even though the size was correct
|
|
|
|
// Copy the color information from the registry info to g_rgSchemeData
|
|
g_rgSchemeData[g_nSchemeCount].nColorsUsed = COLOR_MAX_97_NT5;
|
|
|
|
// Copy the color array
|
|
for(int i=0;i<g_rgSchemeData[g_nSchemeCount].nColorsUsed;i++)
|
|
g_rgSchemeData[g_nSchemeCount].rgb[i] = sd.rgb[i];
|
|
|
|
g_nSchemeCount++;
|
|
}
|
|
break;
|
|
case sizeof(SCHEMEDATA_NT5):
|
|
{
|
|
SCHEMEDATA_NT5 sd;
|
|
RegQueryValueEx(hkSchemes, szBuf, NULL, &dwType, (BYTE *)&sd, &dwSize);
|
|
if(2 != sd.version)
|
|
break; // We have the wrong version even though the size was correct
|
|
|
|
// Copy the color information from the registry info to g_rgSchemeData
|
|
g_rgSchemeData[g_nSchemeCount].nColorsUsed = COLOR_MAX_97_NT5;
|
|
|
|
// Copy the color array
|
|
for(int i=0;i<g_rgSchemeData[g_nSchemeCount].nColorsUsed;i++)
|
|
g_rgSchemeData[g_nSchemeCount].rgb[i] = sd.rgb[i];
|
|
|
|
g_nSchemeCount++;
|
|
}
|
|
break;
|
|
default:
|
|
// We had an unknown sized structure in the registry - IGNORE IT
|
|
#ifdef _DEBUG
|
|
TCHAR sz[200];
|
|
wsprintf(sz, __TEXT("Scheme - %s, size = %i, sizeof(95) = %i, sizeof(NT4) = %i, sizeof(97) = %i, sizeof(NT5) = %i"), szBuf, dwSize,
|
|
sizeof(SCHEMEDATA_95),
|
|
sizeof(SCHEMEDATA_NT4),
|
|
sizeof(SCHEMEDATA_97),
|
|
sizeof(SCHEMEDATA_NT5)
|
|
);
|
|
MessageBox(NULL, sz, NULL, MB_OK);
|
|
#endif // _DEBUG
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
RegCloseKey(hkSchemes);
|
|
}
|
|
|
|
#endif // READSCHEMESFROMREGISTRY
|
|
|
|
void PORTABLE_NONCLIENTMETRICS::ApplyChanges() const
|
|
{
|
|
NONCLIENTMETRICS ncmOrig;
|
|
LOGFONT lfIconOrig;
|
|
GetNonClientMetrics(&ncmOrig, &lfIconOrig);
|
|
|
|
NONCLIENTMETRICS ncmNew;
|
|
LOGFONT lfIconNew;
|
|
|
|
ZeroMemory(&ncmNew, sizeof(ncmNew));
|
|
ZeroMemory(&lfIconNew, sizeof(lfIconNew));
|
|
|
|
ncmNew.cbSize = sizeof(ncmNew);
|
|
ncmNew.iBorderWidth = m_iBorderWidth;
|
|
ncmNew.iScrollWidth = m_iScrollWidth;
|
|
ncmNew.iScrollHeight = m_iScrollHeight;
|
|
ncmNew.iCaptionWidth = m_iCaptionWidth;
|
|
ncmNew.iCaptionHeight = m_iCaptionHeight;
|
|
ncmNew.lfCaptionFont.lfHeight = m_lfCaptionFont_lfHeight;
|
|
ncmNew.lfCaptionFont.lfWeight = m_lfCaptionFont_lfWeight;
|
|
ncmNew.iSmCaptionWidth = m_iSmCaptionWidth;
|
|
ncmNew.iSmCaptionHeight = m_iSmCaptionHeight;
|
|
ncmNew.lfSmCaptionFont.lfHeight = m_lfSmCaptionFont_lfHeight;
|
|
ncmNew.lfSmCaptionFont.lfWeight = m_lfSmCaptionFont_lfWeight;
|
|
ncmNew.iMenuWidth = m_iMenuWidth;
|
|
ncmNew.iMenuHeight = m_iMenuHeight;
|
|
ncmNew.lfMenuFont.lfHeight = m_lfMenuFont_lfHeight;
|
|
ncmNew.lfMenuFont.lfWeight = m_lfMenuFont_lfWeight;
|
|
ncmNew.lfStatusFont.lfHeight = m_lfStatusFont_lfHeight;
|
|
ncmNew.lfStatusFont.lfWeight = m_lfStatusFont_lfWeight;
|
|
ncmNew.lfMessageFont.lfHeight = m_lfMessageFont_lfHeight;
|
|
ncmNew.lfMessageFont.lfWeight = m_lfMessageFont_lfWeight;
|
|
lfIconNew.lfHeight = m_lfIconWindowsDefault_lfHeight;
|
|
lfIconNew.lfWeight = m_lfIconWindowsDefault_lfWeight;
|
|
|
|
|
|
// Fill in fonts
|
|
if(m_nFontFaces)
|
|
{
|
|
TCHAR lfFaceName[LF_FACESIZE];
|
|
LoadString(g_hInstDll, IDS_SYSTEMFONTNAME, lfFaceName, ARRAYSIZE(lfFaceName));
|
|
|
|
BYTE lfCharSet;
|
|
TCHAR szCharSet[20];
|
|
if(LoadString(g_hInstDll,IDS_FONTCHARSET, szCharSet,sizeof(szCharSet)/sizeof(TCHAR))) {
|
|
lfCharSet = (BYTE)_tcstoul(szCharSet,NULL,10);
|
|
} else {
|
|
lfCharSet = 0; // Default
|
|
}
|
|
|
|
ncmNew.lfCaptionFont.lfCharSet = lfCharSet;
|
|
ncmNew.lfSmCaptionFont.lfCharSet = lfCharSet;
|
|
ncmNew.lfMenuFont.lfCharSet = lfCharSet;
|
|
ncmNew.lfStatusFont.lfCharSet = lfCharSet;
|
|
ncmNew.lfMessageFont.lfCharSet = lfCharSet;
|
|
lfIconNew.lfCharSet = lfCharSet;
|
|
|
|
lstrcpy(ncmNew.lfCaptionFont.lfFaceName, lfFaceName);
|
|
lstrcpy(ncmNew.lfSmCaptionFont.lfFaceName, lfFaceName);
|
|
lstrcpy(ncmNew.lfMenuFont.lfFaceName, lfFaceName);
|
|
lstrcpy(ncmNew.lfStatusFont.lfFaceName, lfFaceName);
|
|
lstrcpy(ncmNew.lfMessageFont.lfFaceName, lfFaceName);
|
|
lstrcpy(lfIconNew.lfFaceName, lfFaceName);
|
|
}
|
|
else
|
|
{
|
|
ncmNew.lfCaptionFont.lfCharSet = ncmOrig.lfCaptionFont.lfCharSet;
|
|
ncmNew.lfSmCaptionFont.lfCharSet = ncmOrig.lfSmCaptionFont.lfCharSet;
|
|
ncmNew.lfMenuFont.lfCharSet = ncmOrig.lfMenuFont.lfCharSet;
|
|
ncmNew.lfStatusFont.lfCharSet = ncmOrig.lfStatusFont.lfCharSet;
|
|
ncmNew.lfMessageFont.lfCharSet = ncmOrig.lfMessageFont.lfCharSet;
|
|
lfIconNew.lfCharSet = lfIconOrig.lfCharSet;
|
|
|
|
lstrcpy(ncmNew.lfCaptionFont.lfFaceName, ncmOrig.lfCaptionFont.lfFaceName);
|
|
lstrcpy(ncmNew.lfSmCaptionFont.lfFaceName, ncmOrig.lfSmCaptionFont.lfFaceName);
|
|
lstrcpy(ncmNew.lfMenuFont.lfFaceName, ncmOrig.lfMenuFont.lfFaceName);
|
|
lstrcpy(ncmNew.lfStatusFont.lfFaceName, ncmOrig.lfStatusFont.lfFaceName);
|
|
lstrcpy(ncmNew.lfMessageFont.lfFaceName, ncmOrig.lfMessageFont.lfFaceName);
|
|
lstrcpy(lfIconNew.lfFaceName, lfIconOrig.lfFaceName);
|
|
}
|
|
|
|
|
|
if(0 != memcmp(&ncmNew, &ncmOrig, sizeof(ncmOrig)))
|
|
SystemParametersInfo(SPI_SETNONCLIENTMETRICS, sizeof(ncmNew), (PVOID)&ncmNew, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
|
|
if(0 != memcmp(&lfIconNew, &lfIconOrig, sizeof(lfIconOrig)))
|
|
SystemParametersInfo(SPI_SETICONTITLELOGFONT, sizeof(lfIconNew), &lfIconNew, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
|
|
}
|
|
|
|
// Helpers for setting/getting numeric string reg entry
|
|
void WINAPI RegQueryStr(
|
|
LPTSTR lpDefault,
|
|
HKEY hkey,
|
|
LPTSTR lpSubKey,
|
|
LPTSTR lpValueName,
|
|
LPTSTR lpszValue,
|
|
DWORD cbData) // note this is bytes, not characters.
|
|
{
|
|
DWORD dwType;
|
|
DWORD dwLast = cbData / (sizeof TCHAR) - 1;
|
|
|
|
lstrcpy(lpszValue, lpDefault);
|
|
if (ERROR_SUCCESS == RegOpenKeyEx(hkey, lpSubKey, 0, KEY_QUERY_VALUE, &hkey))
|
|
{
|
|
RegQueryValueEx(hkey, lpValueName, NULL, &dwType, (PBYTE) lpszValue, &cbData);
|
|
lpszValue[dwLast] = TEXT('\0');
|
|
RegCloseKey(hkey);
|
|
}
|
|
}
|
|
|
|
BOOL RegSetStr(
|
|
HKEY hkey,
|
|
LPCTSTR lpSection,
|
|
LPCTSTR lpKeyName,
|
|
LPCTSTR lpString)
|
|
{
|
|
BOOL fRet = FALSE;
|
|
LONG lErr;
|
|
DWORD dwDisposition;
|
|
|
|
lErr = RegCreateKeyEx(
|
|
hkey,
|
|
lpSection,
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_SET_VALUE,
|
|
NULL,
|
|
&hkey,
|
|
&dwDisposition);
|
|
|
|
if (ERROR_SUCCESS == lErr)
|
|
{
|
|
if (NULL != lpString)
|
|
{
|
|
lErr = RegSetValueEx(
|
|
hkey,
|
|
lpKeyName,
|
|
0,
|
|
REG_SZ,
|
|
(CONST BYTE *)lpString,
|
|
(lstrlen(lpString) + 1) * sizeof(*lpString));
|
|
}
|
|
else
|
|
{
|
|
lErr = RegSetValueEx(
|
|
hkey,
|
|
lpKeyName,
|
|
0,
|
|
REG_SZ,
|
|
(CONST BYTE *)__TEXT(""),
|
|
1 * sizeof(*lpString));
|
|
}
|
|
|
|
if (ERROR_SUCCESS == lErr)
|
|
{
|
|
fRet = TRUE;
|
|
}
|
|
RegCloseKey(hkey);
|
|
}
|
|
return(fRet);
|
|
}
|
|
|
|
DWORD WINAPI RegQueryStrDW(
|
|
DWORD dwDefault,
|
|
HKEY hkey,
|
|
LPTSTR lpSubKey,
|
|
LPTSTR lpValueName)
|
|
{
|
|
DWORD dwRet = dwDefault;
|
|
TCHAR szTemp[40];
|
|
TCHAR szDefault[40];
|
|
DWORD dwSize = sizeof(szTemp);
|
|
|
|
wsprintf(szDefault, TEXT("%d"), dwDefault);
|
|
|
|
RegQueryStr(szDefault, hkey, lpSubKey, lpValueName, szTemp, dwSize);
|
|
|
|
dwRet = _ttol(szTemp);
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
|
|
BOOL RegSetStrDW(HKEY hkey, LPTSTR lpSection, LPCTSTR lpKeyName, DWORD dwValue)
|
|
{
|
|
TCHAR szTemp[40];
|
|
|
|
wsprintf(szTemp, TEXT("%d"), dwValue);
|
|
return RegSetStr(hkey, lpSection, lpKeyName, szTemp);
|
|
}
|
|
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|