//Copyright (c) 1997-2000 Microsoft Corporation #include "pch.hxx" // pch #pragma hdrstop #include "Schemes.h" #include #include #include #include #include #include #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= 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)*sizeof(TCHAR); if (RegQueryValueEx(hk, HC_FLAGS, NULL, NULL, (LPBYTE)szValue, &dwSize) == ERROR_SUCCESS) { 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]) { HTHEMEFILE hThemeFile; hr = OpenThemeFile(pszThemeName, pszThemeColor, pszThemeSize, &hThemeFile, TRUE); if (SUCCEEDED(hr)) { hr = ApplyTheme(hThemeFile, AT_LOAD_SYSMETRICS | AT_SYNC_LOADMETRICS, NULL); CloseThemeFile(hThemeFile); 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 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 2) { HKEY hkSub; if (RegOpenKeyEx(hk, m_szSelectedStyle, 0, KEY_READ, &hkSub) == ERROR_SUCCESS) { TCHAR szSize[MAX_NUM_SZ] = {0}; ccb = ARRAYSIZE(szSize)*sizeof(TCHAR); DBPRINTF(TEXT("RegQueryValueEx(NEW_SCHEMES_SELECTEDSIZE=%s,,,ccb=%d)\r\n"), NEW_SCHEMES_SELECTEDSIZE, ccb); RegQueryValueEx(hkSub, NEW_SCHEMES_SELECTEDSIZE, 0, NULL, (LPBYTE)szSize, &ccb); 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;ielfFullName)) { 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 (RegOpenKey(HKEY_CURRENT_USER, REGSTR_PATH_LOOKSCHEMES, &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