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.

721 lines
21 KiB

  1. #include "private.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include "HKLHelp.h"
  5. // Safe String
  6. #define STRSAFE_NO_DEPRECATE
  7. #include "strsafe.h"
  8. extern BOOL WINAPI IsNT();
  9. typedef char KeyNameType[MAX_NAME];
  10. // Forward decls.
  11. static void SortRegKeys(KeyNameType *hKLKeyList, KeyNameType *hKLList, INT Num);
  12. static void RenumberPreload(HKEY hKeyCU);
  13. static void SwitcHKLtoIME61();
  14. static BOOL CALLBACK EnumChildProcForSwitchKL(HWND hWnd, LPARAM lParam);
  15. static BOOL CALLBACK EnumProcForSwitchKL(HWND hWnd, LPARAM lParam);
  16. /*---------------------------------------------------------------------------
  17. GetHKLfromHKLM
  18. ---------------------------------------------------------------------------*/
  19. HKL GetHKLfromHKLM(LPSTR argszIMEFile)
  20. {
  21. HKL hklAnswer = 0;
  22. HKEY hKey, hSubKey;
  23. DWORD i, cbSubKey, cbIMEFile;
  24. TCHAR szSubKey[MAX_PATH], szIMEFile[MAX_PATH];
  25. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\Keyboard Layouts", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
  26. {
  27. for (i=0; ;i++)
  28. {
  29. cbSubKey = MAX_PATH;
  30. if (RegEnumKeyEx(hKey, i, szSubKey, &cbSubKey, NULL, NULL, NULL, NULL) == ERROR_NO_MORE_ITEMS)
  31. break;
  32. RegOpenKeyEx(hKey, szSubKey, 0, KEY_READ, &hSubKey);
  33. cbIMEFile=MAX_PATH;
  34. if (RegQueryValueEx(hSubKey,"IME File",NULL,NULL,(LPBYTE)szIMEFile, &cbIMEFile) == ERROR_SUCCESS)
  35. {
  36. if (lstrcmpi(argszIMEFile, szIMEFile) == 0)
  37. {
  38. RegCloseKey(hSubKey);
  39. sscanf(szSubKey, "%08x", &hklAnswer);
  40. break;
  41. }
  42. }
  43. RegCloseKey(hSubKey);
  44. }
  45. RegCloseKey(hKey);
  46. }
  47. return(hklAnswer);
  48. }
  49. /*---------------------------------------------------------------------------
  50. GetDefaultIMEFromHKCU
  51. ---------------------------------------------------------------------------*/
  52. HKL GetDefaultIMEFromHKCU(HKEY hKeyCU)
  53. {
  54. HKEY hKey;
  55. DWORD cbData;
  56. BYTE Data[MAX_NAME];
  57. HKL hKL = 0;
  58. cbData=sizeof(Data);
  59. if (IsNT())
  60. {
  61. RegOpenKeyEx(hKeyCU, "Keyboard Layout\\Preload", 0, KEY_READ, &hKey);
  62. RegQueryValueEx(hKey, "1", 0, NULL, Data, &cbData);
  63. RegCloseKey(hKey);
  64. }
  65. else
  66. { // Case of non-NT
  67. RegOpenKeyEx(hKeyCU, "keyboard layout\\preload\\1", 0, KEY_READ, &hKey);
  68. RegQueryValueEx(hKey, "", 0, NULL, Data, &cbData);
  69. RegCloseKey(hKey);
  70. }
  71. sscanf((const char *)Data,"%08x",&hKL);
  72. return(hKL);
  73. }
  74. /*---------------------------------------------------------------------------
  75. HKLHelpExistInPreload
  76. ---------------------------------------------------------------------------*/
  77. BOOL HKLHelpExistInPreload(HKEY hKeyCU, HKL hKL)
  78. {
  79. HKEY hKey,hSubKey;
  80. CHAR szKL[20];
  81. int i,j;
  82. DWORD cbName,cbData;
  83. CHAR Name[MAX_NAME];
  84. BYTE Data[MAX_NAME];
  85. FILETIME ftLastWriteTime;
  86. BOOL fResult = FALSE;
  87. wsprintf(szKL,"%08x",hKL);
  88. if (IsNT())
  89. {
  90. if (RegOpenKeyEx(hKeyCU, "Keyboard Layout\\Preload", 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
  91. {
  92. for (j=0; cbName=MAX_NAME, cbData=MAX_NAME, RegEnumValue(hKey, j, Name, &cbName, NULL, NULL, Data, &cbData) != ERROR_NO_MORE_ITEMS; j++)
  93. {
  94. if (lstrcmpi((LPCSTR)Data, szKL) == 0)
  95. {
  96. fResult = TRUE;
  97. break;
  98. }
  99. }
  100. RegCloseKey(hKey);
  101. }
  102. }
  103. else
  104. { // Case of non-NT
  105. if (RegOpenKeyEx(hKeyCU, "keyboard layout\\preload", 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
  106. {
  107. for (i=0; cbName=MAX_NAME, RegEnumKeyEx(hKey, i, Name, &cbName, 0, NULL, NULL, &ftLastWriteTime) != ERROR_NO_MORE_ITEMS; i++)
  108. {
  109. RegOpenKeyEx(hKey, Name, 0, KEY_ALL_ACCESS, &hSubKey);
  110. cbData=MAX_NAME;
  111. RegQueryValueEx(hSubKey, "", 0, NULL, Data, &cbData);
  112. RegCloseKey(hSubKey);
  113. if (lstrcmpi((LPCSTR)Data, szKL) == 0)
  114. {
  115. fResult = TRUE;
  116. break;
  117. }
  118. }
  119. RegCloseKey(hKey);
  120. }
  121. }
  122. return(fResult);
  123. }
  124. /*---------------------------------------------------------------------------
  125. HKLHelp412ExistInPreload
  126. ---------------------------------------------------------------------------*/
  127. BOOL HKLHelp412ExistInPreload(HKEY hKeyCU)
  128. {
  129. HKEY hKey, hSubKey;
  130. int i ,j;
  131. DWORD cbName, cbData;
  132. CHAR szName[MAX_NAME];
  133. CHAR szData[MAX_NAME];
  134. HKL hkl;
  135. FILETIME ftLastWriteTime;
  136. BOOL fResult = FALSE;
  137. if (IsNT())
  138. {
  139. if (RegOpenKeyEx(hKeyCU, "Keyboard Layout\\Preload", 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
  140. {
  141. for (j=0; cbName=MAX_NAME, cbData=MAX_NAME, RegEnumValue(hKey, j, szName, &cbName, NULL, NULL, (LPBYTE)szData, &cbData) != ERROR_NO_MORE_ITEMS; j++)
  142. {
  143. // See If Korean KL exist. Just compare last LCID part if it's 0x412.
  144. // IME hkl set 0xE000 on hiword.
  145. sscanf(szData, "%08x", &hkl);
  146. if ((HIWORD(hkl) & 0xe000) && LOWORD(hkl) == 0x0412)
  147. {
  148. fResult = TRUE;
  149. break;
  150. }
  151. }
  152. RegCloseKey(hKey);
  153. }
  154. }
  155. else
  156. { // Case of non-NT
  157. if (RegOpenKeyEx(hKeyCU, "keyboard layout\\preload", 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
  158. {
  159. for (i=0; cbName=MAX_NAME, RegEnumKeyEx(hKey, i, szName, &cbName, 0, NULL, NULL, &ftLastWriteTime) != ERROR_NO_MORE_ITEMS; i++)
  160. {
  161. RegOpenKeyEx(hKey, szName, 0, KEY_ALL_ACCESS, &hSubKey);
  162. cbData=MAX_NAME;
  163. RegQueryValueEx(hSubKey, "", 0, NULL, (LPBYTE)szData, &cbData);
  164. RegCloseKey(hSubKey);
  165. sscanf(szData, "%08x", &hkl);
  166. if ((HIWORD(hkl) & 0xe000) && LOWORD(hkl) == 0x0412)
  167. {
  168. fResult = TRUE;
  169. break;
  170. }
  171. }
  172. RegCloseKey(hKey);
  173. }
  174. }
  175. return(fResult);
  176. }
  177. /*---------------------------------------------------------------------------
  178. HKLHelpRemoveFromPreload
  179. ---------------------------------------------------------------------------*/
  180. void HKLHelpRemoveFromPreload(HKEY hKeyCU, HKL hKL)
  181. {
  182. HKEY hKey,hSubKey;
  183. char szKL[20];
  184. int i, j;
  185. DWORD cbName,cbData;
  186. CHAR szName[MAX_NAME];
  187. BYTE Data[MAX_NAME];
  188. FILETIME ftLastWriteTime;
  189. wsprintf(szKL, "%08x", hKL);
  190. if (IsNT())
  191. {
  192. if (RegOpenKeyEx(hKeyCU,"Keyboard Layout\\Preload", 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
  193. {
  194. for (j=0; ; j++)
  195. {
  196. cbName = MAX_NAME;
  197. cbData = MAX_NAME;
  198. if (RegEnumValue(hKey, j, szName, &cbName, NULL, NULL, Data, &cbData) == ERROR_NO_MORE_ITEMS )
  199. break;
  200. if (lstrcmpi((const char *)Data,szKL) == 0)
  201. {
  202. RegDeleteValue(hKey, szName);
  203. break;
  204. }
  205. }
  206. RegCloseKey(hKey);
  207. }
  208. }
  209. else
  210. {
  211. if (RegOpenKeyEx(hKeyCU,"keyboard layout\\preload", 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
  212. {
  213. for (i=0; ; i++)
  214. {
  215. cbName = MAX_NAME;
  216. if (RegEnumKeyEx(hKey, i, szName, &cbName, 0, NULL, NULL, &ftLastWriteTime) == ERROR_NO_MORE_ITEMS)
  217. break;
  218. RegOpenKeyEx(hKey, szName, 0, KEY_ALL_ACCESS, &hSubKey);
  219. cbData = MAX_NAME;
  220. RegQueryValueEx(hSubKey, "", 0, NULL, Data, &cbData);
  221. RegCloseKey(hSubKey);
  222. if (lstrcmpi((const char *)Data,szKL) == 0)
  223. {
  224. RegDeleteKey(hKey, szName);
  225. break;
  226. }
  227. }
  228. RegCloseKey(hKey);
  229. }
  230. }
  231. RenumberPreload(hKeyCU);
  232. }
  233. /*---------------------------------------------------------------------------
  234. HKLHelpRemoveFromControlSet
  235. ---------------------------------------------------------------------------*/
  236. void HKLHelpRemoveFromControlSet(HKL hKL)
  237. {
  238. HKEY hKey;
  239. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,"System\\CurrentControlSet\\control\\keyboard layouts",0,KEY_ALL_ACCESS,&hKey) == ERROR_SUCCESS)
  240. {
  241. CHAR szKeyName[10];
  242. wsprintf(szKeyName, "%08x", hKL);
  243. RegDeleteKey(hKey, szKeyName);
  244. RegCloseKey(hKey);
  245. }
  246. }
  247. /*---------------------------------------------------------------------------
  248. HKLHelpRegisterIMEwithForcedHKL
  249. ---------------------------------------------------------------------------*/
  250. void HKLHelpRegisterIMEwithForcedHKL(HKL hKL, LPSTR szIMEFile, LPSTR szTitle)
  251. {
  252. CHAR szRegPath[MAX_PATH];
  253. DWORD dwDisposition;
  254. HKEY hKey;
  255. CHAR szIMEFileUpper[MAX_PATH];
  256. for (INT i = 0; szIMEFile[i] != 0; i++)
  257. szIMEFileUpper[i] = (CHAR)toupper(szIMEFile[i]);
  258. szIMEFileUpper[i] = 0;
  259. wsprintf(szRegPath, "System\\CurrentControlSet\\Control\\Keyboard Layouts\\%08x", hKL);
  260. if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, szRegPath, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition) == ERROR_SUCCESS)
  261. {
  262. RegSetValueEx(hKey, "Ime File", 0, REG_SZ, (LPBYTE)szIMEFileUpper, lstrlen(szIMEFile)+1);
  263. RegSetValueEx(hKey, "Layout Text", 0, REG_SZ, (LPBYTE)szTitle, lstrlen(szTitle)+1);
  264. RegCloseKey(hKey);
  265. }
  266. }
  267. /*---------------------------------------------------------------------------
  268. HKLHelpGetLayoutString
  269. ---------------------------------------------------------------------------*/
  270. void HKLHelpGetLayoutString(HKL hKL, LPSTR szLayoutString, DWORD *pcbSize)
  271. {
  272. CHAR szRegPath[MAX_PATH];
  273. HKEY hKey;
  274. wsprintf(szRegPath, "System\\CurrentControlSet\\Control\\Keyboard Layouts\\%08x", hKL);
  275. if(ERROR_SUCCESS==RegOpenKeyEx(HKEY_LOCAL_MACHINE, szRegPath, 0, KEY_READ, &hKey))
  276. {
  277. RegQueryValueEx(hKey, "Layout Text", NULL, NULL, (LPBYTE)szLayoutString, pcbSize);
  278. RegCloseKey(hKey);
  279. }
  280. }
  281. /*---------------------------------------------------------------------------
  282. HKLHelpSetDefaultKeyboardLayout
  283. ---------------------------------------------------------------------------*/
  284. void HKLHelpSetDefaultKeyboardLayout(HKEY hKeyHKCU, HKL hKL, BOOL fSetToDefault)
  285. {
  286. char szKL[20];
  287. BYTE Data[MAX_PATH];
  288. DWORD cbData;
  289. char szSubKey[MAX_PATH];
  290. HKEY hKey,hSubKey;
  291. DWORD NumKL;
  292. wsprintf(szKL, "%08x", hKL);
  293. if (IsNT())
  294. {
  295. RegOpenKeyEx(hKeyHKCU, "Keyboard Layout\\Preload", 0, KEY_ALL_ACCESS, &hKey);
  296. if (hKey != NULL)
  297. {
  298. RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &NumKL, NULL, NULL, NULL, NULL);
  299. for (DWORD i=0; i<NumKL; i++)
  300. {
  301. wsprintf(szSubKey, "%d", i+1);
  302. cbData = MAX_PATH;
  303. RegQueryValueEx(hKey, szSubKey, NULL, NULL, Data, &cbData);
  304. if (lstrcmpi((const char *)Data, szKL) == 0)
  305. break;
  306. }
  307. // if hKL is not exist create it.
  308. if (NumKL == i)
  309. {
  310. wsprintf(szSubKey,"%d",i+1);
  311. RegSetValueEx(hKey, szSubKey, 0, REG_SZ, (const unsigned char *)szKL, lstrlen(szKL)+1);
  312. NumKL++;
  313. }
  314. // Set hKL as first, Shift down other.
  315. if(fSetToDefault)
  316. {
  317. for(int j=i; j>0; j--)
  318. {
  319. wsprintf(szSubKey,"%d",j);
  320. cbData = MAX_PATH;
  321. RegQueryValueEx(hKey, szSubKey, NULL, NULL, Data, &cbData);
  322. wsprintf(szSubKey,"%d",j+1);
  323. RegSetValueEx(hKey, szSubKey, 0, REG_SZ, Data, cbData);
  324. }
  325. RegSetValueEx(hKey, "1", 0, REG_SZ, (const unsigned char *)szKL, lstrlen(szKL)+1);
  326. }
  327. RegCloseKey(hKey);
  328. }
  329. }
  330. else
  331. {
  332. RegOpenKeyEx(hKeyHKCU, "Keyboard Layout\\Preload", 0, KEY_ALL_ACCESS, &hKey);
  333. if (hKey != NULL)
  334. {
  335. RegQueryInfoKey(hKey, NULL, NULL, NULL, &NumKL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
  336. for (DWORD i=0; i<NumKL; i++)
  337. {
  338. wsprintf(szSubKey, "%d", i+1);
  339. RegOpenKeyEx(hKey, szSubKey, 0, KEY_ALL_ACCESS, &hSubKey);
  340. cbData = MAX_PATH;
  341. RegQueryValueEx(hSubKey, "", NULL, NULL, Data, &cbData);
  342. if (lstrcmpi((const char *)Data, szKL) == 0)
  343. break;
  344. RegCloseKey(hSubKey);
  345. }
  346. if (NumKL == i)
  347. {
  348. wsprintf(szSubKey,"%d",i+1);
  349. RegCreateKeyEx(hKey,szSubKey,0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hSubKey,NULL);
  350. RegSetValueEx(hSubKey,"",0,REG_SZ,(const unsigned char *)szKL,lstrlen(szKL)+1);
  351. RegCloseKey(hSubKey);
  352. NumKL++;
  353. }
  354. if(fSetToDefault)
  355. {
  356. for (int j=i; j>0; j--)
  357. {
  358. wsprintf(szSubKey, "%d", j);
  359. RegOpenKeyEx(hKey, szSubKey, 0, KEY_ALL_ACCESS, &hSubKey);
  360. cbData = MAX_PATH;
  361. RegQueryValueEx(hSubKey, "", NULL, NULL, Data, &cbData);
  362. RegCloseKey(hSubKey);
  363. wsprintf(szSubKey,"%d",j+1);
  364. RegOpenKeyEx(hKey, szSubKey, 0, KEY_ALL_ACCESS, &hSubKey);
  365. cbData = MAX_PATH;
  366. RegSetValueEx(hSubKey, "", 0, REG_SZ, Data, cbData);
  367. RegCloseKey(hSubKey);
  368. }
  369. RegOpenKeyEx(hKey, "1", 0, KEY_ALL_ACCESS, &hSubKey);
  370. RegSetValueEx(hSubKey, "", 0, REG_SZ, (const LPBYTE)szKL, lstrlen(szKL)+1);
  371. RegCloseKey(hSubKey);
  372. }
  373. RegCloseKey(hKey);
  374. }
  375. }
  376. (void)LoadKeyboardLayout(szKL, KLF_ACTIVATE | KLF_SETFORPROCESS);
  377. // To activate IME2002 right now without reboot.
  378. if(fSetToDefault)
  379. {
  380. (void)SystemParametersInfo(SPI_SETDEFAULTINPUTLANG, 0, (HKL*)&hKL, SPIF_SENDCHANGE);
  381. SwitcHKLtoIME61();
  382. }
  383. }
  384. /*---------------------------------------------------------------------------
  385. SetDefaultKeyboardLayout
  386. ---------------------------------------------------------------------------*/
  387. void SetDefaultKeyboardLayoutForDefaultUser(const HKL hKL)
  388. {
  389. char szKL[20];
  390. HKEY hKey, hSubKey;
  391. wsprintf(szKL,"%08x",hKL);
  392. if (!IsNT())
  393. {
  394. // Win9x has only one preload.
  395. RegOpenKeyEx(HKEY_USERS, ".Default\\Keyboard Layout\\Preload", 0, KEY_ALL_ACCESS, &hKey);
  396. RegOpenKeyEx(hKey, "1", 0, KEY_ALL_ACCESS, &hSubKey);
  397. RegSetValueEx(hSubKey, "", 0, REG_SZ, (const LPBYTE)szKL, lstrlen(szKL)+1);
  398. RegCloseKey(hSubKey);
  399. RegCloseKey(hKey);
  400. }
  401. }
  402. /*---------------------------------------------------------------------------
  403. AddPreload
  404. Add IME2002 to preload in given HKCU tree.
  405. If there's other old MS-IMEs, remove them from preload.
  406. If Korean keyboard layout was the default keyboard layout,
  407. set IME2002 as default keyboard layout.
  408. Given HKCU usually can be HKEY_CURRENT_USER or HKEY_USERS\.Default.
  409. ---------------------------------------------------------------------------*/
  410. BOOL AddPreload(HKEY hKeyCU, HKL hKL)
  411. {
  412. BOOL fKoreanWasDefault = fFalse;
  413. HKL hDefaultKL, hKLOldMSIME;
  414. // If there is no Kor IME exist in preload, we shouldn't add Kor IME.
  415. if (!HKLHelp412ExistInPreload(hKeyCU))
  416. return FALSE;
  417. hDefaultKL = GetDefaultIMEFromHKCU(hKeyCU);
  418. if (LOWORD(hDefaultKL) == 0x0412)
  419. fKoreanWasDefault = fTrue;
  420. // Win95 IME
  421. hKLOldMSIME = GetHKLfromHKLM("msime95.ime");
  422. if (hKLOldMSIME)
  423. {
  424. HKLHelpRemoveFromPreload(hKeyCU, hKLOldMSIME);
  425. RegFlushKey(hKeyCU);
  426. UnloadKeyboardLayout(hKLOldMSIME);
  427. }
  428. // NT4 IME
  429. hKLOldMSIME = GetHKLfromHKLM("msime95k.ime");
  430. if(NULL != hKLOldMSIME)
  431. {
  432. HKLHelpRemoveFromPreload(hKeyCU, hKLOldMSIME);
  433. RegFlushKey(hKeyCU);
  434. UnloadKeyboardLayout(hKLOldMSIME);
  435. }
  436. // Win98, ME, NT4 SP6 & W2K IME
  437. hKLOldMSIME = GetHKLfromHKLM("imekr98u.ime");
  438. if(NULL != hKLOldMSIME)
  439. {
  440. HKLHelpRemoveFromPreload(hKeyCU, hKLOldMSIME);
  441. RegFlushKey(hKeyCU);
  442. UnloadKeyboardLayout(hKLOldMSIME);
  443. }
  444. // Office 10 IME(6.0)
  445. hKLOldMSIME = GetHKLfromHKLM("imekr.ime");
  446. if(NULL != hKLOldMSIME)
  447. {
  448. HKLHelpRemoveFromPreload(hKeyCU, hKLOldMSIME);
  449. RegFlushKey(hKeyCU);
  450. UnloadKeyboardLayout(hKLOldMSIME);
  451. }
  452. if (hKL && hKL != hDefaultKL)
  453. HKLHelpSetDefaultKeyboardLayout(hKeyCU, hKL, fKoreanWasDefault);
  454. return (fKoreanWasDefault);
  455. }
  456. //////////////////////////////////////////////////////////////////////////////
  457. // Private functions
  458. void SortRegKeys(KeyNameType *hKLKeyList, KeyNameType *hKLList, INT Num)
  459. {
  460. KeyNameType hKeyTmp;
  461. INT PhaseCur, PhaseEnd;
  462. for (PhaseEnd=0; PhaseEnd < Num-1; PhaseEnd++)
  463. {
  464. for (PhaseCur = Num-1; PhaseCur > PhaseEnd; PhaseCur--)
  465. {
  466. if(atoi(hKLKeyList[PhaseCur]) < atoi(hKLKeyList[PhaseCur-1]))
  467. {
  468. StringCchCopy(hKeyTmp, MAX_NAME, hKLKeyList[PhaseCur-1]);
  469. StringCchCopy(hKLKeyList[PhaseCur-1], MAX_NAME, hKLKeyList[PhaseCur]);
  470. StringCchCopy(hKLKeyList[PhaseCur], MAX_NAME, hKeyTmp);
  471. StringCchCopy(hKeyTmp, MAX_NAME, hKLList[PhaseCur-1]);
  472. StringCchCopy(hKLList[PhaseCur-1], MAX_NAME, hKLList[PhaseCur]);
  473. StringCchCopy(hKLList[PhaseCur], MAX_NAME, hKeyTmp);
  474. }
  475. }
  476. }
  477. }
  478. void RenumberPreload(HKEY hKeyCU)
  479. {
  480. int i, j, k;
  481. DWORD cbName,cbData;
  482. char Name[MAX_NAME];
  483. BYTE Data[MAX_NAME];
  484. FILETIME ftLastWriteTime;
  485. HKEY hKey,hSubKey;
  486. char szNum[10];
  487. DWORD dwDisposition,MaxValue;
  488. KeyNameType *hKLKeyList,*hKLList;
  489. if(IsNT())
  490. {
  491. RegOpenKeyEx(hKeyCU,"keyboard layout\\preload",0,KEY_ALL_ACCESS,&hKey);
  492. if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &MaxValue, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
  493. {
  494. RegCloseKey(hKey);
  495. return;
  496. }
  497. hKLKeyList = (KeyNameType *)GlobalAllocPtr(GHND, sizeof(KeyNameType)*MaxValue);
  498. if (hKLKeyList == NULL)
  499. {
  500. RegCloseKey(hKey);
  501. return;
  502. }
  503. hKLList = (KeyNameType *)GlobalAllocPtr(GHND, sizeof(KeyNameType)*MaxValue);
  504. if (hKLList == NULL)
  505. {
  506. GlobalFreePtr(hKLKeyList);
  507. RegCloseKey(hKey);
  508. return;
  509. }
  510. for (j=0; ;j++)
  511. {
  512. cbName = MAX_NAME;
  513. cbData = MAX_NAME;
  514. if (RegEnumValue(hKey, j, Name, &cbName, NULL, NULL, Data, &cbData) == ERROR_NO_MORE_ITEMS)
  515. break;
  516. StringCchCopy(hKLList[j], MAX_NAME, (const char *)Data);
  517. StringCchCopy(hKLKeyList[j], MAX_NAME, Name);
  518. }
  519. for (k=0; k<j; k++)
  520. RegDeleteValue(hKey, hKLKeyList[k]);
  521. SortRegKeys(hKLKeyList, hKLList, j);
  522. for (k=0; k<j; k++)
  523. {
  524. wsprintf(szNum,"%d",k+1);
  525. RegSetValueEx(hKey, szNum, 0, REG_SZ, (const unsigned char *)hKLList[k], lstrlen(hKLList[k])+1);
  526. }
  527. RegCloseKey(hKey);
  528. GlobalFreePtr(hKLList);
  529. GlobalFreePtr(hKLKeyList);
  530. }
  531. else
  532. {
  533. RegOpenKeyEx(hKeyCU,"keyboard layout\\preload",0,KEY_ALL_ACCESS,&hKey);
  534. if (RegQueryInfoKey(hKey, NULL, NULL, NULL, &MaxValue, NULL, NULL,NULL,NULL,NULL,NULL,NULL) != ERROR_SUCCESS)
  535. {
  536. RegCloseKey(hKey);
  537. return;
  538. }
  539. hKLKeyList = (KeyNameType *)GlobalAllocPtr(GHND,sizeof(KeyNameType)*MaxValue);
  540. hKLList = (KeyNameType *)GlobalAllocPtr(GHND,sizeof(KeyNameType)*MaxValue);
  541. if (hKLKeyList == NULL || hKLList == NULL)
  542. return;
  543. for (i=0; ;i++)
  544. {
  545. cbName = MAX_NAME;
  546. if (RegEnumKeyEx(hKey, i, Name, &cbName, 0, NULL, NULL, &ftLastWriteTime) == ERROR_NO_MORE_ITEMS)
  547. break;
  548. RegOpenKeyEx(hKey, Name, 0, KEY_ALL_ACCESS, &hSubKey);
  549. cbData = MAX_NAME;
  550. RegQueryValueEx(hSubKey, "", 0, NULL, Data, &cbData);
  551. RegCloseKey(hSubKey);
  552. StringCchCopy(hKLList[i], MAX_NAME, (const char *)Data);
  553. StringCchCopy(hKLKeyList[i], MAX_NAME, Name);
  554. }
  555. for(k=0; k<i; k++)
  556. RegDeleteKey(hKey, hKLKeyList[k]);
  557. SortRegKeys(hKLKeyList, hKLList, i);
  558. for(k=0; k<i; k++)
  559. {
  560. wsprintf(szNum,"%d",k+1);
  561. RegCreateKeyEx(hKey, szNum, 0, "",REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hSubKey, &dwDisposition);
  562. RegSetValueEx(hSubKey, "", 0, REG_SZ, (const unsigned char *)hKLList[k], lstrlen(hKLList[k])+1);
  563. RegCloseKey(hSubKey);
  564. }
  565. RegCloseKey(hKey);
  566. GlobalFreePtr(hKLList);
  567. GlobalFreePtr(hKLKeyList);
  568. }
  569. }
  570. BOOL CALLBACK EnumChildProcForSwitchKL(HWND hWnd, LPARAM lParam)
  571. {
  572. if (TRUE/*IsWindowVisible( hWnd )*/)
  573. {
  574. HKL hKL = (HKL)lParam;
  575. PostMessage(hWnd, WM_INPUTLANGCHANGEREQUEST, 1/*INPUTLANGCHANGE_SYSCHARSET*/, (LPARAM)hKL); // change kl to IME8.1
  576. }
  577. return TRUE;
  578. }
  579. BOOL CALLBACK EnumProcForSwitchKL(HWND hWnd, LPARAM lParam)
  580. {
  581. if (TRUE/*IsWindowVisible( hWnd )*/)
  582. {
  583. HKL hKL = (HKL)lParam;
  584. PostMessage(hWnd, WM_INPUTLANGCHANGEREQUEST, 1/*INPUTLANGCHANGE_SYSCHARSET*/, (LPARAM)hKL);
  585. // try child windows
  586. EnumChildWindows(hWnd, EnumChildProcForSwitchKL, lParam);
  587. }
  588. return TRUE;
  589. }
  590. void SwitcHKLtoIME61()
  591. {
  592. HKL hKL = NULL;
  593. HWND hWnd = NULL;
  594. //
  595. // switch hKL to IME6.1
  596. //
  597. hKL = GetHKLfromHKLM(TEXT("imekr61.ime")); // find IME6.1 kl
  598. if (hKL != NULL)
  599. {
  600. //
  601. // desktop (special)
  602. //
  603. hWnd = FindWindow("Progman", NULL); // find desktop window
  604. if (hWnd!= NULL)
  605. PostMessage(hWnd, WM_INPUTLANGCHANGEREQUEST, 1/*INPUTLANGCHANGE_SYSCHARSET*/, (LPARAM)hKL);
  606. //
  607. // generic enum
  608. //
  609. EnumWindows(EnumProcForSwitchKL, (LPARAM)hKL);
  610. }
  611. }