mirror of
https://github.com/reactos/reactos.git
synced 2025-04-25 08:00:24 +00:00
- Implement auto add keyboard layouts
svn path=/trunk/; revision=38977
This commit is contained in:
parent
befc05e353
commit
29817cbb51
4 changed files with 256 additions and 1 deletions
|
@ -28,7 +28,6 @@
|
|||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include <cpl.h>
|
||||
#include <tchar.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -441,6 +440,7 @@ GeneralPageProc(HWND hwndDlg,
|
|||
|
||||
/* Set new locale */
|
||||
SetNewLocale(NewLcid);
|
||||
AddNewKbLayoutsByLcid(NewLcid);
|
||||
SetUserGeoID(NewGeoID);
|
||||
SetNonUnicodeLang(hwndDlg, NewLcid);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef __CPL_INTL_H
|
||||
#define __CPL_INTL_H
|
||||
|
||||
#include <cpl.h>
|
||||
|
||||
#define MAX_FMT_SIZE 30
|
||||
#define MAX_STR_SIZE 128
|
||||
#define MAX_SAMPLES_STR_SIZE 70
|
||||
|
@ -77,6 +79,9 @@ LONG
|
|||
APIENTRY
|
||||
SetupApplet(HWND hwndDlg, LCID lcid);
|
||||
|
||||
/* kblayouts.c */
|
||||
VOID AddNewKbLayoutsByLcid(LCID Lcid);
|
||||
|
||||
#endif /* __CPL_INTL_H */
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
<file>numbers.c</file>
|
||||
<file>time.c</file>
|
||||
<file>misc.c</file>
|
||||
<file>kblayouts.c</file>
|
||||
<file>languages.c</file>
|
||||
<file>advanced.c</file>
|
||||
<file>sort.c</file>
|
||||
|
|
249
reactos/dll/cpl/intl/kblayouts.c
Normal file
249
reactos/dll/cpl/intl/kblayouts.c
Normal file
|
@ -0,0 +1,249 @@
|
|||
/*
|
||||
* PROJECT: ReactOS International Control Panel
|
||||
* FILE: dll/cpl/intl/kblayouts.c
|
||||
* PURPOSE: Functions for manipulation with keyboard layouts
|
||||
* PROGRAMMER: Dmitry Chapyshev (dmitry@reactos.org)
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <setupapi.h>
|
||||
#include <tchar.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "intl.h"
|
||||
#include "resource.h"
|
||||
|
||||
/* Character Count of a layout ID like "00000409" */
|
||||
#define CCH_LAYOUT_ID 8
|
||||
|
||||
/* Maximum Character Count of a ULONG in decimal */
|
||||
#define CCH_ULONG_DEC 10
|
||||
|
||||
|
||||
/* szLayoutID like 00000409, szLangID like 00000409 */
|
||||
static BOOL
|
||||
IsLayoutExists(LPTSTR szLayoutID, LPTSTR szLangID)
|
||||
{
|
||||
HKEY hKey, hSubKey;
|
||||
TCHAR szPreload[CCH_LAYOUT_ID + 1], szLayoutNum[3 + 1],
|
||||
szTmp[CCH_LAYOUT_ID + 1], szOldLangID[CCH_LAYOUT_ID + 1];
|
||||
DWORD dwIndex = 0, dwType, dwSize;
|
||||
BOOL IsLangExists = FALSE;
|
||||
LANGID langid;
|
||||
|
||||
if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"),
|
||||
0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
|
||||
{
|
||||
dwSize = sizeof(szLayoutNum);
|
||||
|
||||
while (RegEnumValue(hKey, dwIndex, szLayoutNum, &dwSize, NULL, &dwType, NULL, NULL) == ERROR_SUCCESS)
|
||||
{
|
||||
dwSize = sizeof(szPreload);
|
||||
if (RegQueryValueEx(hKey, szLayoutNum, NULL, NULL, (LPBYTE)szPreload, &dwSize) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey(hKey);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
langid = (LANGID)_tcstoul(szPreload, NULL, 16);
|
||||
GetLocaleInfo(langid, LOCALE_ILANGUAGE, szTmp, sizeof(szTmp) / sizeof(TCHAR));
|
||||
wsprintf(szOldLangID, _T("0000%s"), szTmp);
|
||||
|
||||
if (_tcscmp(szOldLangID, szLangID) == 0)
|
||||
IsLangExists = TRUE;
|
||||
else
|
||||
IsLangExists = FALSE;
|
||||
|
||||
if (szPreload[0] == 'd')
|
||||
{
|
||||
if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Substitutes"),
|
||||
0, KEY_QUERY_VALUE, &hSubKey) == ERROR_SUCCESS)
|
||||
{
|
||||
dwSize = sizeof(szTmp);
|
||||
RegQueryValueEx(hSubKey, szPreload, NULL, NULL, (LPBYTE)szTmp, &dwSize);
|
||||
|
||||
if ((_tcscmp(szTmp, szLayoutID) == 0)&&(IsLangExists))
|
||||
{
|
||||
RegCloseKey(hSubKey);
|
||||
RegCloseKey(hKey);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((_tcscmp(szPreload, szLayoutID) == 0) && (IsLangExists))
|
||||
{
|
||||
RegCloseKey(hKey);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
IsLangExists = FALSE;
|
||||
dwSize = sizeof(szLayoutNum);
|
||||
dwIndex++;
|
||||
}
|
||||
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
/* szLayoutID like 00000409, szLangID like 00000409 */
|
||||
static BOOL
|
||||
AddNewLayout(LPTSTR szLayoutID, LPTSTR szLangID)
|
||||
{
|
||||
TCHAR NewLayout[CCH_ULONG_DEC + 1], Lang[MAX_PATH],
|
||||
LangID[CCH_LAYOUT_ID + 1], SubPath[CCH_LAYOUT_ID + 1];
|
||||
HKEY hKey, hSubKey;
|
||||
DWORD cValues;
|
||||
LCID lcid;
|
||||
|
||||
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);
|
||||
|
||||
lcid = _tcstoul(szLangID, NULL, 16);
|
||||
|
||||
GetLocaleInfo(MAKELCID(lcid, SORT_DEFAULT), LOCALE_ILANGUAGE, Lang, sizeof(Lang) / sizeof(TCHAR));
|
||||
wsprintf(LangID, _T("0000%s"), Lang);
|
||||
|
||||
if (IsLayoutExists(szLayoutID, LangID))
|
||||
{
|
||||
RegCloseKey(hKey);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (GetLayoutCount(Lang) >= 1)
|
||||
{
|
||||
wsprintf(SubPath, _T("d%03d%s"), GetLayoutCount(Lang), Lang);
|
||||
}
|
||||
else if ((_tcscmp(LangID, szLayoutID) != 0) && (GetLayoutCount(Lang) == 0))
|
||||
{
|
||||
wsprintf(SubPath, _T("d%03d%s"), 0, Lang);
|
||||
}
|
||||
else SubPath[0] = '\0';
|
||||
|
||||
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)szLayoutID,
|
||||
(DWORD)((CCH_LAYOUT_ID + 1) * sizeof(TCHAR))) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey(hSubKey);
|
||||
RegCloseKey(hKey);
|
||||
return FALSE;
|
||||
}
|
||||
RegCloseKey(hSubKey);
|
||||
}
|
||||
lstrcpy(szLayoutID, SubPath);
|
||||
}
|
||||
|
||||
RegSetValueEx(hKey,
|
||||
NewLayout,
|
||||
0,
|
||||
REG_SZ,
|
||||
(LPBYTE)szLayoutID,
|
||||
(DWORD)((CCH_LAYOUT_ID + 1) * sizeof(TCHAR)));
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID
|
||||
AddNewKbLayoutsByLcid(LCID Lcid)
|
||||
{
|
||||
HINF hIntlInf;
|
||||
TCHAR szLang[CCH_LAYOUT_ID + 1], szLangID[CCH_LAYOUT_ID + 1];
|
||||
TCHAR szLangStr[MAX_STR_SIZE], szLayoutStr[MAX_STR_SIZE], szStr[MAX_STR_SIZE];
|
||||
INFCONTEXT InfContext;
|
||||
LONG Count;
|
||||
DWORD FieldCount, Index;
|
||||
|
||||
GetLocaleInfo(MAKELCID(Lcid, SORT_DEFAULT), LOCALE_ILANGUAGE, szLang, sizeof(szLang) / sizeof(TCHAR));
|
||||
wsprintf(szLangID, _T("0000%s"), szLang);
|
||||
|
||||
hIntlInf = SetupOpenInfFile(_T("intl.inf"), NULL, INF_STYLE_WIN4, NULL);
|
||||
|
||||
if (hIntlInf == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
|
||||
if (!SetupOpenAppendInfFile(NULL, hIntlInf, NULL))
|
||||
{
|
||||
SetupCloseInfFile(hIntlInf);
|
||||
hIntlInf = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
Count = SetupGetLineCount(hIntlInf, _T("Locales"));
|
||||
if (Count <= 0) return;
|
||||
|
||||
if (SetupFindFirstLine(hIntlInf, _T("Locales"), szLangID, &InfContext))
|
||||
{
|
||||
FieldCount = SetupGetFieldCount(&InfContext);
|
||||
|
||||
if (FieldCount != 0)
|
||||
{
|
||||
for (Index = 5; Index <= FieldCount; Index++)
|
||||
{
|
||||
if (SetupGetStringField(&InfContext, Index, szStr, MAX_STR_SIZE, NULL))
|
||||
{
|
||||
INT i, j;
|
||||
|
||||
if (_tcslen(szStr) != 13) continue;
|
||||
|
||||
wsprintf(szLangStr, _T("0000%s"), szStr);
|
||||
szLangStr[8] = '\0';
|
||||
|
||||
for (i = 5, j = 0; i <= _tcslen(szStr); i++, j++)
|
||||
szLayoutStr[j] = szStr[i];
|
||||
|
||||
AddNewLayout(szLayoutStr, szLangStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetupCloseInfFile(hIntlInf);
|
||||
}
|
Loading…
Reference in a new issue