windows-nt/Source/XPSP1/NT/shell/osshell/accessib/accwiz/curschme.cpp
2020-09-26 16:20:57 +08:00

282 lines
8.3 KiB
C++

//Copyright (c) 1997-2000 Microsoft Corporation
#include "pch.hxx" // pch
#pragma hdrstop
#include "resource.h"
#include "CurSchme.h"
DWORD g_dwSchemeSource;
static LPCTSTR g_rgszCursorNames[] =
{
__TEXT("Arrow"),
__TEXT("Help"),
__TEXT("AppStarting"),
__TEXT("Wait"),
__TEXT("Crosshair"),
__TEXT("IBeam"),
__TEXT("NWPen"),
__TEXT("No"),
__TEXT("SizeNS"),
__TEXT("SizeWE"),
__TEXT("SizeNWSE"),
__TEXT("SizeNESW"),
__TEXT("SizeAll"),
__TEXT("UpArrow"),
__TEXT("Hand"),
NULL // This is the default value
};
#define CCURSORS (sizeof(g_rgszCursorNames) / sizeof(g_rgszCursorNames[0]))
TCHAR g_szOrigCursors[CCURSORS][_MAX_PATH];
DWORD g_dwOrigSchemeSource = 0;
const TCHAR g_szCursorRegPath[] = REGSTR_PATH_CURSORS;
const TCHAR szSchemeSource[] = TEXT("Scheme Source");
TCHAR g_szSchemeNames[8][100]; // HACK - We have to make sure the scheme names are less than 100 characters
typedef
LANGID
(WINAPI *pfnGetUserDefaultUILanguage)(
void
);
typedef
LANGID
(WINAPI *pfnGetSystemDefaultUILanguage)(
void
);
BOOL IsMUI_Enabled()
{
OSVERSIONINFO verinfo;
LANGID rcLang;
HMODULE hModule;
pfnGetUserDefaultUILanguage gpfnGetUserDefaultUILanguage;
pfnGetSystemDefaultUILanguage gpfnGetSystemDefaultUILanguage;
static g_bPFNLoaded=FALSE;
static g_bMUIStatus=FALSE;
if(g_bPFNLoaded)
return g_bMUIStatus;
g_bPFNLoaded = TRUE;
verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx( &verinfo) ;
if (verinfo.dwMajorVersion == 5)
{
hModule = GetModuleHandle(TEXT("kernel32.dll"));
if (hModule)
{
gpfnGetSystemDefaultUILanguage =
(pfnGetSystemDefaultUILanguage)GetProcAddress(hModule,"GetSystemDefaultUILanguage");
if (gpfnGetSystemDefaultUILanguage)
{
rcLang = (LANGID) gpfnGetSystemDefaultUILanguage();
if (rcLang == 0x409 )
{
gpfnGetUserDefaultUILanguage =
(pfnGetUserDefaultUILanguage)GetProcAddress(hModule,"GetUserDefaultUILanguage");
if (gpfnGetUserDefaultUILanguage)
{
if (rcLang != (LANGID)gpfnGetUserDefaultUILanguage() )
{
g_bMUIStatus = TRUE;
}
}
}
}
}
}
return g_bMUIStatus;
}
void LoadCursorSchemeNames()
{
static BOOL g_bSchemeNamesLoaded = FALSE;
if(g_bSchemeNamesLoaded)
return;
g_bSchemeNamesLoaded = TRUE;
if (!IsMUI_Enabled())
{
LoadString(g_hInstDll, IDS_CURSOR_SCHEME_WINDOWS_STANDARD_LARGE , g_szSchemeNames[0], 100);
LoadString(g_hInstDll, IDS_CURSOR_SCHEME_WINDOWS_STANDARD_EXTRALARGE, g_szSchemeNames[1], 100);
LoadString(g_hInstDll, IDS_CURSOR_SCHEME_WINDOWS_BLACK , g_szSchemeNames[2], 100);
LoadString(g_hInstDll, IDS_CURSOR_SCHEME_WINDOWS_BLACK_LARGE , g_szSchemeNames[3], 100);
LoadString(g_hInstDll, IDS_CURSOR_SCHEME_WINDOWS_BLACK_EXTRALARGE , g_szSchemeNames[4], 100);
LoadString(g_hInstDll, IDS_CURSOR_SCHEME_WINDOWS_INVERTED , g_szSchemeNames[5], 100);
LoadString(g_hInstDll, IDS_CURSOR_SCHEME_WINDOWS_INVERTED_LARGE , g_szSchemeNames[6], 100);
LoadString(g_hInstDll, IDS_CURSOR_SCHEME_WINDOWS_INVERTED_EXTRALARGE, g_szSchemeNames[7], 100);
}
else
{
lstrcpy(g_szSchemeNames[0],IDSENG_CURSOR_SCHEME_WINDOWS_STANDARD_LARGE);
lstrcpy(g_szSchemeNames[1],IDSENG_CURSOR_SCHEME_WINDOWS_STANDARD_EXTRALARGE);
lstrcpy(g_szSchemeNames[2],IDSENG_CURSOR_SCHEME_WINDOWS_BLACK);
lstrcpy(g_szSchemeNames[3],IDSENG_CURSOR_SCHEME_WINDOWS_BLACK_LARGE);
lstrcpy(g_szSchemeNames[4],IDSENG_CURSOR_SCHEME_WINDOWS_BLACK_EXTRALARGE);
lstrcpy(g_szSchemeNames[5],IDSENG_CURSOR_SCHEME_WINDOWS_INVERTED);
lstrcpy(g_szSchemeNames[6],IDSENG_CURSOR_SCHEME_WINDOWS_INVERTED_LARGE);
lstrcpy(g_szSchemeNames[7],IDSENG_CURSOR_SCHEME_WINDOWS_INVERTED_EXTRALARGE);
}
// Load the current cursor settings
HKEY hkCursors;
if (ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER, g_szCursorRegPath, &hkCursors ))
{
for(int i=0;i<CCURSORS;i++)
{
g_szOrigCursors[i][0] = 0;
DWORD dwCount = _MAX_PATH * sizeof(TCHAR);
DWORD dwType;
RegQueryValueEx( hkCursors,
g_rgszCursorNames[i],
NULL,
&dwType,
(LPBYTE)g_szOrigCursors[i],
&dwCount );
}
// Get the scheme source value
DWORD dwLen = sizeof(g_dwOrigSchemeSource);
if (RegQueryValueEx( hkCursors, szSchemeSource, NULL, NULL, (unsigned char *)&g_dwOrigSchemeSource, &dwLen ) != ERROR_SUCCESS)
g_dwOrigSchemeSource = 1;
RegCloseKey(hkCursors);
}
else
_ASSERTE(FALSE);
}
static const TCHAR c_szRegPathCursorSchemes[] = REGSTR_PATH_CURSORS TEXT( "\\Schemes" );
static const TCHAR c_szRegPathSystemSchemes[] = REGSTR_PATH_SETUP TEXT("\\Control Panel\\Cursors\\Schemes");
// ApplyScheme(int nScheme)
// '0' Scheme loaded in g_szOrigScheme
// '1' Windows Default
// '2' Standard Large
// '3' Standard Ex Large
// '4' Black
// '5' Black Large
// '6' Black Ex Large
// '7' Inverted
// '8' Inverted Large
// '9' Inverted Ex Large
void ApplyCursorScheme(int nScheme)
{
LoadCursorSchemeNames();
HKEY hkCursors;
DWORD dwPosition;
// Initially for default cursor, The registry "\\ControlPanel\Cursors" is not created
// so. Create the registry values: a-anilk
if(ERROR_SUCCESS != RegCreateKeyEx( HKEY_CURRENT_USER, g_szCursorRegPath, 0L, TEXT(""),
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkCursors, &dwPosition ))
return;
int i;
DWORD dwSchemeSource;
switch(nScheme)
{
case 0: // Original scheme
dwSchemeSource = g_dwOrigSchemeSource;
for(i=0;i<CCURSORS;i++)
RegSetValueEx( hkCursors, g_rgszCursorNames[i], 0L, REG_SZ, (CONST LPBYTE)g_szOrigCursors[i], (lstrlen(g_szOrigCursors[i])+1)*sizeof(TCHAR));
break;
case 1: // Windows default
dwSchemeSource = 0;
for(i=0;i<CCURSORS;i++)
RegSetValueEx( hkCursors, g_rgszCursorNames[i], 0L, REG_SZ, (CONST LPBYTE)"", sizeof(TCHAR));
break;
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
{
dwSchemeSource = 2; // Assume System schemes
HKEY hkScheme;
// Try to find the 'system' schemes first
if(ERROR_SUCCESS != RegOpenKey( HKEY_LOCAL_MACHINE, c_szRegPathSystemSchemes, &hkScheme ))
{
// Couldn't find system schemes, try looking in user schemes
dwSchemeSource = 1; // User schemes
if(ERROR_SUCCESS != RegOpenKey( HKEY_CURRENT_USER, c_szRegPathCursorSchemes, &hkScheme ))
return;
}
DWORD dwCount = 0;
DWORD dwType;
long nResult;
if(ERROR_SUCCESS != (nResult = RegQueryValueEx( hkScheme, g_szSchemeNames[nScheme - 2], NULL, &dwType, NULL, &dwCount )))
dwCount = 1; // The value probably was not there. Fake it and allocate 1 byte.
LPTSTR lpszData = (LPTSTR)new BYTE[dwCount]; // NOTE: For Unicode, RegQueryValueEx still returns the 'Byte' size not 'Char count'
lpszData[0] = 0;
if(ERROR_SUCCESS == nResult)
RegQueryValueEx( hkScheme, g_szSchemeNames[nScheme - 2], NULL, &dwType, (LPBYTE)lpszData, &dwCount );
LPTSTR lpszCurrentValue = lpszData;
LPTSTR lpszFinalNULL = lpszData + lstrlen(lpszData);
// Parse the information
for(i=0;i<CCURSORS;i++)
{
// Hack to set the default value
if(CCURSORS - 1 == i)
{
lpszCurrentValue = g_szSchemeNames[nScheme - 2];
RegSetValueEx( hkCursors, NULL, 0L, REG_SZ, (CONST LPBYTE)lpszCurrentValue, (lstrlen(lpszCurrentValue)+1)*sizeof(TCHAR));
}
else
{
// Find next comma
LPTSTR lpszComma = _tcschr(lpszCurrentValue, __TEXT(','));
// Turn it into a zero
if(lpszComma)
*lpszComma = 0;
RegSetValueEx( hkCursors, g_rgszCursorNames[i], 0L, REG_SZ, (CONST LPBYTE)lpszCurrentValue, (lstrlen(lpszCurrentValue)+1)*sizeof(TCHAR));
lpszCurrentValue = min(lpszFinalNULL, lpszCurrentValue + lstrlen(lpszCurrentValue) + 1);
}
}
delete [] lpszData;
RegCloseKey(hkScheme);
}
break;
default:
_ASSERTE(FALSE);
}
// Save the 'Scheme Source'
RegSetValueEx(hkCursors, szSchemeSource, 0, REG_DWORD, (unsigned char *)&dwSchemeSource, sizeof(dwSchemeSource));
RegCloseKey(hkCursors);
SystemParametersInfo( SPI_SETCURSORS, 0, 0, SPIF_SENDCHANGE );
}