/* * * PROJECT: input.dll * FILE: dll/win32/input/add.c * PURPOSE: input.dll * PROGRAMMER: Dmitry Chapyshev (dmitry@reactos.org) * Colin Finck * UPDATE HISTORY: * 06-09-2007 Created */ #include "resource.h" #include "input.h" static HWND hLangList; static HWND hLayoutList; static VOID SelectLayoutByLang(VOID) { TCHAR Layout[MAX_PATH], Lang[MAX_PATH], LangID[CCH_LAYOUT_ID + 1]; INT iIndex; LCID Lcid; iIndex = SendMessage(hLangList, CB_GETCURSEL, 0, 0); Lcid = SendMessage(hLangList, CB_GETITEMDATA, iIndex, 0); GetLocaleInfo(MAKELCID(Lcid, SORT_DEFAULT), LOCALE_ILANGUAGE, Lang, sizeof(Lang) / sizeof(TCHAR)); wsprintf(LangID, _T("0000%s"), Lang); if (GetLayoutName(LangID, Layout)) { SendMessage(hLayoutList, CB_SELECTSTRING, (WPARAM) -1, (LPARAM)Layout); } } INT GetLayoutCount(LPTSTR szLang) { HKEY hKey; TCHAR szLayoutID[3 + 1], szPreload[CCH_LAYOUT_ID + 1], szLOLang[MAX_PATH]; DWORD dwIndex = 0, dwType, dwSize; UINT Count = 0, i, j; if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) { dwSize = sizeof(szLayoutID); while (RegEnumValue(hKey, dwIndex, szLayoutID, &dwSize, NULL, &dwType, NULL, NULL) == ERROR_SUCCESS) { dwSize = sizeof(szPreload); RegQueryValueEx(hKey, szLayoutID, NULL, NULL, (LPBYTE)szPreload, &dwSize); for (i = 4, j = 0; i < _tcslen(szPreload)+1; i++, j++) szLOLang[j] = szPreload[i]; if (_tcscmp(szLOLang, szLang) == 0) Count += 1; dwSize = sizeof(szLayoutID); dwIndex++; } RegCloseKey(hKey); } return Count; } static VOID AddNewLayout(HWND hwndDlg) { TCHAR NewLayout[CCH_ULONG_DEC + 1], Lang[MAX_PATH], LangID[CCH_LAYOUT_ID + 1], Layout[MAX_PATH], SubPath[CCH_LAYOUT_ID + 1], szMessage[MAX_PATH]; INT iLayout, iLang; HKEY hKey, hSubKey; DWORD cValues; PTSTR pts; LCID lcid; iLayout = SendMessage(hLayoutList, CB_GETCURSEL, 0, 0); if (iLayout == CB_ERR) return; if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"), 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS) { if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &cValues, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { _ultot(cValues + 1, NewLayout, 10); iLang = SendMessage(hLangList, CB_GETCURSEL, 0, 0); lcid = SendMessage(hLangList, CB_GETITEMDATA, iLang, 0); pts = (PTSTR) SendMessage(hLayoutList, CB_GETITEMDATA, iLayout, 0); GetLocaleInfo(MAKELCID(lcid, SORT_DEFAULT), LOCALE_ILANGUAGE, Lang, sizeof(Lang) / sizeof(TCHAR)); wsprintf(LangID, _T("0000%s"), Lang); if (IsLayoutExists(pts, LangID)) { LoadString(hApplet, IDS_LAYOUT_EXISTS2, szMessage, sizeof(szMessage) / sizeof(TCHAR)); MessageBox(hwndDlg, szMessage, NULL, MB_OK | MB_ICONINFORMATION); RegCloseKey(hKey); return; } if (_tcscmp(LangID, pts) != 0) { if (!GetLayoutName(pts, Layout)) { RegCloseKey(hKey); return; } } else { if (!GetLayoutName(LangID, Layout)) { RegCloseKey(hKey); return; } } if (SendMessage(hLayoutList, CB_SELECTSTRING, (WPARAM) -1, (LPARAM)Layout) != CB_ERR) { if (GetLayoutCount(Lang) >= 1) { wsprintf(SubPath, _T("d%03d%s"), GetLayoutCount(Lang), Lang); } else if ((_tcscmp(LangID, pts) != 0) && (GetLayoutCount(Lang) == 0)) { wsprintf(SubPath, _T("d%03d%s"), 0, Lang); } else SubPath[0] = '\0'; } else { RegCloseKey(hKey); return; } if (_tcslen(SubPath) != 0) { if (RegCreateKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Substitutes"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hSubKey, NULL) == ERROR_SUCCESS) { if (RegSetValueEx(hSubKey, SubPath, 0, REG_SZ, (LPBYTE)pts, (DWORD)((CCH_LAYOUT_ID + 1) * sizeof(TCHAR))) != ERROR_SUCCESS) { RegCloseKey(hSubKey); RegCloseKey(hKey); return; } RegCloseKey(hSubKey); } lstrcpy(pts, SubPath); } if (RegSetValueEx(hKey, NewLayout, 0, REG_SZ, (LPBYTE)pts, (DWORD)((CCH_LAYOUT_ID + 1) * sizeof(TCHAR))) == ERROR_SUCCESS) { UpdateLayoutsList(); } } RegCloseKey(hKey); } } VOID CreateKeyboardLayoutList(HWND hItemsList) { HKEY hKey; PTSTR pstrLayoutID; TCHAR szLayoutID[CCH_LAYOUT_ID + 1], KeyName[MAX_PATH]; DWORD dwIndex = 0; DWORD dwSize; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("System\\CurrentControlSet\\Control\\Keyboard Layouts"), 0, KEY_ENUMERATE_SUB_KEYS, &hKey) == ERROR_SUCCESS) { dwSize = sizeof(szLayoutID) / sizeof(TCHAR); while (RegEnumKeyEx(hKey, dwIndex, szLayoutID, &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { INT iIndex; GetLayoutName(szLayoutID, KeyName); iIndex = (INT) SendMessage(hItemsList, CB_ADDSTRING, 0, (LPARAM)KeyName); pstrLayoutID = (PTSTR)HeapAlloc(hProcessHeap, 0, sizeof(szLayoutID)); lstrcpy(pstrLayoutID, szLayoutID); SendMessage(hItemsList, CB_SETITEMDATA, iIndex, (LPARAM)pstrLayoutID); // FIXME! if (_tcscmp(szLayoutID, _T("00000409")) == 0) { SendMessage(hItemsList, CB_SETCURSEL, (WPARAM)iIndex, (LPARAM)0); } dwIndex++; dwSize = sizeof(szLayoutID) / sizeof(TCHAR); } RegCloseKey(hKey); } } /* Language enumerate procedure */ static BOOL CALLBACK LanguagesEnumProc(LPTSTR lpLanguage) { LCID Lcid; TCHAR Lang[1024]; INT Index; Lcid = _tcstoul(lpLanguage, NULL, 16); GetLocaleInfo(Lcid, LOCALE_SLANGUAGE, Lang, sizeof(Lang)); Index = (INT)SendMessage(hLangList, CB_ADDSTRING, 0, (LPARAM)Lang); SendMessage(hLangList, CB_SETITEMDATA, Index, (LPARAM)Lcid); // FIXME! if (Lcid == 0x0409) { SendMessage(hLangList, CB_SELECTSTRING, (WPARAM) -1, (LPARAM)Lang); } return TRUE; } INT_PTR CALLBACK AddDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: { hLangList = GetDlgItem(hDlg, IDC_INPUT_LANG_COMBO); hLayoutList = GetDlgItem(hDlg, IDC_KEYBOARD_LO_COMBO); EnumSystemLocales(LanguagesEnumProc, LCID_INSTALLED); CreateKeyboardLayoutList(hLayoutList); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_INPUT_LANG_COMBO: { if (HIWORD(wParam) == CBN_SELCHANGE) { SelectLayoutByLang(); } } break; case IDOK: { AddNewLayout(hDlg); EndDialog(hDlg, LOWORD(wParam)); } break; case IDCANCEL: { EndDialog(hDlg, LOWORD(wParam)); } } } break; case WM_DESTROY: { INT iCount; for(iCount = SendMessage(hLayoutList, CB_GETCOUNT, 0, 0); --iCount >= 0;) HeapFree(hProcessHeap, 0, (LPVOID)SendMessage(hLayoutList, CB_GETITEMDATA, iCount, 0)); } break; } return FALSE; } /* EOF */