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.

284 lines
8.9 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 == RegOpenKeyEx( HKEY_CURRENT_USER, g_szCursorRegPath, 0, KEY_READ,
  114. &hkCursors ))
  115. {
  116. for(int i=0;i<CCURSORS;i++)
  117. {
  118. g_szOrigCursors[i][0] = 0;
  119. DWORD dwCount = _MAX_PATH * sizeof(TCHAR);
  120. DWORD dwType;
  121. RegQueryValueEx( hkCursors,
  122. g_rgszCursorNames[i],
  123. NULL,
  124. &dwType,
  125. (LPBYTE)g_szOrigCursors[i],
  126. &dwCount );
  127. g_szOrigCursors[i][ARRAYSIZE(g_szOrigCursors[i])-1] = TEXT('\0'); // ensure NUL termination
  128. }
  129. // Get the scheme source value
  130. DWORD dwLen = sizeof(g_dwOrigSchemeSource);
  131. if (RegQueryValueEx( hkCursors, szSchemeSource, NULL, NULL, (unsigned char *)&g_dwOrigSchemeSource, &dwLen ) != ERROR_SUCCESS)
  132. g_dwOrigSchemeSource = 1;
  133. RegCloseKey(hkCursors);
  134. }
  135. else
  136. _ASSERTE(FALSE);
  137. }
  138. static const TCHAR c_szRegPathCursorSchemes[] = REGSTR_PATH_CURSORS TEXT( "\\Schemes" );
  139. static const TCHAR c_szRegPathSystemSchemes[] = REGSTR_PATH_SETUP TEXT("\\Control Panel\\Cursors\\Schemes");
  140. // ApplyScheme(int nScheme)
  141. // '0' Scheme loaded in g_szOrigScheme
  142. // '1' Windows Default
  143. // '2' Standard Large
  144. // '3' Standard Ex Large
  145. // '4' Black
  146. // '5' Black Large
  147. // '6' Black Ex Large
  148. // '7' Inverted
  149. // '8' Inverted Large
  150. // '9' Inverted Ex Large
  151. void ApplyCursorScheme(int nScheme)
  152. {
  153. LoadCursorSchemeNames();
  154. HKEY hkCursors;
  155. DWORD dwPosition;
  156. // Initially for default cursor, The registry "\\ControlPanel\Cursors" is not created
  157. // so. Create the registry values: a-anilk
  158. if(ERROR_SUCCESS != RegCreateKeyEx( HKEY_CURRENT_USER, g_szCursorRegPath, 0L, TEXT(""),
  159. REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkCursors, &dwPosition ))
  160. return;
  161. int i;
  162. DWORD dwSchemeSource;
  163. switch(nScheme)
  164. {
  165. case 0: // Original scheme
  166. dwSchemeSource = g_dwOrigSchemeSource;
  167. for(i=0;i<CCURSORS;i++)
  168. RegSetValueEx( hkCursors, g_rgszCursorNames[i], 0L, REG_SZ, (CONST LPBYTE)g_szOrigCursors[i], (lstrlen(g_szOrigCursors[i])+1)*sizeof(TCHAR));
  169. break;
  170. case 1: // Windows default
  171. dwSchemeSource = 0;
  172. for(i=0;i<CCURSORS;i++)
  173. RegSetValueEx( hkCursors, g_rgszCursorNames[i], 0L, REG_SZ, (CONST LPBYTE)TEXT(""), sizeof(TCHAR));
  174. break;
  175. case 2:
  176. case 3:
  177. case 4:
  178. case 5:
  179. case 6:
  180. case 7:
  181. case 8:
  182. case 9:
  183. {
  184. dwSchemeSource = 2; // Assume System schemes
  185. HKEY hkScheme;
  186. // Try to find the 'system' schemes first
  187. if(ERROR_SUCCESS != RegOpenKeyEx( HKEY_LOCAL_MACHINE, c_szRegPathSystemSchemes,
  188. 0, KEY_READ,&hkScheme ))
  189. {
  190. // Couldn't find system schemes, try looking in user schemes
  191. dwSchemeSource = 1; // User schemes
  192. if(ERROR_SUCCESS != RegOpenKeyEx( HKEY_CURRENT_USER, c_szRegPathCursorSchemes, 0, KEY_READ, &hkScheme ))
  193. return;
  194. }
  195. DWORD dwCount = 0;
  196. DWORD dwType;
  197. long nResult;
  198. if(ERROR_SUCCESS != (nResult = RegQueryValueEx( hkScheme, g_szSchemeNames[nScheme - 2], NULL, &dwType, NULL, &dwCount )))
  199. dwCount = sizeof TCHAR; // The value probably was not there. Fake it and allocate 1 byte.
  200. DWORD dwOrigCount = dwCount;
  201. LPTSTR lpszData = (LPTSTR)new BYTE[dwCount]; // NOTE: For Unicode, RegQueryValueEx still returns the 'Byte' size not 'Char count'
  202. lpszData[0] = 0;
  203. if(ERROR_SUCCESS == nResult)
  204. RegQueryValueEx( hkScheme, g_szSchemeNames[nScheme - 2], NULL, &dwType, (LPBYTE)lpszData, &dwCount );
  205. lpszData[dwOrigCount/(sizeof TCHAR)-1] = TEXT('\0'); // ensure NUL termination
  206. LPTSTR lpszCurrentValue = lpszData;
  207. LPTSTR lpszFinalNULL = lpszData + lstrlen(lpszData);
  208. // Parse the information
  209. for(i=0;i<CCURSORS;i++)
  210. {
  211. // Hack to set the default value
  212. if(CCURSORS - 1 == i)
  213. {
  214. lpszCurrentValue = g_szSchemeNames[nScheme - 2];
  215. RegSetValueEx( hkCursors, NULL, 0L, REG_SZ, (CONST LPBYTE)lpszCurrentValue, (lstrlen(lpszCurrentValue)+1)*sizeof(TCHAR));
  216. }
  217. else
  218. {
  219. // Find next comma
  220. LPTSTR lpszComma = _tcschr(lpszCurrentValue, __TEXT(','));
  221. // Turn it into a zero
  222. if(lpszComma)
  223. *lpszComma = 0;
  224. RegSetValueEx( hkCursors, g_rgszCursorNames[i], 0L, REG_SZ, (CONST LPBYTE)lpszCurrentValue, (lstrlen(lpszCurrentValue)+1)*sizeof(TCHAR));
  225. lpszCurrentValue = min(lpszFinalNULL, lpszCurrentValue + lstrlen(lpszCurrentValue) + 1);
  226. }
  227. }
  228. delete [] lpszData;
  229. RegCloseKey(hkScheme);
  230. }
  231. break;
  232. default:
  233. _ASSERTE(FALSE);
  234. }
  235. // Save the 'Scheme Source'
  236. RegSetValueEx(hkCursors, szSchemeSource, 0, REG_DWORD, (unsigned char *)&dwSchemeSource, sizeof(dwSchemeSource));
  237. RegCloseKey(hkCursors);
  238. SystemParametersInfo( SPI_SETCURSORS, 0, 0, SPIF_SENDCHANGE );
  239. }