Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

281 lines
8.3 KiB

  1. //Copyright (c) 1997-2000 Microsoft Corporation
  2. #include "pch.hxx" // pch
  3. #pragma hdrstop
  4. #include "resource.h"
  5. #include "CurSchme.h"
  6. DWORD g_dwSchemeSource;
  7. static LPCTSTR g_rgszCursorNames[] =
  8. {
  9. __TEXT("Arrow"),
  10. __TEXT("Help"),
  11. __TEXT("AppStarting"),
  12. __TEXT("Wait"),
  13. __TEXT("Crosshair"),
  14. __TEXT("IBeam"),
  15. __TEXT("NWPen"),
  16. __TEXT("No"),
  17. __TEXT("SizeNS"),
  18. __TEXT("SizeWE"),
  19. __TEXT("SizeNWSE"),
  20. __TEXT("SizeNESW"),
  21. __TEXT("SizeAll"),
  22. __TEXT("UpArrow"),
  23. __TEXT("Hand"),
  24. NULL // This is the default value
  25. };
  26. #define CCURSORS (sizeof(g_rgszCursorNames) / sizeof(g_rgszCursorNames[0]))
  27. TCHAR g_szOrigCursors[CCURSORS][_MAX_PATH];
  28. DWORD g_dwOrigSchemeSource = 0;
  29. const TCHAR g_szCursorRegPath[] = REGSTR_PATH_CURSORS;
  30. const TCHAR szSchemeSource[] = TEXT("Scheme Source");
  31. TCHAR g_szSchemeNames[8][100]; // HACK - We have to make sure the scheme names are less than 100 characters
  32. typedef
  33. LANGID
  34. (WINAPI *pfnGetUserDefaultUILanguage)(
  35. void
  36. );
  37. typedef
  38. LANGID
  39. (WINAPI *pfnGetSystemDefaultUILanguage)(
  40. void
  41. );
  42. BOOL IsMUI_Enabled()
  43. {
  44. OSVERSIONINFO verinfo;
  45. LANGID rcLang;
  46. HMODULE hModule;
  47. pfnGetUserDefaultUILanguage gpfnGetUserDefaultUILanguage;
  48. pfnGetSystemDefaultUILanguage gpfnGetSystemDefaultUILanguage;
  49. static g_bPFNLoaded=FALSE;
  50. static g_bMUIStatus=FALSE;
  51. if(g_bPFNLoaded)
  52. return g_bMUIStatus;
  53. g_bPFNLoaded = TRUE;
  54. verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  55. GetVersionEx( &verinfo) ;
  56. if (verinfo.dwMajorVersion == 5)
  57. {
  58. hModule = GetModuleHandle(TEXT("kernel32.dll"));
  59. if (hModule)
  60. {
  61. gpfnGetSystemDefaultUILanguage =
  62. (pfnGetSystemDefaultUILanguage)GetProcAddress(hModule,"GetSystemDefaultUILanguage");
  63. if (gpfnGetSystemDefaultUILanguage)
  64. {
  65. rcLang = (LANGID) gpfnGetSystemDefaultUILanguage();
  66. if (rcLang == 0x409 )
  67. {
  68. gpfnGetUserDefaultUILanguage =
  69. (pfnGetUserDefaultUILanguage)GetProcAddress(hModule,"GetUserDefaultUILanguage");
  70. if (gpfnGetUserDefaultUILanguage)
  71. {
  72. if (rcLang != (LANGID)gpfnGetUserDefaultUILanguage() )
  73. {
  74. g_bMUIStatus = TRUE;
  75. }
  76. }
  77. }
  78. }
  79. }
  80. }
  81. return g_bMUIStatus;
  82. }
  83. void LoadCursorSchemeNames()
  84. {
  85. static BOOL g_bSchemeNamesLoaded = FALSE;
  86. if(g_bSchemeNamesLoaded)
  87. return;
  88. g_bSchemeNamesLoaded = TRUE;
  89. if (!IsMUI_Enabled())
  90. {
  91. LoadString(g_hInstDll, IDS_CURSOR_SCHEME_WINDOWS_STANDARD_LARGE , g_szSchemeNames[0], 100);
  92. LoadString(g_hInstDll, IDS_CURSOR_SCHEME_WINDOWS_STANDARD_EXTRALARGE, g_szSchemeNames[1], 100);
  93. LoadString(g_hInstDll, IDS_CURSOR_SCHEME_WINDOWS_BLACK , g_szSchemeNames[2], 100);
  94. LoadString(g_hInstDll, IDS_CURSOR_SCHEME_WINDOWS_BLACK_LARGE , g_szSchemeNames[3], 100);
  95. LoadString(g_hInstDll, IDS_CURSOR_SCHEME_WINDOWS_BLACK_EXTRALARGE , g_szSchemeNames[4], 100);
  96. LoadString(g_hInstDll, IDS_CURSOR_SCHEME_WINDOWS_INVERTED , g_szSchemeNames[5], 100);
  97. LoadString(g_hInstDll, IDS_CURSOR_SCHEME_WINDOWS_INVERTED_LARGE , g_szSchemeNames[6], 100);
  98. LoadString(g_hInstDll, IDS_CURSOR_SCHEME_WINDOWS_INVERTED_EXTRALARGE, g_szSchemeNames[7], 100);
  99. }
  100. else
  101. {
  102. lstrcpy(g_szSchemeNames[0],IDSENG_CURSOR_SCHEME_WINDOWS_STANDARD_LARGE);
  103. lstrcpy(g_szSchemeNames[1],IDSENG_CURSOR_SCHEME_WINDOWS_STANDARD_EXTRALARGE);
  104. lstrcpy(g_szSchemeNames[2],IDSENG_CURSOR_SCHEME_WINDOWS_BLACK);
  105. lstrcpy(g_szSchemeNames[3],IDSENG_CURSOR_SCHEME_WINDOWS_BLACK_LARGE);
  106. lstrcpy(g_szSchemeNames[4],IDSENG_CURSOR_SCHEME_WINDOWS_BLACK_EXTRALARGE);
  107. lstrcpy(g_szSchemeNames[5],IDSENG_CURSOR_SCHEME_WINDOWS_INVERTED);
  108. lstrcpy(g_szSchemeNames[6],IDSENG_CURSOR_SCHEME_WINDOWS_INVERTED_LARGE);
  109. lstrcpy(g_szSchemeNames[7],IDSENG_CURSOR_SCHEME_WINDOWS_INVERTED_EXTRALARGE);
  110. }
  111. // Load the current cursor settings
  112. HKEY hkCursors;
  113. if (ERROR_SUCCESS == RegOpenKey( HKEY_CURRENT_USER, g_szCursorRegPath, &hkCursors ))
  114. {
  115. for(int i=0;i<CCURSORS;i++)
  116. {
  117. g_szOrigCursors[i][0] = 0;
  118. DWORD dwCount = _MAX_PATH * sizeof(TCHAR);
  119. DWORD dwType;
  120. RegQueryValueEx( hkCursors,
  121. g_rgszCursorNames[i],
  122. NULL,
  123. &dwType,
  124. (LPBYTE)g_szOrigCursors[i],
  125. &dwCount );
  126. }
  127. // Get the scheme source value
  128. DWORD dwLen = sizeof(g_dwOrigSchemeSource);
  129. if (RegQueryValueEx( hkCursors, szSchemeSource, NULL, NULL, (unsigned char *)&g_dwOrigSchemeSource, &dwLen ) != ERROR_SUCCESS)
  130. g_dwOrigSchemeSource = 1;
  131. RegCloseKey(hkCursors);
  132. }
  133. else
  134. _ASSERTE(FALSE);
  135. }
  136. static const TCHAR c_szRegPathCursorSchemes[] = REGSTR_PATH_CURSORS TEXT( "\\Schemes" );
  137. static const TCHAR c_szRegPathSystemSchemes[] = REGSTR_PATH_SETUP TEXT("\\Control Panel\\Cursors\\Schemes");
  138. // ApplyScheme(int nScheme)
  139. // '0' Scheme loaded in g_szOrigScheme
  140. // '1' Windows Default
  141. // '2' Standard Large
  142. // '3' Standard Ex Large
  143. // '4' Black
  144. // '5' Black Large
  145. // '6' Black Ex Large
  146. // '7' Inverted
  147. // '8' Inverted Large
  148. // '9' Inverted Ex Large
  149. void ApplyCursorScheme(int nScheme)
  150. {
  151. LoadCursorSchemeNames();
  152. HKEY hkCursors;
  153. DWORD dwPosition;
  154. // Initially for default cursor, The registry "\\ControlPanel\Cursors" is not created
  155. // so. Create the registry values: a-anilk
  156. if(ERROR_SUCCESS != RegCreateKeyEx( HKEY_CURRENT_USER, g_szCursorRegPath, 0L, TEXT(""),
  157. REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkCursors, &dwPosition ))
  158. return;
  159. int i;
  160. DWORD dwSchemeSource;
  161. switch(nScheme)
  162. {
  163. case 0: // Original scheme
  164. dwSchemeSource = g_dwOrigSchemeSource;
  165. for(i=0;i<CCURSORS;i++)
  166. RegSetValueEx( hkCursors, g_rgszCursorNames[i], 0L, REG_SZ, (CONST LPBYTE)g_szOrigCursors[i], (lstrlen(g_szOrigCursors[i])+1)*sizeof(TCHAR));
  167. break;
  168. case 1: // Windows default
  169. dwSchemeSource = 0;
  170. for(i=0;i<CCURSORS;i++)
  171. RegSetValueEx( hkCursors, g_rgszCursorNames[i], 0L, REG_SZ, (CONST LPBYTE)"", sizeof(TCHAR));
  172. break;
  173. case 2:
  174. case 3:
  175. case 4:
  176. case 5:
  177. case 6:
  178. case 7:
  179. case 8:
  180. case 9:
  181. {
  182. dwSchemeSource = 2; // Assume System schemes
  183. HKEY hkScheme;
  184. // Try to find the 'system' schemes first
  185. if(ERROR_SUCCESS != RegOpenKey( HKEY_LOCAL_MACHINE, c_szRegPathSystemSchemes, &hkScheme ))
  186. {
  187. // Couldn't find system schemes, try looking in user schemes
  188. dwSchemeSource = 1; // User schemes
  189. if(ERROR_SUCCESS != RegOpenKey( HKEY_CURRENT_USER, c_szRegPathCursorSchemes, &hkScheme ))
  190. return;
  191. }
  192. DWORD dwCount = 0;
  193. DWORD dwType;
  194. long nResult;
  195. if(ERROR_SUCCESS != (nResult = RegQueryValueEx( hkScheme, g_szSchemeNames[nScheme - 2], NULL, &dwType, NULL, &dwCount )))
  196. dwCount = 1; // The value probably was not there. Fake it and allocate 1 byte.
  197. LPTSTR lpszData = (LPTSTR)new BYTE[dwCount]; // NOTE: For Unicode, RegQueryValueEx still returns the 'Byte' size not 'Char count'
  198. lpszData[0] = 0;
  199. if(ERROR_SUCCESS == nResult)
  200. RegQueryValueEx( hkScheme, g_szSchemeNames[nScheme - 2], NULL, &dwType, (LPBYTE)lpszData, &dwCount );
  201. LPTSTR lpszCurrentValue = lpszData;
  202. LPTSTR lpszFinalNULL = lpszData + lstrlen(lpszData);
  203. // Parse the information
  204. for(i=0;i<CCURSORS;i++)
  205. {
  206. // Hack to set the default value
  207. if(CCURSORS - 1 == i)
  208. {
  209. lpszCurrentValue = g_szSchemeNames[nScheme - 2];
  210. RegSetValueEx( hkCursors, NULL, 0L, REG_SZ, (CONST LPBYTE)lpszCurrentValue, (lstrlen(lpszCurrentValue)+1)*sizeof(TCHAR));
  211. }
  212. else
  213. {
  214. // Find next comma
  215. LPTSTR lpszComma = _tcschr(lpszCurrentValue, __TEXT(','));
  216. // Turn it into a zero
  217. if(lpszComma)
  218. *lpszComma = 0;
  219. RegSetValueEx( hkCursors, g_rgszCursorNames[i], 0L, REG_SZ, (CONST LPBYTE)lpszCurrentValue, (lstrlen(lpszCurrentValue)+1)*sizeof(TCHAR));
  220. lpszCurrentValue = min(lpszFinalNULL, lpszCurrentValue + lstrlen(lpszCurrentValue) + 1);
  221. }
  222. }
  223. delete [] lpszData;
  224. RegCloseKey(hkScheme);
  225. }
  226. break;
  227. default:
  228. _ASSERTE(FALSE);
  229. }
  230. // Save the 'Scheme Source'
  231. RegSetValueEx(hkCursors, szSchemeSource, 0, REG_DWORD, (unsigned char *)&dwSchemeSource, sizeof(dwSchemeSource));
  232. RegCloseKey(hkCursors);
  233. SystemParametersInfo( SPI_SETCURSORS, 0, 0, SPIF_SENDCHANGE );
  234. }