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.

1926 lines
47 KiB

  1. #include "private.h"
  2. #include "globals.h"
  3. #include "internat.h"
  4. #include "strary.h"
  5. #include "xstring.h"
  6. #include "immxutil.h"
  7. #include "cregkey.h"
  8. #include "cmydc.h"
  9. #include "assembly.h"
  10. CStructArray<MLNGINFO> *g_pMlngInfo = NULL;
  11. const TCHAR c_szDefaultUserPreload[] = TEXT(".DEFAULT\\Keyboard Layout\\Preload");
  12. const TCHAR c_szPreload[] = TEXT("Keyboard Layout\\Preload");
  13. const TCHAR c_szSubst[] = TEXT("Keyboard Layout\\Substitutes");
  14. //////////////////////////////////////////////////////////////////////////////
  15. //
  16. // CStaticIconList
  17. //
  18. //////////////////////////////////////////////////////////////////////////////
  19. class CStaticIconList
  20. {
  21. public:
  22. void Init(int cx, int cy);
  23. void RemoveAll(BOOL fInUninit);
  24. BOOL IsInited()
  25. {
  26. return _cx != 0;
  27. }
  28. int AddIcon(HICON hicon);
  29. HICON ExtractIcon(int i);
  30. void GetIconSize(int *cx, int *cy);
  31. int GetImageCount();
  32. private:
  33. static int _cx;
  34. static int _cy;
  35. static CStructArray<HICON> *_prgIcons;
  36. };
  37. CStaticIconList g_IconList;
  38. int CStaticIconList::_cx = 0;
  39. int CStaticIconList::_cy = 0;
  40. CStructArray<HICON> *CStaticIconList::_prgIcons = NULL;
  41. //+---------------------------------------------------------------------------
  42. //
  43. // Init
  44. //
  45. //----------------------------------------------------------------------------
  46. inline void CStaticIconList::Init(int cx, int cy)
  47. {
  48. CicEnterCriticalSection(g_cs);
  49. _cx = cx;
  50. _cy = cy;
  51. CicLeaveCriticalSection(g_cs);
  52. }
  53. //+---------------------------------------------------------------------------
  54. //
  55. // RemoveAll
  56. //
  57. //----------------------------------------------------------------------------
  58. void CStaticIconList::RemoveAll(BOOL fInUninit)
  59. {
  60. int i;
  61. //
  62. // don't have to enter g_cs if we're in DllMain(PROCESS_DETATCH).
  63. //
  64. if (!fInUninit)
  65. CicEnterCriticalSection(g_cs);
  66. if (_prgIcons == NULL)
  67. goto Exit;
  68. for (i=0; i<_prgIcons->Count(); i++)
  69. {
  70. DestroyIcon(*_prgIcons->GetPtr(i));
  71. }
  72. delete _prgIcons;
  73. _prgIcons = NULL;
  74. Exit:
  75. if (!fInUninit)
  76. CicLeaveCriticalSection(g_cs);
  77. }
  78. //+---------------------------------------------------------------------------
  79. //
  80. // AddIcon
  81. //
  82. //----------------------------------------------------------------------------
  83. inline int CStaticIconList::AddIcon(HICON hicon)
  84. {
  85. HICON hIconCopy;
  86. HICON *pIconDst;
  87. int nRet = -1;
  88. CicEnterCriticalSection(g_cs);
  89. if (!_prgIcons)
  90. _prgIcons = new CStructArray<HICON>;
  91. if (!_prgIcons)
  92. goto Exit;
  93. if ((pIconDst = _prgIcons->Append(1)) == NULL)
  94. goto Exit;
  95. if ((hIconCopy = CopyIcon(hicon)) == 0)
  96. {
  97. _prgIcons->Remove(_prgIcons->Count()-1, 1);
  98. goto Exit;
  99. }
  100. *pIconDst = hIconCopy;
  101. nRet = _prgIcons->Count()-1;
  102. Exit:
  103. CicLeaveCriticalSection(g_cs);
  104. return nRet;
  105. }
  106. //+---------------------------------------------------------------------------
  107. //
  108. // ExtractIcon
  109. //
  110. //----------------------------------------------------------------------------
  111. inline HICON CStaticIconList::ExtractIcon(int i)
  112. {
  113. HICON hIcon = NULL;
  114. CicEnterCriticalSection(g_cs);
  115. if (!_prgIcons)
  116. goto Exit;
  117. if (i >= _prgIcons->Count() || i < 0)
  118. goto Exit;
  119. hIcon = CopyIcon(*_prgIcons->GetPtr(i));
  120. Exit:
  121. CicLeaveCriticalSection(g_cs);
  122. return hIcon;
  123. }
  124. //+---------------------------------------------------------------------------
  125. //
  126. // GetIconSize
  127. //
  128. //----------------------------------------------------------------------------
  129. inline void CStaticIconList::GetIconSize(int *cx, int *cy)
  130. {
  131. CicEnterCriticalSection(g_cs);
  132. *cx = _cx;
  133. *cy = _cy;
  134. CicLeaveCriticalSection(g_cs);
  135. }
  136. //+---------------------------------------------------------------------------
  137. //
  138. // GetImageCount
  139. //
  140. //----------------------------------------------------------------------------
  141. inline int CStaticIconList::GetImageCount()
  142. {
  143. int nRet = 0;
  144. CicEnterCriticalSection(g_cs);
  145. if (_prgIcons == NULL)
  146. goto Exit;
  147. nRet = _prgIcons->Count();
  148. Exit:
  149. CicLeaveCriticalSection(g_cs);
  150. return nRet;
  151. }
  152. //////////////////////////////////////////////////////////////////////////////
  153. //
  154. // UninitINAT
  155. //
  156. //////////////////////////////////////////////////////////////////////////////
  157. void UninitINAT()
  158. {
  159. g_IconList.RemoveAll(TRUE);
  160. if (g_pMlngInfo)
  161. {
  162. delete g_pMlngInfo;
  163. g_pMlngInfo = NULL;
  164. }
  165. }
  166. //////////////////////////////////////////////////////////////////////////////
  167. //
  168. // InterNAT icon APIs
  169. //
  170. //////////////////////////////////////////////////////////////////////////////
  171. #if 0
  172. //
  173. // ISO 639:1988 Code.
  174. //
  175. //
  176. // Under NT, we use GetLocaleInfoNTString(). It returns ISO 3166.
  177. //
  178. INATSYMBOL symInatSymbols[] =
  179. {
  180. {0x0436, "AF"}, // Afrikaans
  181. {0x041c, "SQ"}, // Albanian
  182. {0x0401, "AR"}, // Arabic
  183. {0x042d, "EU"}, // Basque
  184. {0x0423, "BE"}, // Byelorus
  185. {0x0402, "BG"}, // Bulgaria
  186. {0x0403, "CA"}, // Catalan
  187. {0x0404, "CH"}, // China #1
  188. {0x0804, "CH"}, // China #2
  189. //#ifdef WINDOWS_PE
  190. #if 1
  191. {0x041a, "HR"}, // Croatian
  192. #else
  193. {0x041a, "SH"}, // Croatian
  194. #endif
  195. {0x0405, "CZ"}, // Czech
  196. {0x0406, "DA"}, // Danish
  197. {0x0413, "NL"}, // Dutch
  198. {0x0813, "NL"}, // Dutch
  199. {0x0409, "EN"}, // English
  200. {0x0809, "EN"}, // English
  201. {0x0c09, "EN"}, // English
  202. {0x1009, "EN"}, // English
  203. {0x1409, "EN"}, // English
  204. {0x1809, "EN"}, // English
  205. {0x0425, "ET"}, // Estonian
  206. {0x0429, "FA"}, // Farsi
  207. {0x040b, "FI"}, // Finnish
  208. {0x040c, "FR"}, // French
  209. {0x080c, "FR"}, // French
  210. {0x0c0c, "FR"}, // French
  211. {0x0407, "DE"}, // German
  212. {0x0807, "DE"}, // German
  213. {0x0c07, "DE"}, // German
  214. {0x1007, "DE"}, // German
  215. {0x1407, "DE"}, // German
  216. {0x0408, "GR"}, // Greek
  217. {0x040d, "HE"}, // Hebrew
  218. {0x040e, "HU"}, // Hungary
  219. {0x040f, "IS"}, // Iceland
  220. {0x0421, "BA"}, // Indonesia
  221. {0x0410, "IT"}, // Italy
  222. {0x0810, "IT"}, // Italy
  223. {0x0411, "JA"}, // Japan
  224. {0x0412, "KO"}, // Korea
  225. {0x0426, "LV"}, // Latvian
  226. {0x0427, "LT"}, // Lithuanian
  227. {0x042f, "MK"}, // Former Yugoslav Republic of Macedonia
  228. {0x0414, "NO"}, // Norway
  229. {0x0814, "NO"}, // Norway
  230. {0x0415, "PL"}, // Poland
  231. {0x0416, "PT"}, // Portugal
  232. {0x0816, "PT"}, // Portugal
  233. {0x0417, "RM"}, // Rhaeto
  234. {0x0418, "RO"}, // Romanian
  235. {0x0818, "RO"}, // Romanian
  236. {0x0419, "RU"}, // Russian
  237. {0x0819, "RU"}, // Russian
  238. {0x081a, "SR"}, // Serbian
  239. //#ifdef WINDOWS_PE
  240. #if 1
  241. {0x0c1a, "SR"}, // Serbian
  242. #endif
  243. {0x041b, "SK"}, // Slovakian
  244. {0x0424, "SL"}, // Slovenian
  245. {0x042e, "SB"}, // Sorbian
  246. {0x040a, "ES"}, // Spanish
  247. {0x080a, "ES"}, // Spanish
  248. {0x0c0a, "ES"}, // Spanish
  249. {0x041d, "SV"}, // Swedish
  250. {0x041e, "TH"}, // Thai
  251. {0x041f, "TR"}, // Turkish
  252. {0x0422, "UK"}, // Ukranian
  253. {0x0420, "UR"}, // Urdu
  254. {0x0033, "VE"}, // Venda
  255. {0x042a, "VN"}, // Vietnamese
  256. {0x0034, "XH"}, // Xhosa
  257. {0x0035, "ZU"}, // Zulu
  258. {0x002b, "ST"}, // Sutu
  259. {0x002e, "TS"}, // Tsona
  260. {0x002f, "TN"}, // Tswana
  261. {0x0000, "??"}
  262. } ;
  263. #define NSYMBOLS ((sizeof(symInatSymbols) / sizeof(INATSYMBOL))-1)
  264. #endif
  265. static const TCHAR c_szLayoutPath[] = TEXT("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts");
  266. static const TCHAR c_szLayoutText[] = TEXT("layout text");
  267. static const TCHAR c_szLayoutID[] = TEXT("layout id");
  268. static const WCHAR c_szMUILayoutTextW[] = L"Layout Display Name";
  269. static const WCHAR c_szLayoutTextW[] = L"layout text";
  270. static const char c_szNamesPath[] = "system\\currentcontrolset\\control\\nls\\Locale";
  271. //+---------------------------------------------------------------------------
  272. //
  273. // GetLocaleInfoString
  274. //
  275. // this is not a general wrapper for GetLocaleInfo!
  276. // LCTYPE must be LOCALE_SABBREVLANGNAME or LOCALE_SLANGUAGE.
  277. //
  278. //----------------------------------------------------------------------------
  279. int GetLocaleInfoString(LCID lcid, LCTYPE lcType, char *psz, int cch)
  280. {
  281. WCHAR achW[64];
  282. Assert((lcType & LOCALE_SLANGUAGE) || (lcType & LOCALE_SABBREVLANGNAME));
  283. if (IsOnNT())
  284. {
  285. if (GetLocaleInfoW(lcid, lcType, achW, ARRAYSIZE(achW)))
  286. {
  287. return WideCharToMultiByte(CP_ACP, 0, achW, -1, psz, cch, NULL, NULL);
  288. }
  289. }
  290. else
  291. {
  292. return GetLocaleInfo(lcid, lcType, psz, cch);
  293. }
  294. return 0;
  295. }
  296. //+---------------------------------------------------------------------------
  297. //
  298. // InatCreateIcon
  299. //
  300. //+---------------------------------------------------------------------------
  301. HICON InatCreateIcon(WORD langID)
  302. {
  303. LOGFONT lf;
  304. UINT cxSmIcon;
  305. UINT cySmIcon;
  306. cxSmIcon = GetSystemMetrics( SM_CXSMICON );
  307. cySmIcon = GetSystemMetrics( SM_CYSMICON );
  308. if( !SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0))
  309. return NULL;
  310. if (cySmIcon < GetPhysicalFontHeight(lf))
  311. {
  312. lf.lfHeight = 0 - ((int)cySmIcon * 7 / 10);
  313. lf.lfWidth = 0;
  314. }
  315. return InatCreateIconBySize(langID, cxSmIcon, cySmIcon, &lf);
  316. }
  317. //+---------------------------------------------------------------------------
  318. //
  319. // InatCreateIconBySize
  320. //
  321. //+---------------------------------------------------------------------------
  322. HICON InatCreateIconBySize(WORD langID, int cxSmIcon, int cySmIcon, LOGFONT *plf)
  323. {
  324. HBITMAP hbmColour;
  325. HBITMAP hbmMono;
  326. HBITMAP hbmOld;
  327. HICON hicon = NULL;
  328. ICONINFO ii;
  329. RECT rc;
  330. DWORD rgbText;
  331. DWORD rgbBk = 0;
  332. HDC hdc;
  333. HDC hdcScreen;
  334. HFONT hfont;
  335. HFONT hfontOld;
  336. TCHAR szData[20];
  337. //
  338. // Get the indicator by using the first 2 characters of the
  339. // abbreviated language name.
  340. //
  341. if (GetLocaleInfoString( MAKELCID(langID, SORT_DEFAULT),
  342. LOCALE_SABBREVLANGNAME | LOCALE_NOUSEROVERRIDE,
  343. szData,
  344. sizeof(szData) / sizeof(TCHAR) ))
  345. {
  346. //
  347. // Make Uppercase
  348. //
  349. if (!IsOnNT())
  350. {
  351. szData[0] -= 0x20;
  352. szData[1] -= 0x20;
  353. }
  354. //
  355. // Only use the first two characters.
  356. //
  357. szData[2] = TEXT('\0');
  358. }
  359. else
  360. {
  361. //
  362. // Id wasn't found. Use question marks.
  363. //
  364. szData[0] = TEXT('?');
  365. szData[1] = TEXT('?');
  366. szData[2] = TEXT('\0');
  367. }
  368. if( (hfont = CreateFontIndirect(plf)) )
  369. {
  370. hdcScreen = GetDC(NULL);
  371. hdc = CreateCompatibleDC(hdcScreen);
  372. hbmColour = CreateCompatibleBitmap(hdcScreen, cxSmIcon, cySmIcon);
  373. ReleaseDC( NULL, hdcScreen);
  374. if (hbmColour && hdc)
  375. {
  376. hbmMono = CreateBitmap(cxSmIcon, cySmIcon, 1, 1, NULL);
  377. if (hbmMono)
  378. {
  379. hbmOld = (HBITMAP)SelectObject( hdc, hbmColour);
  380. rc.left = 0;
  381. rc.top = 0;
  382. rc.right = cxSmIcon;
  383. rc.bottom = cySmIcon;
  384. rgbBk = SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
  385. rgbText = SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
  386. ExtTextOut( hdc, rc.left, rc.top, ETO_OPAQUE, &rc, "", 0, NULL);
  387. hfontOld = (HFONT)SelectObject( hdc, hfont);
  388. DrawText(hdc,
  389. szData,
  390. 2,
  391. &rc,
  392. DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  393. SelectObject( hdc, hbmMono);
  394. PatBlt(hdc, 0, 0, cxSmIcon, cySmIcon, BLACKNESS);
  395. ii.fIcon = TRUE;
  396. ii.xHotspot = 0;
  397. ii.yHotspot = 0;
  398. ii.hbmColor = hbmColour;
  399. ii.hbmMask = hbmMono;
  400. hicon = CreateIconIndirect(&ii);
  401. SelectObject(hdc, hbmOld);
  402. DeleteObject(hbmMono);
  403. SelectObject(hdc, hfontOld);
  404. }
  405. }
  406. DeleteObject(hbmColour);
  407. DeleteDC(hdc);
  408. DeleteObject(hfont);
  409. }
  410. return hicon;
  411. }
  412. //+---------------------------------------------------------------------------
  413. //
  414. // GetIconFromFile
  415. //
  416. //+---------------------------------------------------------------------------
  417. HICON GetIconFromFile(int cx, int cy, WCHAR *lpszFileName, UINT uIconIndex)
  418. {
  419. return GetIconFromFileA(cx, cy, WtoA(lpszFileName), uIconIndex);
  420. }
  421. //+---------------------------------------------------------------------------
  422. //
  423. // GetIconFromFileA
  424. //
  425. //+---------------------------------------------------------------------------
  426. HICON GetIconFromFileA(int cx, int cy, char *lpszFileName, UINT uIconIndex)
  427. {
  428. HICON hicon = NULL;
  429. if (cx > GetSystemMetrics(SM_CXSMICON))
  430. {
  431. ExtractIconEx(lpszFileName, uIconIndex, &hicon, NULL, 1);
  432. }
  433. else
  434. {
  435. ExtractIconEx(lpszFileName, uIconIndex, NULL, &hicon, 1);
  436. }
  437. return hicon;
  438. }
  439. //+---------------------------------------------------------------------------
  440. //
  441. // CLayoutsSharedMem
  442. //
  443. //+---------------------------------------------------------------------------
  444. extern CCicMutex g_mutexLayouts;
  445. extern char g_szLayoutsCache[];
  446. class CLayoutsSharedMem : public CCicFileMappingStatic
  447. {
  448. public:
  449. void Init()
  450. {
  451. CCicFileMappingStatic::Init(g_szLayoutsCache, &g_mutexLayouts);
  452. }
  453. BOOL Start(UINT nNum)
  454. {
  455. BOOL fAlreadyExists;
  456. CCicSecAttr sa;
  457. if (Create(sa, sizeof(LAYOUT) * nNum, &fAlreadyExists) == NULL)
  458. return FALSE;
  459. return TRUE;
  460. }
  461. LAYOUT *GetPtr() { return (LAYOUT *)_pv; }
  462. };
  463. CLayoutsSharedMem g_smLayouts;
  464. //+---------------------------------------------------------------------------
  465. //
  466. // UninitLayoutMappedFile();
  467. //
  468. //----------------------------------------------------------------------------
  469. void UninitLayoutMappedFile()
  470. {
  471. g_smLayouts.Uninit();
  472. }
  473. //+---------------------------------------------------------------------------
  474. //
  475. // LoadKeyboardLayouts
  476. //
  477. //----------------------------------------------------------------------------
  478. BOOL LoadKeyboardLayouts()
  479. {
  480. CMyRegKey key;
  481. DWORD dwIndex;
  482. BOOL bRet = FALSE;
  483. TCHAR szValue[MAX_PATH]; // language id (number)
  484. WCHAR szValueW[MAX_PATH];
  485. TCHAR szData[MAX_PATH]; // language name
  486. CStructArray<LAYOUT> *pLayouts = NULL;
  487. LAYOUT *pLayout;
  488. BOOL bLoadedLayout;
  489. pLayouts = new CStructArray<LAYOUT>;
  490. if (!pLayouts)
  491. return FALSE;
  492. //
  493. // Now read all the locales from the registry.
  494. //
  495. if (key.Open(HKEY_LOCAL_MACHINE, c_szLayoutPath, KEY_READ) != ERROR_SUCCESS)
  496. {
  497. goto Exit;
  498. }
  499. dwIndex = 0;
  500. szValue[0] = TEXT('\0');
  501. while (key.EnumKey(dwIndex, szValue, ARRAYSIZE(szValue)) == ERROR_SUCCESS)
  502. {
  503. CRegKeyMUI key1;
  504. pLayout = pLayouts->Append(1);
  505. if (!pLayout)
  506. goto Exit;
  507. pLayout->dwID = AsciiToNum(szValue);
  508. if (StringCchPrintf(szData, ARRAYSIZE(szData), "%s\\%s", c_szLayoutPath, szValue) != S_OK)
  509. goto Next;
  510. if (key1.Open(HKEY_LOCAL_MACHINE, szData, KEY_READ) == S_OK)
  511. {
  512. //
  513. // Get the layout name.
  514. //
  515. szValue[0] = TEXT('\0');
  516. bLoadedLayout = FALSE;
  517. if (IsOnNT())
  518. {
  519. szValueW[0] = 0;
  520. if (key1.QueryValueCchW(szValueW,
  521. c_szMUILayoutTextW,
  522. ARRAYSIZE(szValueW)) == S_OK)
  523. {
  524. bLoadedLayout = TRUE;
  525. }
  526. else if (key1.QueryValueCchW(szValueW,
  527. c_szLayoutTextW,
  528. ARRAYSIZE(szValueW)) == S_OK)
  529. {
  530. bLoadedLayout = TRUE;
  531. }
  532. if (bLoadedLayout)
  533. {
  534. wcsncpy(pLayout->wszText,
  535. szValueW,
  536. ARRAYSIZE(pLayout->wszText));
  537. }
  538. }
  539. else
  540. {
  541. if (key1.QueryValueCch(szValue,
  542. c_szLayoutText,
  543. ARRAYSIZE(szValue)) == S_OK)
  544. {
  545. wcsncpy(pLayout->wszText,
  546. AtoW(szValue),
  547. ARRAYSIZE(pLayout->wszText));
  548. bLoadedLayout = TRUE;
  549. }
  550. }
  551. if (bLoadedLayout)
  552. {
  553. szValue[0] = TEXT('\0');
  554. pLayout->iSpecialID = 0;
  555. if (key1.QueryValueCch(szValue,
  556. c_szLayoutID,
  557. ARRAYSIZE(szValue)) == S_OK)
  558. {
  559. //
  560. // This may not exist!
  561. //
  562. pLayout->iSpecialID = (UINT)AsciiToNum(szValue);
  563. }
  564. }
  565. }
  566. Next:
  567. dwIndex++;
  568. szValue[0] = TEXT('\0');
  569. }
  570. pLayout = pLayouts->Append(1);
  571. if (!pLayout)
  572. goto Exit;
  573. memset(pLayout, 0, sizeof(LAYOUT));
  574. if (!g_smLayouts.Enter())
  575. goto Exit;
  576. g_smLayouts.Close();
  577. if (g_smLayouts.Start(pLayouts->Count()))
  578. {
  579. if (g_smLayouts.GetPtr())
  580. {
  581. memcpy(g_smLayouts.GetPtr(),
  582. pLayouts->GetPtr(0),
  583. pLayouts->Count() * sizeof(LAYOUT));
  584. bRet = TRUE;
  585. }
  586. }
  587. g_smLayouts.Leave();
  588. Exit:
  589. if (pLayouts)
  590. delete pLayouts;
  591. return bRet;
  592. }
  593. //+---------------------------------------------------------------------------
  594. //
  595. // FindLayoutEntry
  596. //
  597. // Gets the name of the given layout.
  598. //
  599. //+---------------------------------------------------------------------------
  600. UINT FindLayoutEntry( LAYOUT *pLayout, DWORD dwLayout )
  601. {
  602. UINT ctr = 0;
  603. UINT id;
  604. WORD wLayout = HIWORD(dwLayout);
  605. BOOL bIsIME = ((HIWORD(dwLayout) & 0xf000) == 0xe000) ? TRUE : FALSE;
  606. //
  607. // Find the layout in the global structure.
  608. //
  609. if ((wLayout & 0xf000) == 0xf000)
  610. {
  611. //
  612. // Layout is special, need to search for the ID
  613. // number.
  614. //
  615. id = wLayout & 0x0fff;
  616. ctr = 0;
  617. while (pLayout[ctr].dwID)
  618. {
  619. if (id == pLayout[ctr].iSpecialID)
  620. {
  621. break;
  622. }
  623. ctr++;
  624. }
  625. }
  626. else
  627. {
  628. ctr = 0;
  629. while (pLayout[ctr].dwID)
  630. {
  631. //
  632. // If it is IME, needs to be DWORD comparison.
  633. //
  634. if (IsOnFE() && bIsIME && (dwLayout == pLayout[ctr].dwID))
  635. {
  636. break;
  637. }
  638. else if (wLayout == LOWORD(pLayout[ctr].dwID))
  639. {
  640. break;
  641. }
  642. ctr++;
  643. }
  644. }
  645. return ctr;
  646. }
  647. //+---------------------------------------------------------------------------
  648. //
  649. // GetKbdLayoutName
  650. //
  651. // Gets the name of the given layout.
  652. //
  653. //+---------------------------------------------------------------------------
  654. void GetKbdLayoutName( DWORD dwLayout, WCHAR *pBuffer, int nBufSize)
  655. {
  656. UINT ctr;
  657. LAYOUT *pLayout;
  658. *pBuffer = L'\0';
  659. if (!g_smLayouts.Enter())
  660. return;
  661. g_smLayouts.Close();
  662. g_smLayouts.Init();
  663. if (!g_smLayouts.Open())
  664. {
  665. if (!LoadKeyboardLayouts())
  666. {
  667. Assert(0);
  668. }
  669. }
  670. pLayout = g_smLayouts.GetPtr();
  671. if (!pLayout)
  672. goto Exit;
  673. ctr = FindLayoutEntry( pLayout, dwLayout );
  674. //
  675. // Make sure there is a match. If not, then simply return without
  676. // copying anything.
  677. //
  678. if (pLayout[ctr].dwID)
  679. {
  680. //
  681. // Separate the Input Locale name and the Layout name with " - ".
  682. //
  683. #ifdef ATTACH_LAYOUTNAME
  684. pBuffer[0] = L' ';
  685. pBuffer[1] = L'-';
  686. pBuffer[2] = L' ';
  687. wcsncpy(pBuffer + 3, pLayout[ctr].wszText, nBufSize - 3);
  688. #else
  689. wcsncpy(pBuffer, pLayout[ctr].wszText, nBufSize);
  690. #endif
  691. }
  692. Exit:
  693. g_smLayouts.Leave();
  694. }
  695. //+---------------------------------------------------------------------------
  696. //
  697. // GetKbdLayoutId
  698. //
  699. // Gets the name of the given layout.
  700. //
  701. //+---------------------------------------------------------------------------
  702. DWORD GetKbdLayoutId( DWORD dwLayout)
  703. {
  704. UINT ctr;
  705. DWORD dwId = 0;
  706. LAYOUT *pLayout;
  707. if (!g_smLayouts.Enter())
  708. return 0;
  709. g_smLayouts.Close();
  710. g_smLayouts.Init();
  711. if (!g_smLayouts.Open())
  712. LoadKeyboardLayouts();
  713. pLayout = g_smLayouts.GetPtr();
  714. if (!pLayout)
  715. goto Exit;
  716. ctr = FindLayoutEntry( pLayout, dwLayout );
  717. //
  718. // Make sure there is a match. If not, then simply return without
  719. // copying anything.
  720. //
  721. dwId = pLayout[ctr].dwID;
  722. Exit:
  723. g_smLayouts.Leave();
  724. return dwId;
  725. }
  726. //+---------------------------------------------------------------------------
  727. //
  728. // GetLocaleInfoString
  729. //
  730. // this is not a general wrapper for GetLocaleInfo!
  731. // LCTYPE must be LOCALE_SABBREVLANGNAME or LOCALE_SLANGUAGE.
  732. //
  733. //----------------------------------------------------------------------------
  734. ULONG GetLocaleInfoString(HKL hKL, WCHAR *pszRegText, int nSize)
  735. {
  736. ULONG cb = 0;
  737. DWORD dwRegValue = (DWORD)((LONG_PTR)(hKL) & 0x0000FFFF);
  738. *pszRegText = L'\0';
  739. if (IsOnNT())
  740. {
  741. if (!GetLocaleInfoW(dwRegValue, LOCALE_SLANGUAGE, pszRegText, nSize))
  742. {
  743. *pszRegText = L'\0';
  744. }
  745. //
  746. // Attach the Layout name if it's not the default.
  747. //
  748. if (HIWORD(hKL) != LOWORD(hKL))
  749. {
  750. #ifdef ATTACH_LAYOUTNAME
  751. WCHAR *pszRT = pszRegText + wcslen(pszRegText);
  752. //
  753. // Pass DWORD value for IME.
  754. //
  755. GetKbdLayoutName((DWORD)(LONG_PTR)hKL,
  756. pszRT,
  757. nSize - (DWORD)(pszRT - pszRegText));
  758. #else
  759. GetKbdLayoutName((DWORD)(LONG_PTR)hKL, pszRegText, nSize);
  760. #endif
  761. }
  762. }
  763. else
  764. {
  765. CMyRegKey key;
  766. char szRegKey[128];
  767. char szRegText[128];
  768. StringCchPrintf(szRegKey, ARRAYSIZE(szRegKey),"%8.8lx", (DWORD)dwRegValue);
  769. *pszRegText = '\0';
  770. if(key.Open(HKEY_LOCAL_MACHINE,c_szNamesPath, KEY_READ)==ERROR_SUCCESS)
  771. {
  772. if(key.QueryValueCch(szRegText, szRegKey, ARRAYSIZE(szRegText)) == ERROR_SUCCESS)
  773. {
  774. DWORD dwLen = MultiByteToWideChar(CP_ACP,
  775. MB_ERR_INVALID_CHARS,
  776. szRegText,
  777. lstrlen(szRegText),
  778. pszRegText,
  779. nSize-1);
  780. pszRegText[dwLen] = L'\0';
  781. }
  782. }
  783. }
  784. return wcslen(pszRegText);
  785. }
  786. //+---------------------------------------------------------------------------
  787. //
  788. // GetHKLDescription
  789. //
  790. //
  791. //----------------------------------------------------------------------------
  792. int GetHKLDesctription(HKL hKL, WCHAR *pszDesc, int cchDesc, WCHAR *pszIMEFile, int cchIMEFile)
  793. {
  794. DWORD dwIMEDesc = 0;
  795. if (IsIMEHKL(hKL))
  796. {
  797. HKEY hkey;
  798. DWORD dwIMELayout;
  799. TCHAR szIMELayout[MAX_PATH];
  800. TCHAR szIMELayoutPath[MAX_PATH];
  801. dwIMELayout = GetSubstitute(hKL);
  802. StringCchPrintf(szIMELayout, ARRAYSIZE(szIMELayout), "%8.8lx", dwIMELayout);
  803. StringCopyArray(szIMELayoutPath, c_szLayoutPath);
  804. StringCatArray(szIMELayoutPath, TEXT("\\"));
  805. StringCatArray(szIMELayoutPath, szIMELayout);
  806. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szIMELayoutPath, 0, KEY_READ, &hkey)
  807. == ERROR_SUCCESS)
  808. {
  809. if (SHLoadRegUIStringW(hkey,
  810. c_szMUILayoutTextW,
  811. pszDesc, cchDesc) == S_OK)
  812. {
  813. dwIMEDesc = wcslen(pszDesc);
  814. }
  815. RegCloseKey(hkey);
  816. }
  817. if (!dwIMEDesc)
  818. {
  819. dwIMEDesc = ImmGetDescriptionW(hKL,pszDesc,cchDesc);
  820. if (!dwIMEDesc)
  821. pszDesc[0] = L'\0';
  822. }
  823. }
  824. if (dwIMEDesc == 0)
  825. {
  826. GetLocaleInfoString(hKL, pszDesc, cchDesc);
  827. pszIMEFile[0] = L'\0';
  828. }
  829. else
  830. {
  831. if (!ImmGetIMEFileNameW(hKL, pszIMEFile, cchIMEFile))
  832. pszIMEFile[0] = L'\0';
  833. }
  834. return wcslen(pszDesc);
  835. }
  836. //////////////////////////////////////////////////////////////////////////////
  837. //
  838. // MLNGINFO List
  839. //
  840. //////////////////////////////////////////////////////////////////////////////
  841. //---------------------------------------------------------------------------
  842. //
  843. // MlngInfoCount()
  844. //
  845. //---------------------------------------------------------------------------
  846. int WINAPI TF_MlngInfoCount()
  847. {
  848. if (!g_pMlngInfo)
  849. return 0;
  850. return g_pMlngInfo->Count();
  851. }
  852. //---------------------------------------------------------------------------
  853. //
  854. // GetMlngInfo()
  855. //
  856. //---------------------------------------------------------------------------
  857. BOOL GetMlngInfo(int n, MLNGINFO *pmlInfo)
  858. {
  859. BOOL bRet = FALSE;
  860. MLNGINFO *pml;
  861. if (!g_pMlngInfo)
  862. return FALSE;
  863. CicEnterCriticalSection(g_cs);
  864. Assert(g_pMlngInfo);
  865. if (n >= g_pMlngInfo->Count())
  866. goto Exit;
  867. pml = g_pMlngInfo->GetPtr(n);
  868. if (!pml)
  869. goto Exit;
  870. *pmlInfo = *pml;
  871. bRet = TRUE;
  872. Exit:
  873. CicLeaveCriticalSection(g_cs);
  874. return bRet;
  875. }
  876. //---------------------------------------------------------------------------
  877. //
  878. // GetMlngInfoByhKL()
  879. //
  880. //---------------------------------------------------------------------------
  881. int GetMlngInfoByhKL(HKL hKL, MLNGINFO *pmlInfo)
  882. {
  883. int nRet = -1;
  884. MLNGINFO *pml;
  885. if (!g_pMlngInfo)
  886. return 0;
  887. CicEnterCriticalSection(g_cs);
  888. int nCnt = g_pMlngInfo->Count();
  889. int i;
  890. for (i = 0; i < nCnt; i++)
  891. {
  892. pml = g_pMlngInfo->GetPtr(i);
  893. if (pml->hKL == hKL)
  894. {
  895. *pmlInfo = *pml;
  896. nRet = i;
  897. break;
  898. }
  899. }
  900. CicLeaveCriticalSection(g_cs);
  901. return nRet;
  902. }
  903. //+---------------------------------------------------------------------------
  904. //
  905. // CheckMlngInfo
  906. //
  907. // return TRUE, if MlangInfo needs to be updated.
  908. //
  909. //----------------------------------------------------------------------------
  910. BOOL CheckMlngInfo()
  911. {
  912. int iLangs;
  913. BOOL bRet = FALSE;
  914. HKL *pLanguages = NULL;
  915. if (!g_pMlngInfo)
  916. return TRUE;
  917. iLangs = GetKeyboardLayoutList((UINT)0, (HKL FAR *)NULL);
  918. if (iLangs != TF_MlngInfoCount())
  919. return TRUE;
  920. if (iLangs)
  921. {
  922. int i;
  923. pLanguages = (HKL *)cicMemAlloc(iLangs * sizeof(HKL));
  924. if (!pLanguages)
  925. goto Exit;
  926. GetKeyboardLayoutList(iLangs, (HKL FAR *)pLanguages);
  927. for (i = 0; i < iLangs; i++)
  928. {
  929. MLNGINFO *pMlngInfo = g_pMlngInfo->GetPtr(i);
  930. if (pMlngInfo->hKL != pLanguages[i])
  931. {
  932. bRet = TRUE;
  933. goto Exit;
  934. }
  935. }
  936. }
  937. Exit:
  938. if (pLanguages)
  939. cicMemFree(pLanguages);
  940. return bRet;
  941. }
  942. //---------------------------------------------------------------------------
  943. //
  944. // void DestroyMlngInfo()
  945. //
  946. //---------------------------------------------------------------------------
  947. void DestroyMlngInfo()
  948. {
  949. if (g_pMlngInfo)
  950. {
  951. while (g_pMlngInfo->Count())
  952. {
  953. g_pMlngInfo->Remove(0, 1);
  954. }
  955. delete g_pMlngInfo;
  956. g_pMlngInfo = NULL;
  957. }
  958. }
  959. //---------------------------------------------------------------------------
  960. //
  961. // void CreateMLlngInfo()
  962. //
  963. //---------------------------------------------------------------------------
  964. void CreateMlngInfo()
  965. {
  966. HKL *pLanguages;
  967. UINT uCount;
  968. UINT uLangs;
  969. MLNGINFO *pMlngInfo;
  970. BOOL fNeedInd = FALSE;
  971. uLangs = GetKeyboardLayoutList((UINT)0, (HKL FAR *)NULL);
  972. if (!g_pMlngInfo)
  973. g_pMlngInfo = new CStructArray<MLNGINFO>;
  974. if (!g_pMlngInfo)
  975. return;
  976. if (!EnsureIconImageList())
  977. {
  978. return;
  979. }
  980. pLanguages = (HKL *)cicMemAllocClear(uLangs * sizeof(HKL));
  981. if (!pLanguages)
  982. return;
  983. GetKeyboardLayoutList(uLangs, (HKL FAR *)pLanguages);
  984. //
  985. // pLanguages contains all the HKLs in the system
  986. // Put everything together in the DPA and Image List
  987. //
  988. for (uCount = 0; uCount < uLangs; uCount++)
  989. {
  990. pMlngInfo = g_pMlngInfo->Append(1);
  991. if (pMlngInfo)
  992. {
  993. pMlngInfo->hKL = pLanguages[uCount];
  994. pMlngInfo->fInitIcon = FALSE;
  995. pMlngInfo->fInitDesc = FALSE;
  996. }
  997. }
  998. cicMemFree(pLanguages);
  999. }
  1000. //---------------------------------------------------------------------------
  1001. //
  1002. // void InitDesc
  1003. //
  1004. //---------------------------------------------------------------------------
  1005. void MLNGINFO::InitDesc()
  1006. {
  1007. MLNGINFO *pml;
  1008. if (fInitDesc)
  1009. return;
  1010. WCHAR szRegText[256];
  1011. WCHAR szIMEFile[256];
  1012. GetHKLDesctription(hKL,
  1013. szRegText, ARRAYSIZE(szRegText),
  1014. szIMEFile, ARRAYSIZE(szIMEFile));
  1015. fInitDesc = TRUE;
  1016. SetDesc(szRegText);
  1017. CicEnterCriticalSection(g_cs);
  1018. Assert(g_pMlngInfo);
  1019. int nCnt = g_pMlngInfo->Count();
  1020. int i;
  1021. for (i = 0; i < nCnt; i++)
  1022. {
  1023. pml = g_pMlngInfo->GetPtr(i);
  1024. if (pml->hKL == hKL)
  1025. {
  1026. pml->fInitDesc = TRUE;
  1027. pml->SetDesc(szRegText);
  1028. break;
  1029. }
  1030. }
  1031. CicLeaveCriticalSection(g_cs);
  1032. return;
  1033. }
  1034. //---------------------------------------------------------------------------
  1035. //
  1036. // void InitIcon
  1037. //
  1038. //---------------------------------------------------------------------------
  1039. void MLNGINFO::InitIcon()
  1040. {
  1041. HICON hIcon;
  1042. if (fInitIcon)
  1043. return;
  1044. WCHAR szRegText[256];
  1045. WCHAR szIMEFile[256];
  1046. GetHKLDesctription(hKL,
  1047. szRegText, ARRAYSIZE(szRegText),
  1048. szIMEFile, ARRAYSIZE(szIMEFile));
  1049. fInitDesc = TRUE;
  1050. SetDesc(szRegText);
  1051. if (wcslen(szIMEFile))
  1052. {
  1053. int cx, cy;
  1054. InatGetIconSize(&cx, &cy);
  1055. if ((hIcon = GetIconFromFile(cx, cy, szIMEFile, 0)) == 0)
  1056. {
  1057. goto GetLangIcon;
  1058. }
  1059. }
  1060. else // for non-ime layout
  1061. {
  1062. GetLangIcon:
  1063. hIcon = InatCreateIcon(LOWORD((DWORD)(UINT_PTR)hKL));
  1064. }
  1065. if (hIcon)
  1066. {
  1067. nIconIndex = InatAddIcon(hIcon);
  1068. DestroyIcon(hIcon);
  1069. }
  1070. MLNGINFO *pml;
  1071. CicEnterCriticalSection(g_cs);
  1072. Assert(g_pMlngInfo);
  1073. int nCnt = g_pMlngInfo->Count();
  1074. int i;
  1075. for (i = 0; i < nCnt; i++)
  1076. {
  1077. pml = g_pMlngInfo->GetPtr(i);
  1078. if (pml->hKL == hKL)
  1079. {
  1080. pml->fInitDesc = TRUE;
  1081. pml->fInitIcon = TRUE;
  1082. pml->nIconIndex = nIconIndex;
  1083. pml->SetDesc(szRegText);
  1084. break;
  1085. }
  1086. }
  1087. CicLeaveCriticalSection(g_cs);
  1088. return;
  1089. }
  1090. //---------------------------------------------------------------------------
  1091. //
  1092. // void TF_InitMLlngInfo()
  1093. //
  1094. //---------------------------------------------------------------------------
  1095. void WINAPI TF_InitMlngInfo()
  1096. {
  1097. CicEnterCriticalSection(g_cs);
  1098. if (CheckMlngInfo())
  1099. {
  1100. DestroyMlngInfo();
  1101. CreateMlngInfo();
  1102. }
  1103. CicLeaveCriticalSection(g_cs);
  1104. }
  1105. //---------------------------------------------------------------------------
  1106. //
  1107. // void TF_InitMLlngHKL()
  1108. //
  1109. //---------------------------------------------------------------------------
  1110. BOOL TF_GetMlngHKL(int nId, HKL *phkl, WCHAR *psz, UINT cch)
  1111. {
  1112. BOOL bRet = FALSE;
  1113. MLNGINFO *pml;
  1114. CicEnterCriticalSection(g_cs);
  1115. Assert(g_pMlngInfo);
  1116. if (nId >= g_pMlngInfo->Count())
  1117. goto Exit;
  1118. pml = g_pMlngInfo->GetPtr(nId);
  1119. if (!pml)
  1120. goto Exit;
  1121. if (phkl)
  1122. *phkl = pml->hKL;
  1123. if (psz)
  1124. wcsncpy(psz, pml->GetDesc(), cch);
  1125. bRet = TRUE;
  1126. Exit:
  1127. CicLeaveCriticalSection(g_cs);
  1128. return bRet;
  1129. }
  1130. //---------------------------------------------------------------------------
  1131. //
  1132. // void TF_GetMlngIconIndex()
  1133. //
  1134. //---------------------------------------------------------------------------
  1135. UINT WINAPI TF_GetMlngIconIndex(int nId)
  1136. {
  1137. UINT uIconIndex = (UINT)-1;
  1138. MLNGINFO *pml;
  1139. CicEnterCriticalSection(g_cs);
  1140. Assert(g_pMlngInfo);
  1141. if (nId >= g_pMlngInfo->Count())
  1142. goto Exit;
  1143. pml = g_pMlngInfo->GetPtr(nId);
  1144. if (!pml)
  1145. goto Exit;
  1146. uIconIndex = pml->GetIconIndex();
  1147. Exit:
  1148. CicLeaveCriticalSection(g_cs);
  1149. return uIconIndex;
  1150. }
  1151. //---------------------------------------------------------------------------
  1152. //
  1153. // void ClearMlngIconIndex()
  1154. //
  1155. //---------------------------------------------------------------------------
  1156. void ClearMlngIconIndex()
  1157. {
  1158. int i;
  1159. CicEnterCriticalSection(g_cs);
  1160. Assert(g_pMlngInfo);
  1161. for (i = 0; i < g_pMlngInfo->Count(); i++)
  1162. {
  1163. MLNGINFO *pml;
  1164. pml = g_pMlngInfo->GetPtr(i);
  1165. if (!pml)
  1166. goto Exit;
  1167. pml->ClearIconIndex();
  1168. }
  1169. Exit:
  1170. CicLeaveCriticalSection(g_cs);
  1171. return;
  1172. }
  1173. //////////////////////////////////////////////////////////////////////////////
  1174. //
  1175. // IconImageList
  1176. //
  1177. //////////////////////////////////////////////////////////////////////////////
  1178. //---------------------------------------------------------------------------
  1179. //
  1180. // EnsureIconImageList
  1181. //
  1182. //---------------------------------------------------------------------------
  1183. BOOL EnsureIconImageList()
  1184. {
  1185. if (g_IconList.IsInited())
  1186. return TRUE;
  1187. g_IconList.Init(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON));
  1188. return TRUE;
  1189. }
  1190. //---------------------------------------------------------------------------
  1191. //
  1192. // InatAddIcon
  1193. //
  1194. //---------------------------------------------------------------------------
  1195. UINT InatAddIcon(HICON hIcon)
  1196. {
  1197. if (!EnsureIconImageList())
  1198. return -1;
  1199. return g_IconList.AddIcon(hIcon);
  1200. }
  1201. //---------------------------------------------------------------------------
  1202. //
  1203. // InatExtractIcon
  1204. //
  1205. //---------------------------------------------------------------------------
  1206. HICON WINAPI TF_InatExtractIcon(UINT uId)
  1207. {
  1208. return g_IconList.ExtractIcon(uId);
  1209. }
  1210. //---------------------------------------------------------------------------
  1211. //
  1212. // InatGetIconSize
  1213. //
  1214. //---------------------------------------------------------------------------
  1215. BOOL InatGetIconSize(int *pcx, int *pcy)
  1216. {
  1217. g_IconList.GetIconSize(pcx, pcy);
  1218. return TRUE;
  1219. }
  1220. //---------------------------------------------------------------------------
  1221. //
  1222. // InatGetImageCount
  1223. //
  1224. //---------------------------------------------------------------------------
  1225. BOOL InatGetImageCount()
  1226. {
  1227. return g_IconList.GetImageCount();
  1228. }
  1229. //---------------------------------------------------------------------------
  1230. //
  1231. // InatRemoveAll
  1232. //
  1233. //---------------------------------------------------------------------------
  1234. void InatRemoveAll()
  1235. {
  1236. if (!g_IconList.IsInited())
  1237. return;
  1238. g_IconList.RemoveAll(FALSE);
  1239. return;
  1240. }
  1241. //////////////////////////////////////////////////////////////////////////////
  1242. //
  1243. // HKL API
  1244. //
  1245. //////////////////////////////////////////////////////////////////////////////
  1246. //-----------------------------------------------------------------------------
  1247. //
  1248. // CPreloadRegKey
  1249. //
  1250. //-----------------------------------------------------------------------------
  1251. class CPreloadRegKey : public CMyRegKey
  1252. {
  1253. public:
  1254. HRESULT Open(BOOL fDefaultUser = FALSE)
  1255. {
  1256. if (fDefaultUser)
  1257. return CMyRegKey::Open(HKEY_USERS, c_szDefaultUserPreload, KEY_ALL_ACCESS);
  1258. else
  1259. return CMyRegKey::Open(HKEY_CURRENT_USER, c_szPreload, KEY_ALL_ACCESS);
  1260. }
  1261. HKL Get(int n)
  1262. {
  1263. char szValue[16];
  1264. char szValueName[16];
  1265. StringCchPrintf(szValueName, ARRAYSIZE(szValueName), "%d", n);
  1266. if (IsOnNT())
  1267. {
  1268. if (QueryValueCch(szValue, szValueName, ARRAYSIZE(szValue)) != S_OK)
  1269. return NULL;
  1270. }
  1271. else
  1272. {
  1273. CMyRegKey keySub;
  1274. if (keySub.Open(m_hKey, szValueName, KEY_READ) != S_OK)
  1275. return NULL;
  1276. if (keySub.QueryValueCch(szValue, NULL, ARRAYSIZE(szValue)) != S_OK)
  1277. return NULL;
  1278. }
  1279. return (HKL)(LONG_PTR)AsciiToNum(szValue);
  1280. }
  1281. void Set(int n, HKL hkl)
  1282. {
  1283. char szValue[16];
  1284. char szValueName[16];
  1285. StringCchPrintf(szValueName, ARRAYSIZE(szValueName), "%d", n);
  1286. NumToA((DWORD)(LONG_PTR)hkl, szValue);
  1287. if (IsOnNT())
  1288. {
  1289. SetValue(szValue, szValueName);
  1290. }
  1291. else
  1292. {
  1293. CMyRegKey keySub;
  1294. if (keySub.Open(m_hKey, szValueName, KEY_ALL_ACCESS) == S_OK)
  1295. keySub.SetValue(szValue, (LPSTR)NULL);
  1296. }
  1297. return;
  1298. }
  1299. void Delete(int n)
  1300. {
  1301. char szValueName[16];
  1302. StringCchPrintf(szValueName, ARRAYSIZE(szValueName), "%d", n);
  1303. if (IsOnNT())
  1304. {
  1305. DeleteValue(szValueName);
  1306. }
  1307. else
  1308. {
  1309. DeleteSubKey(szValueName);
  1310. }
  1311. return;
  1312. }
  1313. };
  1314. //+---------------------------------------------------------------------------
  1315. //
  1316. // GetSubstitute
  1317. //
  1318. //----------------------------------------------------------------------------
  1319. DWORD GetSubstitute(HKL hKL)
  1320. {
  1321. CMyRegKey key;
  1322. DWORD dwIndex = 0;
  1323. TCHAR szValue[16];
  1324. TCHAR szValueName[64];
  1325. DWORD dwLayout = HandleToLong(hKL);
  1326. //
  1327. // it's IME.
  1328. //
  1329. if ((dwLayout & 0xf0000000) == 0xe0000000)
  1330. return dwLayout;
  1331. //
  1332. // it's default layout.
  1333. //
  1334. if (HIWORD(dwLayout) == LOWORD(dwLayout))
  1335. dwLayout &= 0x0000FFFF;
  1336. else if ((dwLayout & 0xf0000000) == 0xf0000000)
  1337. dwLayout = GetKbdLayoutId(dwLayout);
  1338. if (key.Open(HKEY_CURRENT_USER, c_szSubst, KEY_READ) != S_OK)
  1339. return dwLayout;
  1340. if (IsOnNT())
  1341. {
  1342. while (key.EnumValue(dwIndex, szValueName, ARRAYSIZE(szValueName)) == S_OK)
  1343. {
  1344. if (key.QueryValueCch(szValue, szValueName, ARRAYSIZE(szValue)) == S_OK)
  1345. {
  1346. if ((dwLayout & 0x0FFFFFFF) == AsciiToNum(szValue))
  1347. {
  1348. return AsciiToNum(szValueName);
  1349. }
  1350. }
  1351. dwIndex++;
  1352. }
  1353. }
  1354. else
  1355. {
  1356. while (key.EnumKey(dwIndex, szValueName, ARRAYSIZE(szValueName)) == S_OK)
  1357. {
  1358. CMyRegKey keySub;
  1359. if (keySub.Open(key, szValueName, KEY_READ) == S_OK)
  1360. {
  1361. if (key.QueryValueCch(szValue, NULL, ARRAYSIZE(szValue)) == S_OK)
  1362. {
  1363. if ((dwLayout & 0x0FFFFFFF) == AsciiToNum(szValue))
  1364. {
  1365. return AsciiToNum(szValueName);
  1366. }
  1367. }
  1368. }
  1369. dwIndex++;
  1370. }
  1371. }
  1372. return dwLayout;
  1373. }
  1374. //+---------------------------------------------------------------------------
  1375. //
  1376. // SetSystemDefaultHKL
  1377. //
  1378. //----------------------------------------------------------------------------
  1379. BOOL SetSystemDefaultHKL(HKL hkl)
  1380. {
  1381. CPreloadRegKey key;
  1382. int n;
  1383. HKL hklFirst;
  1384. BOOL bRet = FALSE;
  1385. DWORD dwLayout;
  1386. if (key.Open() != S_OK)
  1387. return bRet;
  1388. dwLayout = GetSubstitute(hkl);
  1389. n = 1;
  1390. while(1)
  1391. {
  1392. HKL hklCur;
  1393. hklCur = key.Get(n);
  1394. if (!hklCur)
  1395. break;
  1396. if (n == 1)
  1397. hklFirst = hklCur;
  1398. if (hklCur == LongToHandle(dwLayout))
  1399. {
  1400. bRet = TRUE;
  1401. if (n != 1)
  1402. {
  1403. key.Set(n, hklFirst);
  1404. key.Set(1, hklCur);
  1405. }
  1406. bRet = SystemParametersInfo( SPI_SETDEFAULTINPUTLANG,
  1407. 0,
  1408. (LPVOID)((LPDWORD)&hkl),
  1409. 0 );
  1410. Assert(bRet);
  1411. break;
  1412. }
  1413. n++;
  1414. }
  1415. return bRet;
  1416. }
  1417. //+---------------------------------------------------------------------------
  1418. //
  1419. // GetPreloadListForNT()
  1420. //
  1421. //----------------------------------------------------------------------------
  1422. UINT GetPreloadListForNT(DWORD *pdw, UINT uBufSize)
  1423. {
  1424. CMyRegKey key;
  1425. CMyRegKey key1;
  1426. char szValue[16];
  1427. char szSubstValue[16];
  1428. char szName[16];
  1429. UINT uRet = 0;
  1430. //
  1431. // this function support only NT.
  1432. // win9x has different formation for Preload registry. Each layout is key.
  1433. //
  1434. if (!IsOnNT())
  1435. return 0;
  1436. if (key.Open(HKEY_CURRENT_USER, c_szPreload, KEY_READ) != S_OK)
  1437. return uRet;
  1438. key1.Open(HKEY_CURRENT_USER, c_szSubst, KEY_READ);
  1439. if (!pdw)
  1440. uBufSize = 1000;
  1441. while (uRet < uBufSize)
  1442. {
  1443. BOOL fUseSubst = FALSE;
  1444. StringCchPrintf(szName, ARRAYSIZE(szName), "%d", uRet + 1);
  1445. if (key.QueryValueCch(szValue, szName, ARRAYSIZE(szValue)) != S_OK)
  1446. return uRet;
  1447. if ((HKEY)key1)
  1448. {
  1449. if (key1.QueryValueCch(szSubstValue, szValue, ARRAYSIZE(szSubstValue)) == S_OK)
  1450. fUseSubst = TRUE;
  1451. }
  1452. if (pdw)
  1453. {
  1454. *pdw = AsciiToNum(fUseSubst ? szSubstValue : szValue);
  1455. pdw++;
  1456. }
  1457. uRet++;
  1458. }
  1459. return uRet;
  1460. }
  1461. #ifdef LATER_TO_CHECK_DUMMYHKL
  1462. //+---------------------------------------------------------------------------
  1463. //
  1464. // RemoveFEDummyHKLFromPreloadReg()
  1465. //
  1466. //----------------------------------------------------------------------------
  1467. void RemoveFEDummyHKLFromPreloadReg(HKL hkl, BOOL fDefaultUser)
  1468. {
  1469. CPreloadRegKey key;
  1470. BOOL fReset = FALSE;
  1471. UINT uCount;
  1472. UINT uMatch = 0;
  1473. if (key.Open(fDefaultUser) != S_OK)
  1474. return;
  1475. uCount = 1;
  1476. while(uCount < 1000)
  1477. {
  1478. HKL hklCur;
  1479. hklCur = key.Get(uCount);
  1480. if (!hklCur)
  1481. break;
  1482. if (hklCur == hkl)
  1483. {
  1484. uMatch++;
  1485. uCount++;
  1486. fReset = TRUE;
  1487. continue;
  1488. }
  1489. if (fReset && uMatch)
  1490. {
  1491. if (uCount <= uMatch)
  1492. {
  1493. Assert(0);
  1494. return;
  1495. }
  1496. //
  1497. // reset the hkl orders from preload section
  1498. //
  1499. key.Set(uCount-uMatch, hklCur);
  1500. }
  1501. uCount++;
  1502. }
  1503. while (fReset && uMatch && uCount)
  1504. {
  1505. if (uCount <= uMatch || (uCount - uMatch) <= 1)
  1506. {
  1507. Assert(0);
  1508. return;
  1509. }
  1510. //
  1511. // remove the dummy hkl from preload section
  1512. //
  1513. key.Delete(uCount - uMatch);
  1514. uMatch--;
  1515. }
  1516. return;
  1517. }
  1518. //+---------------------------------------------------------------------------
  1519. //
  1520. // RemoveFEDummyHKLs
  1521. //
  1522. // This function cleans up the FE Dummy HKLs that were added on Win9x.
  1523. // This is called during update setup to Whistler.
  1524. //
  1525. //----------------------------------------------------------------------------
  1526. void RemoveFEDummyHKLs()
  1527. {
  1528. CMyRegKey key;
  1529. DWORD dwIndex;
  1530. TCHAR szValue[MAX_PATH];
  1531. //
  1532. // Now read all the locales from the registry.
  1533. //
  1534. if (key.Open(HKEY_LOCAL_MACHINE, c_szLayoutPath) != ERROR_SUCCESS)
  1535. {
  1536. return;
  1537. }
  1538. dwIndex = 0;
  1539. szValue[0] = TEXT('\0');
  1540. while (key.EnumKey(dwIndex, szValue, ARRAYSIZE(szValue)) == ERROR_SUCCESS)
  1541. {
  1542. BOOL fDelete = FALSE;
  1543. CRegKeyMUI key1;
  1544. if ((szValue[0] != 'e') && (szValue[0] != 'E'))
  1545. goto Next;
  1546. if (key1.Open(key, szValue) == S_OK)
  1547. {
  1548. TCHAR szValueLayoutText[MAX_PATH];
  1549. //
  1550. // Get the layout text.
  1551. //
  1552. szValueLayoutText[0] = TEXT('\0');
  1553. if (key1.QueryValueCch(szValueLayoutText, c_szLayoutText, ARRAYSIZE(szValueLayoutText)) == S_OK)
  1554. {
  1555. char szDummyProfile[256];
  1556. DWORD dw = AsciiToNum(szValue);
  1557. StringCchPrintf(szDummyProfile, ARRAYSIZE(szDummyProfile), "hkl%04x", LOWORD(dw));
  1558. if (!lstrcmpi(szDummyProfile, szValueLayoutText))
  1559. {
  1560. fDelete = TRUE;
  1561. //
  1562. // Remove dummy HKL from Preload of HKCU and HKU\.DEFAULT.
  1563. // We may need to enum all users in HKU\.DEFAULT.
  1564. //
  1565. RemoveFEDummyHKLFromPreloadReg((HKL)LongToHandle(dw), TRUE);
  1566. RemoveFEDummyHKLFromPreloadReg((HKL)LongToHandle(dw), FALSE);
  1567. }
  1568. }
  1569. key1.Close();
  1570. }
  1571. if (fDelete)
  1572. {
  1573. key.RecurseDeleteKey(szValue);
  1574. }
  1575. else
  1576. {
  1577. Next:
  1578. dwIndex++;
  1579. }
  1580. szValue[0] = TEXT('\0');
  1581. }
  1582. return;
  1583. }
  1584. #endif LATER_TO_CHECK_DUMMYHKL