+static
+BOOL
+GetLayoutName(
+ LPCWSTR szLCID,
+ LPWSTR szName)
+{
+ HKEY hKey;
+ DWORD dwBufLen;
+ WCHAR szBuf[MAX_PATH], szDispName[MAX_PATH], szIndex[MAX_PATH], szPath[MAX_PATH];
+ HANDLE hLib;
+ UINT i, j, k;
+
+ wsprintf(szBuf, L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s", szLCID);
+
+ if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, (LPCTSTR)szBuf, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
+ {
+ dwBufLen = sizeof(szDispName);
+
+ if (RegQueryValueExW(hKey, L"Layout Display Name", NULL, NULL, (LPBYTE)szDispName, &dwBufLen) == ERROR_SUCCESS)
+ {
+ if (szDispName[0] == '@')
+ {
+ for (i = 0; i < wcslen(szDispName); i++)
+ {
+ if ((szDispName[i] == ',') && (szDispName[i + 1] == '-'))
+ {
+ for (j = i + 2, k = 0; j < wcslen(szDispName)+1; j++, k++)
+ {
+ szIndex[k] = szDispName[j];
+ }
+ szDispName[i - 1] = '\0';
+ break;
+ }
+ else
+ szDispName[i] = szDispName[i + 1];
+ }
+
+ if (ExpandEnvironmentStringsW(szDispName, szPath, ARRAYSIZE(szPath)))
+ {
+ hLib = LoadLibraryW(szPath);
+ if (hLib)
+ {
+ if (LoadStringW(hLib, _wtoi(szIndex), szPath, ARRAYSIZE(szPath)) != 0)
+ {
+ wcscpy(szName, szPath);
+ RegCloseKey(hKey);
+ return TRUE;
+ }
+ FreeLibrary(hLib);
+ }
+ }
+ }
+ }
+
+ dwBufLen = sizeof(szBuf);
+
+ if (RegQueryValueExW(hKey, L"Layout Text", NULL, NULL, (LPBYTE)szName, &dwBufLen) == ERROR_SUCCESS)
+ {
+ RegCloseKey(hKey);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+static
+VOID
+SetKeyboardLayout(
+ HWND hwnd)
+{
+ INT iCurSel;
+ ULONG ulLayoutId;
+ HKL hKl;
+ WCHAR szLayoutId[9];
+
+ iCurSel = SendMessageW(hwnd, CB_GETCURSEL, 0, 0);
+ if (iCurSel == CB_ERR)
+ return;
+
+ ulLayoutId = (ULONG)SendMessageW(hwnd, CB_GETITEMDATA, iCurSel, 0);
+ if (ulLayoutId == (ULONG)CB_ERR)
+ return;
+
+ swprintf(szLayoutId, L"%08lx", ulLayoutId);
+
+ hKl = LoadKeyboardLayoutW(szLayoutId, KLF_ACTIVATE | KLF_REPLACELANG | KLF_SETFORPROCESS);
+ SystemParametersInfoW(SPI_SETDEFAULTINPUTLANG, 0, &hKl, SPIF_SENDWININICHANGE);
+}
+
+
+static
+VOID
+SelectKeyboardForLanguage(
+ HWND hwnd,
+ LCID lcid)
+{
+ INT i, nCount;
+ LCID LayoutId;
+
+ TRACE("LCID: %08lx\n", lcid);
+ TRACE("LangID: %04lx\n", LANGIDFROMLCID(lcid));
+
+ nCount = SendMessageW(hwnd, CB_GETCOUNT, 0, 0);
+
+ for (i = 0; i < nCount; i++)
+ {
+ LayoutId = (LCID)SendMessageW(hwnd, CB_GETITEMDATA, i, 0);
+ TRACE("Layout: %08lx\n", LayoutId);
+
+ if (LANGIDFROMLCID(LayoutId) == LANGIDFROMLCID(lcid))
+ {
+ TRACE("Found 1: %08lx --> %08lx\n", LayoutId, lcid);
+ SendMessageW(hwnd, CB_SETCURSEL, i, 0);
+ return;
+ }
+ }
+
+ for (i = 0; i < nCount; i++)
+ {
+ LayoutId = (LCID)SendMessageW(hwnd, CB_GETITEMDATA, i, 0);
+ TRACE("Layout: %08lx\n", LayoutId);
+
+ if (PRIMARYLANGID(LayoutId) == PRIMARYLANGID(lcid))
+ {
+ TRACE("Found 2: %08lx --> %08lx\n", LayoutId, lcid);
+ SendMessageW(hwnd, CB_SETCURSEL, i, 0);
+ return;
+ }
+ }
+
+ TRACE("No match found!\n");
+}
+
+
+static
+VOID
+CreateKeyboardLayoutList(
+ HWND hItemsList)
+{
+ HKEY hKey;
+ WCHAR szLayoutId[9], szCurrentLayoutId[9];
+ WCHAR KeyName[MAX_PATH];
+ DWORD dwIndex = 0;
+ DWORD dwSize;
+ INT iIndex;
+ LONG lError;
+ ULONG ulLayoutId;
+
+ if (!GetKeyboardLayoutNameW(szCurrentLayoutId))
+ wcscpy(szCurrentLayoutId, L"00000409");
+
+ lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ L"System\\CurrentControlSet\\Control\\Keyboard Layouts",
+ 0,
+ KEY_ENUMERATE_SUB_KEYS,
+ &hKey);
+ if (lError != ERROR_SUCCESS)
+ return;
+
+ while (TRUE)
+ {
+ dwSize = ARRAYSIZE(szLayoutId);
+
+ lError = RegEnumKeyExW(hKey,
+ dwIndex,
+ szLayoutId,
+ &dwSize,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ if (lError != ERROR_SUCCESS)
+ break;
+
+ GetLayoutName(szLayoutId, KeyName);
+
+ iIndex = (INT)SendMessageW(hItemsList, CB_ADDSTRING, 0, (LPARAM)KeyName);
+
+ ulLayoutId = wcstoul(szLayoutId, NULL, 16);
+ SendMessageW(hItemsList, CB_SETITEMDATA, iIndex, (LPARAM)ulLayoutId);
+
+ if (wcscmp(szLayoutId, szCurrentLayoutId) == 0)
+ {
+ SendMessageW(hItemsList, CB_SETCURSEL, (WPARAM)iIndex, (LPARAM)0);
+ }
+
+ dwIndex++;
+ }
+
+ RegCloseKey(hKey);
+}
+
+