mirror of
https://github.com/reactos/reactos.git
synced 2025-06-03 16:30:26 +00:00
kbswitch:
- Revert some changes from r33106: * Set the size of szTempLCID back to CCH_LAYOUT_ID + 1, a layout ID mustn't be longer than this. As we pass the correct size to the Registry functions as well, there can be no buffer overflow. MAX_PATH was probably used here, because input.dll had a bug as well, so that it saved the layout ID with the wrong length. * Use wsprintf over _stprintf * Pass the correct value to dwBufLen (in bytes, not in TCHAR's!) - Add back SystemParametersInfo, so that the system gets to know about the keyboard layout change. EnumWindows is still used for setting the new keyboard layout to all existing Windows. - Don't show a different menu for left and right clicks, that's not how most popup menus work under Windows. Instead append all menu items from the menu template to the popup menu. - Call SetForegroundWindow before and post a WM_NULL message after calling TrackPopupMenu, so that the popup menu will be closed, when the user clicks somewhere else - Fix indentation input.dll: - Fix some incorrect lengths passed to other functions - Get rid of some unneeded variables - Always use the 32-bit Registry functions over the old 16-bit deprecated ones - Fix some other stuff here and there svn path=/trunk/; revision=33130
This commit is contained in:
parent
9dc0da2dea
commit
a8253264f5
8 changed files with 157 additions and 151 deletions
|
@ -11,7 +11,7 @@
|
||||||
#define WM_NOTIFYICONMSG (WM_USER + 248)
|
#define WM_NOTIFYICONMSG (WM_USER + 248)
|
||||||
|
|
||||||
HINSTANCE hInst;
|
HINSTANCE hInst;
|
||||||
HWND hwnd;
|
HANDLE hProcessHeap;
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
AddTrayIcon(HWND hwnd, HICON hIcon)
|
AddTrayIcon(HWND hwnd, HICON hIcon)
|
||||||
|
@ -46,15 +46,17 @@ static BOOL
|
||||||
GetLayoutID(LPTSTR szLayoutNum, LPTSTR szLCID)
|
GetLayoutID(LPTSTR szLayoutNum, LPTSTR szLCID)
|
||||||
{
|
{
|
||||||
DWORD dwBufLen;
|
DWORD dwBufLen;
|
||||||
|
DWORD dwRes;
|
||||||
HKEY hKey;
|
HKEY hKey;
|
||||||
TCHAR szTempLCID[MAX_PATH];
|
TCHAR szTempLCID[CCH_LAYOUT_ID + 1];
|
||||||
|
|
||||||
// Get the Layout ID
|
// Get the Layout ID
|
||||||
if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
|
if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
dwBufLen = MAX_PATH;
|
dwBufLen = sizeof(szTempLCID);
|
||||||
|
dwRes = RegQueryValueEx(hKey, szLayoutNum, NULL, NULL, (LPBYTE)szTempLCID, &dwBufLen);
|
||||||
|
|
||||||
if (RegQueryValueEx(hKey, szLayoutNum, NULL, NULL, (LPBYTE)szTempLCID, &dwBufLen) != ERROR_SUCCESS)
|
if (dwRes != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
RegCloseKey(hKey);
|
RegCloseKey(hKey);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -66,7 +68,7 @@ GetLayoutID(LPTSTR szLayoutNum, LPTSTR szLCID)
|
||||||
// Look for a substitude of this layout
|
// Look for a substitude of this layout
|
||||||
if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Substitutes"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
|
if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Substitutes"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
dwBufLen = MAX_PATH;
|
dwBufLen = sizeof(szTempLCID);
|
||||||
|
|
||||||
if (RegQueryValueEx(hKey, szTempLCID, NULL, NULL, (LPBYTE)szLCID, &dwBufLen) != ERROR_SUCCESS)
|
if (RegQueryValueEx(hKey, szTempLCID, NULL, NULL, (LPBYTE)szLCID, &dwBufLen) != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -96,11 +98,11 @@ GetLayoutName(LPTSTR szLayoutNum, LPTSTR szName)
|
||||||
if(!GetLayoutID(szLayoutNum, szLCID))
|
if(!GetLayoutID(szLayoutNum, szLCID))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
_stprintf(szBuf, _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s"), szLCID);
|
wsprintf(szBuf, _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s"), szLCID);
|
||||||
|
|
||||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)szBuf, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)szBuf, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
dwBufLen = MAX_PATH;
|
dwBufLen = MAX_PATH * sizeof(TCHAR);
|
||||||
|
|
||||||
if(RegQueryValueEx(hKey, _T("Layout Text"), NULL, NULL, (LPBYTE)szName, &dwBufLen) != ERROR_SUCCESS)
|
if(RegQueryValueEx(hKey, _T("Layout Text"), NULL, NULL, (LPBYTE)szName, &dwBufLen) != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -133,20 +135,25 @@ ActivateLayout(ULONG uLayoutNum)
|
||||||
|
|
||||||
// Switch to the new keyboard layout
|
// Switch to the new keyboard layout
|
||||||
hKl = LoadKeyboardLayout(szLCID, KLF_ACTIVATE);
|
hKl = LoadKeyboardLayout(szLCID, KLF_ACTIVATE);
|
||||||
EnumWindows(EnumWindowsProc, (LPARAM) hKl);
|
SystemParametersInfo(SPI_SETDEFAULTINPUTLANG, 0, &hKl, SPIF_SENDWININICHANGE);
|
||||||
|
EnumWindows(EnumWindowsProc, (LPARAM) hKl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HMENU
|
static HMENU
|
||||||
BuildPopupMenu()
|
BuildPopupMenu()
|
||||||
{
|
{
|
||||||
HMENU hMenu;
|
HMENU hMenu;
|
||||||
|
HMENU hMenuTemplate;
|
||||||
HKEY hKey;
|
HKEY hKey;
|
||||||
DWORD dwIndex, dwSize;
|
DWORD dwIndex, dwSize;
|
||||||
|
LPTSTR pszMenuItem;
|
||||||
|
MENUITEMINFO mii;
|
||||||
TCHAR szLayoutNum[CCH_ULONG_DEC + 1];
|
TCHAR szLayoutNum[CCH_ULONG_DEC + 1];
|
||||||
TCHAR szName[MAX_PATH];
|
TCHAR szName[MAX_PATH];
|
||||||
|
|
||||||
hMenu = CreatePopupMenu();
|
hMenu = CreatePopupMenu();
|
||||||
|
|
||||||
|
// Add the keyboard layouts to the popup menu
|
||||||
if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
|
if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
for(dwIndex = 0; ; dwIndex++)
|
for(dwIndex = 0; ; dwIndex++)
|
||||||
|
@ -164,19 +171,40 @@ BuildPopupMenu()
|
||||||
RegCloseKey(hKey);
|
RegCloseKey(hKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add the menu items from the popup menu template
|
||||||
|
hMenuTemplate = GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(IDR_POPUP)), 0);
|
||||||
|
dwIndex = 0;
|
||||||
|
|
||||||
|
mii.cbSize = sizeof(mii);
|
||||||
|
mii.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_ID;
|
||||||
|
mii.dwTypeData = NULL;
|
||||||
|
|
||||||
|
while(GetMenuItemInfo(hMenuTemplate, dwIndex, TRUE, &mii))
|
||||||
|
{
|
||||||
|
if(mii.cch > 0)
|
||||||
|
{
|
||||||
|
mii.cch++;
|
||||||
|
pszMenuItem = (LPTSTR)HeapAlloc(hProcessHeap, 0, mii.cch * sizeof(TCHAR));
|
||||||
|
|
||||||
|
mii.dwTypeData = pszMenuItem;
|
||||||
|
GetMenuItemInfo(hMenuTemplate, dwIndex, TRUE, &mii);
|
||||||
|
|
||||||
|
AppendMenu(hMenu, mii.fType, mii.wID, mii.dwTypeData);
|
||||||
|
|
||||||
|
HeapFree(hProcessHeap, 0, pszMenuItem);
|
||||||
|
mii.dwTypeData = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AppendMenu(hMenu, mii.fType, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
dwIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
return hMenu;
|
return hMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
|
||||||
ShowRightPopupMenu(HWND hwnd, POINT pt)
|
|
||||||
{
|
|
||||||
HMENU hMenu;
|
|
||||||
|
|
||||||
hMenu = GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(IDR_POPUP)), 0);
|
|
||||||
TrackPopupMenu(hMenu, 0, pt.x, pt.y, 0, hwnd, NULL);
|
|
||||||
DestroyMenu(hMenu);
|
|
||||||
}
|
|
||||||
|
|
||||||
LRESULT CALLBACK
|
LRESULT CALLBACK
|
||||||
WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
|
WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
@ -192,54 +220,47 @@ WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
|
||||||
case WM_NOTIFYICONMSG:
|
case WM_NOTIFYICONMSG:
|
||||||
switch (lParam)
|
switch (lParam)
|
||||||
{
|
{
|
||||||
case WM_LBUTTONDBLCLK:
|
|
||||||
case WM_LBUTTONDOWN:
|
case WM_LBUTTONDOWN:
|
||||||
|
case WM_RBUTTONDOWN:
|
||||||
{
|
{
|
||||||
POINT pt;
|
POINT pt;
|
||||||
|
|
||||||
GetCursorPos(&pt);
|
GetCursorPos(&pt);
|
||||||
|
SetForegroundWindow(hwnd);
|
||||||
TrackPopupMenu(hPopupMenu, 0, pt.x, pt.y, 0, hwnd, NULL);
|
TrackPopupMenu(hPopupMenu, 0, pt.x, pt.y, 0, hwnd, NULL);
|
||||||
|
PostMessage(hwnd, WM_NULL, 0, 0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case WM_RBUTTONDOWN:
|
|
||||||
{
|
|
||||||
POINT pt;
|
|
||||||
|
|
||||||
GetCursorPos(&pt);
|
|
||||||
ShowRightPopupMenu(hwnd, pt);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_COMMAND:
|
case WM_COMMAND:
|
||||||
switch (LOWORD(wParam))
|
switch (LOWORD(wParam))
|
||||||
{
|
{
|
||||||
case ID_EXIT:
|
case ID_EXIT:
|
||||||
SendMessage(hwnd, WM_CLOSE, 0, 0);
|
SendMessage(hwnd, WM_CLOSE, 0, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ID_PROFERENCES:
|
case ID_PREFERENCES:
|
||||||
{
|
{
|
||||||
SHELLEXECUTEINFO shInputDll;
|
SHELLEXECUTEINFO shInputDll = {0};
|
||||||
|
|
||||||
memset(&shInputDll, 0x0, sizeof(SHELLEXECUTEINFO));
|
|
||||||
shInputDll.cbSize = sizeof(shInputDll);
|
shInputDll.cbSize = sizeof(shInputDll);
|
||||||
shInputDll.hwnd = hwnd;
|
shInputDll.hwnd = hwnd;
|
||||||
shInputDll.lpVerb = _T("open");
|
shInputDll.lpVerb = _T("open");
|
||||||
shInputDll.lpFile = _T("RunDll32.exe");
|
shInputDll.lpFile = _T("RunDll32.exe");
|
||||||
shInputDll.lpParameters = _T("shell32.dll,Control_RunDLL input.dll");
|
shInputDll.lpParameters = _T("shell32.dll,Control_RunDLL input.dll");
|
||||||
if (ShellExecuteEx(&shInputDll) == 0)
|
|
||||||
{
|
|
||||||
MessageBox(hwnd, _T("Can't start input.dll"), NULL, MB_OK | MB_ICONERROR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
if (!ShellExecuteEx(&shInputDll))
|
||||||
ActivateLayout(LOWORD(wParam));
|
MessageBox(hwnd, _T("Can't start input.dll"), NULL, MB_OK | MB_ICONERROR);
|
||||||
break;
|
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
ActivateLayout(LOWORD(wParam));
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_DESTROY:
|
case WM_DESTROY:
|
||||||
|
@ -253,12 +274,13 @@ WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
|
||||||
}
|
}
|
||||||
|
|
||||||
INT WINAPI
|
INT WINAPI
|
||||||
wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPTSTR lpCmdLine, INT nCmdShow)
|
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPTSTR lpCmdLine, INT nCmdShow)
|
||||||
{
|
{
|
||||||
WNDCLASS WndClass = {0};
|
WNDCLASS WndClass = {0};
|
||||||
MSG msg;
|
MSG msg;
|
||||||
|
|
||||||
hInst = hInstance;
|
hInst = hInstance;
|
||||||
|
hProcessHeap = GetProcessHeap();
|
||||||
|
|
||||||
WndClass.style = 0;
|
WndClass.style = 0;
|
||||||
WndClass.lpfnWndProc = (WNDPROC)WndProc;
|
WndClass.lpfnWndProc = (WNDPROC)WndProc;
|
||||||
|
@ -271,9 +293,10 @@ wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPTSTR lpCmdLine, INT nCmdSho
|
||||||
WndClass.lpszMenuName = NULL;
|
WndClass.lpszMenuName = NULL;
|
||||||
WndClass.lpszClassName = _T("kbswitch");
|
WndClass.lpszClassName = _T("kbswitch");
|
||||||
|
|
||||||
if (!RegisterClass(&WndClass)) return 0;
|
if (!RegisterClass(&WndClass))
|
||||||
|
return 1;
|
||||||
|
|
||||||
hwnd = CreateWindow(_T("kbswitch"), _T("kbswitch"), 0, 0, 0, 1, 1, HWND_DESKTOP, NULL, hInstance, NULL);
|
CreateWindow(_T("kbswitch"), NULL, 0, 0, 0, 1, 1, HWND_DESKTOP, NULL, hInstance, NULL);
|
||||||
|
|
||||||
while(GetMessage(&msg,NULL,0,0))
|
while(GetMessage(&msg,NULL,0,0))
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,8 +4,8 @@ IDR_POPUP MENU
|
||||||
BEGIN
|
BEGIN
|
||||||
POPUP "popup"
|
POPUP "popup"
|
||||||
BEGIN
|
BEGIN
|
||||||
MENUITEM "&Preferences...", ID_PROFERENCES
|
|
||||||
MENUITEM SEPARATOR
|
MENUITEM SEPARATOR
|
||||||
MENUITEM "&Beenden", ID_EXIT
|
MENUITEM "&Einstellungen...", ID_PREFERENCES
|
||||||
|
MENUITEM "&Beenden", ID_EXIT
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
|
@ -4,8 +4,8 @@ IDR_POPUP MENU
|
||||||
BEGIN
|
BEGIN
|
||||||
POPUP "popup"
|
POPUP "popup"
|
||||||
BEGIN
|
BEGIN
|
||||||
MENUITEM "&Preferences...", ID_PROFERENCES
|
|
||||||
MENUITEM SEPARATOR
|
MENUITEM SEPARATOR
|
||||||
|
MENUITEM "&Preferences...", ID_PREFERENCES
|
||||||
MENUITEM "&Exit", ID_EXIT
|
MENUITEM "&Exit", ID_EXIT
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
|
@ -4,8 +4,8 @@ IDR_POPUP MENU
|
||||||
BEGIN
|
BEGIN
|
||||||
POPUP "popup"
|
POPUP "popup"
|
||||||
BEGIN
|
BEGIN
|
||||||
MENUITEM "&Ïàðàìåòðû...", ID_PROFERENCES
|
|
||||||
MENUITEM SEPARATOR
|
MENUITEM SEPARATOR
|
||||||
|
MENUITEM "&Ïàðàìåòðû...", ID_PREFERENCES
|
||||||
MENUITEM "&Âûõîä", ID_EXIT
|
MENUITEM "&Âûõîä", ID_EXIT
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
|
@ -6,4 +6,4 @@
|
||||||
|
|
||||||
/* Menu items */
|
/* Menu items */
|
||||||
#define ID_EXIT 10001
|
#define ID_EXIT 10001
|
||||||
#define ID_PROFERENCES 10002
|
#define ID_PREFERENCES 10002
|
||||||
|
|
|
@ -18,16 +18,16 @@ static HWND hLayoutList;
|
||||||
static VOID
|
static VOID
|
||||||
SelectLayoutByLang(VOID)
|
SelectLayoutByLang(VOID)
|
||||||
{
|
{
|
||||||
TCHAR Layout[MAX_PATH], Lang[MAX_PATH], LangID[MAX_PATH];
|
TCHAR Layout[MAX_PATH], Lang[MAX_PATH], LangID[CCH_LAYOUT_ID + 1];
|
||||||
INT iIndex;
|
INT iIndex;
|
||||||
LCID Lcid;
|
LCID Lcid;
|
||||||
|
|
||||||
iIndex = SendMessage(hLangList, CB_GETCURSEL, 0, 0);
|
iIndex = SendMessage(hLangList, CB_GETCURSEL, 0, 0);
|
||||||
Lcid = SendMessage(hLangList, CB_GETITEMDATA, iIndex, 0);
|
Lcid = SendMessage(hLangList, CB_GETITEMDATA, iIndex, 0);
|
||||||
|
|
||||||
GetLocaleInfo(MAKELCID(Lcid, SORT_DEFAULT), LOCALE_ILANGUAGE, (WORD*)Lang, sizeof(Lang));
|
GetLocaleInfo(MAKELCID(Lcid, SORT_DEFAULT), LOCALE_ILANGUAGE, Lang, sizeof(Lang) / sizeof(TCHAR));
|
||||||
|
|
||||||
_stprintf(LangID, _T("0000%s"), Lang);
|
wsprintf(LangID, _T("0000%s"), Lang);
|
||||||
|
|
||||||
if (GetLayoutName(LangID, Layout))
|
if (GetLayoutName(LangID, Layout))
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,7 @@ SelectLayoutByLang(VOID)
|
||||||
static VOID
|
static VOID
|
||||||
AddNewLayout(HWND hwndDlg)
|
AddNewLayout(HWND hwndDlg)
|
||||||
{
|
{
|
||||||
TCHAR NewLayout[3];
|
TCHAR NewLayout[CCH_ULONG_DEC + 1];
|
||||||
INT iLayout;
|
INT iLayout;
|
||||||
HKEY hKey;
|
HKEY hKey;
|
||||||
DWORD cValues;
|
DWORD cValues;
|
||||||
|
@ -48,11 +48,11 @@ AddNewLayout(HWND hwndDlg)
|
||||||
iLayout = SendMessage(hLayoutList, CB_GETCURSEL, 0, 0);
|
iLayout = SendMessage(hLayoutList, CB_GETCURSEL, 0, 0);
|
||||||
if (iLayout == CB_ERR) return;
|
if (iLayout == CB_ERR) return;
|
||||||
|
|
||||||
if (RegOpenKey(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"), &hKey) == ERROR_SUCCESS)
|
if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"), 0, KEY_QUERY_VALUE | KEY_SET_VALUE, &hKey) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &cValues, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
|
if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &cValues, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
_stprintf(NewLayout, _T("%d"), cValues + 1);
|
_ultot(cValues + 1, NewLayout, 10);
|
||||||
|
|
||||||
pts = (PTSTR) SendMessage(hLayoutList, CB_GETITEMDATA, iLayout, 0);
|
pts = (PTSTR) SendMessage(hLayoutList, CB_GETITEMDATA, iLayout, 0);
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ AddNewLayout(HWND hwndDlg)
|
||||||
0,
|
0,
|
||||||
REG_SZ,
|
REG_SZ,
|
||||||
(LPBYTE)pts,
|
(LPBYTE)pts,
|
||||||
(DWORD)(_tcslen(pts)*sizeof(PTSTR))) == ERROR_SUCCESS)
|
(DWORD)((CCH_LAYOUT_ID + 1) * sizeof(TCHAR))) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
UpdateLayoutsList();
|
UpdateLayoutsList();
|
||||||
}
|
}
|
||||||
|
@ -73,47 +73,48 @@ VOID
|
||||||
CreateKeyboardLayoutList(VOID)
|
CreateKeyboardLayoutList(VOID)
|
||||||
{
|
{
|
||||||
HKEY hKey, hSubKey;
|
HKEY hKey, hSubKey;
|
||||||
PTSTR pstrBuf;
|
PTSTR pstrLayoutID;
|
||||||
TCHAR szBuf[CCH_LAYOUT_ID + 1], KeyName[MAX_PATH];
|
TCHAR szLayoutID[CCH_LAYOUT_ID + 1], KeyName[MAX_PATH];
|
||||||
LONG Ret;
|
|
||||||
DWORD dwIndex = 0;
|
DWORD dwIndex = 0;
|
||||||
|
DWORD dwSize;
|
||||||
|
|
||||||
if (RegOpenKey(HKEY_LOCAL_MACHINE, _T("System\\CurrentControlSet\\Control\\Keyboard Layouts"), &hKey) == ERROR_SUCCESS)
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("System\\CurrentControlSet\\Control\\Keyboard Layouts"), 0, KEY_ENUMERATE_SUB_KEYS, &hKey) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
Ret = RegEnumKey(hKey, dwIndex, szBuf, sizeof(szBuf) / sizeof(TCHAR));
|
dwSize = sizeof(szLayoutID) / sizeof(TCHAR);
|
||||||
|
|
||||||
while (Ret == ERROR_SUCCESS)
|
while (RegEnumKeyEx(hKey, dwIndex, szLayoutID, &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
_stprintf(KeyName, _T("System\\CurrentControlSet\\Control\\Keyboard Layouts\\%s"), szBuf);
|
wsprintf(KeyName, _T("System\\CurrentControlSet\\Control\\Keyboard Layouts\\%s"), szLayoutID);
|
||||||
|
|
||||||
if (RegOpenKey(HKEY_LOCAL_MACHINE, KeyName, &hSubKey) == ERROR_SUCCESS)
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, KeyName, 0, KEY_QUERY_VALUE, &hSubKey) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
DWORD Length = MAX_PATH;
|
DWORD dwKeyNameSize = sizeof(KeyName);
|
||||||
|
|
||||||
if (RegQueryValueEx(hSubKey, _T("Layout Text"), NULL, NULL, (LPBYTE)KeyName, &Length) == ERROR_SUCCESS)
|
if (RegQueryValueEx(hSubKey, _T("Layout Text"), NULL, NULL, (LPBYTE)KeyName, &dwKeyNameSize) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
INT iIndex = (INT) SendMessage(hLayoutList, CB_ADDSTRING, 0, (LPARAM)KeyName);
|
INT iIndex = (INT) SendMessage(hLayoutList, CB_ADDSTRING, 0, (LPARAM)KeyName);
|
||||||
|
|
||||||
pstrBuf = (PTSTR)HeapAlloc(hProcessHeap, 0, (CCH_LAYOUT_ID + 1) * sizeof(TCHAR));
|
pstrLayoutID = (PTSTR)HeapAlloc(hProcessHeap, 0, sizeof(szLayoutID));
|
||||||
_tcscpy(pstrBuf, szBuf);
|
lstrcpy(pstrLayoutID, szLayoutID);
|
||||||
SendMessage(hLayoutList, CB_SETITEMDATA, iIndex, (LPARAM)pstrBuf);
|
SendMessage(hLayoutList, CB_SETITEMDATA, iIndex, (LPARAM)pstrLayoutID);
|
||||||
|
|
||||||
// FIXME!
|
// FIXME!
|
||||||
if (_tcscmp(szBuf, _T("00000409")) == 0)
|
if (_tcscmp(szLayoutID, _T("00000409")) == 0)
|
||||||
{
|
{
|
||||||
SendMessage(hLayoutList, CB_SETCURSEL, (WPARAM)iIndex, (LPARAM)0);
|
SendMessage(hLayoutList, CB_SETCURSEL, (WPARAM)iIndex, (LPARAM)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
dwIndex++;
|
dwIndex++;
|
||||||
Ret = RegEnumKey(hKey, dwIndex, szBuf, sizeof(szBuf) / sizeof(TCHAR));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RegCloseKey(hSubKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
RegCloseKey(hSubKey);
|
dwSize = sizeof(szLayoutID) / sizeof(TCHAR);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
RegCloseKey(hKey);
|
RegCloseKey(hKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Language enumerate procedure */
|
/* Language enumerate procedure */
|
||||||
|
|
|
@ -27,6 +27,9 @@ extern HANDLE hProcessHeap;
|
||||||
// Character Count of a layout ID like "00000409"
|
// Character Count of a layout ID like "00000409"
|
||||||
#define CCH_LAYOUT_ID 8
|
#define CCH_LAYOUT_ID 8
|
||||||
|
|
||||||
|
// Maximum Character Count of a ULONG in decimal
|
||||||
|
#define CCH_ULONG_DEC 10
|
||||||
|
|
||||||
/* input.c */
|
/* input.c */
|
||||||
VOID
|
VOID
|
||||||
InitPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DLGPROC DlgProc);
|
InitPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DLGPROC DlgProc);
|
||||||
|
|
|
@ -12,8 +12,6 @@
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
|
||||||
#define BUFSIZE 256
|
|
||||||
|
|
||||||
static HWND MainDlgWnd;
|
static HWND MainDlgWnd;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -21,9 +19,8 @@ typedef struct
|
||||||
LANGID LangId;
|
LANGID LangId;
|
||||||
TCHAR LangName[MAX_PATH];
|
TCHAR LangName[MAX_PATH];
|
||||||
TCHAR LayoutName[MAX_PATH];
|
TCHAR LayoutName[MAX_PATH];
|
||||||
TCHAR ValName[MAX_PATH];
|
TCHAR ValName[CCH_ULONG_DEC + 1];
|
||||||
TCHAR IndName[MAX_PATH];
|
TCHAR IndName[MAX_PATH];
|
||||||
TCHAR SubName[MAX_PATH];
|
|
||||||
} LAYOUT_ITEM, *LPLAYOUT_ITEM;
|
} LAYOUT_ITEM, *LPLAYOUT_ITEM;
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
|
@ -31,14 +28,15 @@ GetLayoutName(LPCTSTR lcid, LPTSTR name)
|
||||||
{
|
{
|
||||||
HKEY hKey;
|
HKEY hKey;
|
||||||
DWORD dwBufLen;
|
DWORD dwBufLen;
|
||||||
TCHAR szBuf[BUFSIZE];
|
TCHAR szBuf[MAX_PATH];
|
||||||
|
|
||||||
_stprintf(szBuf, _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s"),lcid);
|
wsprintf(szBuf, _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s"), lcid);
|
||||||
|
|
||||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)szBuf, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)szBuf, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
dwBufLen = BUFSIZE;
|
dwBufLen = sizeof(szBuf);
|
||||||
if (RegQueryValueEx(hKey,_T("Layout Text"),NULL,NULL,(LPBYTE)name,&dwBufLen) == ERROR_SUCCESS)
|
|
||||||
|
if (RegQueryValueEx(hKey, _T("Layout Text"), NULL, NULL, (LPBYTE)name, &dwBufLen) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
RegCloseKey(hKey);
|
RegCloseKey(hKey);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -78,90 +76,71 @@ AddListColumn(HWND hWnd)
|
||||||
(VOID) ListView_InsertColumn(hList, 2, &column);
|
(VOID) ListView_InsertColumn(hList, 2, &column);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL
|
static VOID
|
||||||
InitLangList(HWND hWnd)
|
InitLangList(HWND hWnd)
|
||||||
{
|
{
|
||||||
HKEY hKey, hSubKey;
|
HKEY hKey, hSubKey;
|
||||||
TCHAR szBuf[MAX_PATH], szPreload[MAX_PATH], szSub[MAX_PATH];
|
TCHAR szBuf[MAX_PATH], szPreload[CCH_LAYOUT_ID + 1], szSub[CCH_LAYOUT_ID + 1];
|
||||||
LAYOUT_ITEM lItem;
|
LAYOUT_ITEM lItem;
|
||||||
LONG Ret;
|
|
||||||
DWORD dwIndex = 0, dwType, dwSize;
|
DWORD dwIndex = 0, dwType, dwSize;
|
||||||
LV_ITEM item;
|
LV_ITEM item = {0};
|
||||||
HWND hList = GetDlgItem(hWnd, IDC_KEYLAYOUT_LIST);
|
HWND hList = GetDlgItem(hWnd, IDC_KEYLAYOUT_LIST);
|
||||||
INT i;
|
INT i;
|
||||||
|
|
||||||
|
item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE;
|
||||||
|
|
||||||
if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"),
|
if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"),
|
||||||
0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
|
0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
dwSize = MAX_PATH;
|
dwSize = sizeof(lItem.ValName);
|
||||||
Ret = RegEnumValue(hKey, dwIndex, szBuf, &dwSize, NULL, &dwType, NULL, NULL);
|
|
||||||
if (Ret == ERROR_SUCCESS)
|
while (RegEnumValue(hKey, dwIndex, lItem.ValName, &dwSize, NULL, &dwType, NULL, NULL) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
while (Ret == ERROR_SUCCESS)
|
dwSize = sizeof(szPreload);
|
||||||
|
RegQueryValueEx(hKey, lItem.ValName, NULL, NULL, (LPBYTE)szPreload, &dwSize);
|
||||||
|
|
||||||
|
lItem.LangId = (LANGID)_tcstoul(szPreload, NULL, 16);
|
||||||
|
|
||||||
|
GetLocaleInfo(lItem.LangId, LOCALE_SISO639LANGNAME, (LPTSTR)szBuf, sizeof(szBuf) / sizeof(TCHAR));
|
||||||
|
lstrcpy(lItem.IndName, _tcsupr(szBuf));
|
||||||
|
|
||||||
|
GetLocaleInfo(lItem.LangId, LOCALE_SLANGUAGE, (LPTSTR)szBuf, sizeof(szBuf) / sizeof(TCHAR));
|
||||||
|
lstrcpy(lItem.LangName, szBuf);
|
||||||
|
|
||||||
|
// Does this keyboard layout have a substitute?
|
||||||
|
// Then add the substitute instead of the Layout ID
|
||||||
|
if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Substitutes"),
|
||||||
|
0, KEY_QUERY_VALUE, &hSubKey) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
_tcscpy(lItem.ValName, szBuf);
|
dwSize = sizeof(szSub);
|
||||||
|
|
||||||
dwSize = MAX_PATH;
|
if (RegQueryValueEx(hSubKey, szPreload, NULL, NULL, (LPBYTE)szSub, &dwSize) == ERROR_SUCCESS)
|
||||||
RegQueryValueEx(hKey, szBuf, NULL, NULL, (LPBYTE)szPreload, &dwSize);
|
|
||||||
|
|
||||||
lItem.LangId = _tcstoul(szPreload, NULL, 16);
|
|
||||||
|
|
||||||
GetLocaleInfo(lItem.LangId, LOCALE_SISO639LANGNAME, (LPTSTR) szBuf, sizeof(szBuf));
|
|
||||||
_tcscpy(lItem.IndName, _tcsupr(szBuf));
|
|
||||||
|
|
||||||
GetLocaleInfo(lItem.LangId, LOCALE_SLANGUAGE, (LPTSTR)szBuf, sizeof(szBuf));
|
|
||||||
_tcscpy(lItem.LangName, szBuf);
|
|
||||||
|
|
||||||
if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Substitutes"),
|
|
||||||
0, KEY_QUERY_VALUE, &hSubKey) == ERROR_SUCCESS)
|
|
||||||
{
|
{
|
||||||
dwSize = MAX_PATH;
|
lstrcpy(szPreload, szSub);
|
||||||
if (RegQueryValueEx(hSubKey, szPreload, NULL, NULL, (LPBYTE)szSub, &dwSize) == ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
_tcscpy(lItem.SubName, szPreload);
|
|
||||||
if (GetLayoutName(szSub, szBuf))
|
|
||||||
{
|
|
||||||
_tcscpy(lItem.LayoutName, szBuf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_tcscpy(lItem.SubName, _T(""));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_tcslen(lItem.SubName) < 2)
|
|
||||||
{
|
|
||||||
if (GetLayoutName(szPreload, szBuf))
|
|
||||||
{
|
|
||||||
_tcscpy(lItem.LayoutName, szBuf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ZeroMemory(&item, sizeof(LV_ITEM));
|
|
||||||
item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE;
|
|
||||||
item.pszText = lItem.IndName;
|
|
||||||
item.lParam = (LPARAM)&lItem;
|
|
||||||
item.iItem = (INT) dwIndex;
|
|
||||||
i = ListView_InsertItem(hList, &item);
|
|
||||||
|
|
||||||
ListView_SetItemText(hList, i, 1, lItem.LangName);
|
|
||||||
ListView_SetItemText(hList, i, 2, lItem.LayoutName);
|
|
||||||
|
|
||||||
dwIndex++;
|
|
||||||
Ret = RegEnumValue(hKey, dwIndex, szBuf, &dwSize, NULL, &dwType, NULL, NULL);
|
|
||||||
RegCloseKey(hSubKey);
|
RegCloseKey(hSubKey);
|
||||||
|
}
|
||||||
|
|
||||||
if (_tcscmp(lItem.ValName, _T("1")) == 0)
|
GetLayoutName(szPreload, lItem.LayoutName);
|
||||||
{
|
|
||||||
(VOID) ListView_SetHotItem(hList, i);
|
item.pszText = lItem.IndName;
|
||||||
}
|
item.iItem = (INT) dwIndex;
|
||||||
|
i = ListView_InsertItem(hList, &item);
|
||||||
|
|
||||||
|
ListView_SetItemText(hList, i, 1, lItem.LangName);
|
||||||
|
ListView_SetItemText(hList, i, 2, lItem.LayoutName);
|
||||||
|
|
||||||
|
dwIndex++;
|
||||||
|
|
||||||
|
if (lstrcmp(lItem.ValName, _T("1")) == 0)
|
||||||
|
{
|
||||||
|
(VOID) ListView_SetHotItem(hList, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
RegCloseKey(hKey);
|
RegCloseKey(hKey);
|
||||||
return TRUE;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
|
Loading…
Reference in a new issue