mirror of
https://github.com/reactos/reactos.git
synced 2024-07-06 12:45:16 +00:00
[KBSWITCH]
- Use strsafe functions - Use Shell Hooks in dll for detecting keyboard layout switching - Fix bug in loading kbsdll * Detection switch keyboard layout is now working in Windovs, but does not work in ReactOS (WH_SHELL not work in win32k) svn path=/trunk/; revision=72143
This commit is contained in:
parent
a32f426a76
commit
bc10137a10
|
@ -7,9 +7,10 @@
|
||||||
|
|
||||||
#include "../kbswitch.h"
|
#include "../kbswitch.h"
|
||||||
|
|
||||||
HHOOK hKeyboardHook, hLangHook, hWinHook;
|
HHOOK hWinHook = NULL;
|
||||||
HINSTANCE hInstance;
|
HHOOK hShellHook = NULL;
|
||||||
HWND hKbSwitchWnd;
|
HINSTANCE hInstance = NULL;
|
||||||
|
HWND hKbSwitchWnd = NULL;
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
SendMessageToMainWnd(UINT Msg, WPARAM wParam, LPARAM lParam)
|
SendMessageToMainWnd(UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||||
|
@ -17,40 +18,6 @@ SendMessageToMainWnd(UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||||
PostMessage(hKbSwitchWnd, Msg, wParam, lParam);
|
PostMessage(hKbSwitchWnd, Msg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not used yet */
|
|
||||||
LRESULT CALLBACK
|
|
||||||
KeyboardHookProc(int code, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
return CallNextHookEx(hKeyboardHook, code, wParam, lParam);
|
|
||||||
}
|
|
||||||
|
|
||||||
LRESULT CALLBACK
|
|
||||||
LangHookProc(int code, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
PMSG msg;
|
|
||||||
msg = (PMSG) lParam;
|
|
||||||
|
|
||||||
switch (msg->message)
|
|
||||||
{
|
|
||||||
case WM_INPUTLANGCHANGEREQUEST:
|
|
||||||
{
|
|
||||||
SendMessageToMainWnd(WM_LANG_CHANGED, wParam, msg->lParam);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_HOTKEY:
|
|
||||||
{
|
|
||||||
if (msg->hwnd)
|
|
||||||
{
|
|
||||||
SendMessageToMainWnd(WM_LOAD_LAYOUT, (WPARAM)msg->hwnd, msg->lParam);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CallNextHookEx(hLangHook, code, wParam, lParam);
|
|
||||||
}
|
|
||||||
|
|
||||||
LRESULT CALLBACK
|
LRESULT CALLBACK
|
||||||
WinHookProc(int code, WPARAM wParam, LPARAM lParam)
|
WinHookProc(int code, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
@ -69,18 +36,6 @@ WinHookProc(int code, WPARAM wParam, LPARAM lParam)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCBT_CREATEWND:
|
|
||||||
{
|
|
||||||
RegisterHotKey((HWND)wParam, id, MOD_ALT, VK_F10);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HCBT_DESTROYWND:
|
|
||||||
{
|
|
||||||
UnregisterHotKey((HWND)wParam, id);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalDeleteAtom(id);
|
GlobalDeleteAtom(id);
|
||||||
|
@ -88,25 +43,40 @@ WinHookProc(int code, WPARAM wParam, LPARAM lParam)
|
||||||
return CallNextHookEx(hWinHook, code, wParam, lParam);
|
return CallNextHookEx(hWinHook, code, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LRESULT CALLBACK
|
||||||
|
ShellHookProc(int code, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
switch (code)
|
||||||
|
{
|
||||||
|
case HSHELL_LANGUAGE:
|
||||||
|
{
|
||||||
|
SendMessageToMainWnd(WM_LANG_CHANGED, wParam, lParam);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CallNextHookEx(hShellHook, code, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
BOOL WINAPI
|
BOOL WINAPI
|
||||||
KbSwitchSetHooks(VOID)
|
KbSwitchSetHooks(VOID)
|
||||||
{
|
{
|
||||||
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardHookProc, hInstance, 0);
|
|
||||||
hLangHook = SetWindowsHookEx(WH_GETMESSAGE, LangHookProc, hInstance, 0);
|
|
||||||
hWinHook = SetWindowsHookEx(WH_CBT, WinHookProc, hInstance, 0);
|
hWinHook = SetWindowsHookEx(WH_CBT, WinHookProc, hInstance, 0);
|
||||||
|
hShellHook = SetWindowsHookEx(WH_SHELL, ShellHookProc, hInstance, 0);
|
||||||
|
|
||||||
if ((hKeyboardHook)&&(hLangHook)&&(hWinHook))
|
if (!hWinHook || !hShellHook)
|
||||||
return TRUE;
|
{
|
||||||
else
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID WINAPI
|
VOID WINAPI
|
||||||
KbSwitchDeleteHooks(VOID)
|
KbSwitchDeleteHooks(VOID)
|
||||||
{
|
{
|
||||||
if (hKeyboardHook) UnhookWindowsHookEx(hKeyboardHook);
|
|
||||||
if (hLangHook) UnhookWindowsHookEx(hLangHook);
|
|
||||||
if (hWinHook) UnhookWindowsHookEx(hWinHook);
|
if (hWinHook) UnhookWindowsHookEx(hWinHook);
|
||||||
|
if (hShellHook) UnhookWindowsHookEx(hShellHook);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL WINAPI
|
BOOL WINAPI
|
||||||
|
@ -117,10 +87,15 @@ DllMain(IN HINSTANCE hinstDLL,
|
||||||
switch (dwReason)
|
switch (dwReason)
|
||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
|
{
|
||||||
hInstance = hinstDLL;
|
hInstance = hinstDLL;
|
||||||
hKbSwitchWnd = FindWindow(szKbSwitcherName, NULL);
|
hKbSwitchWnd = FindWindow(szKbSwitcherName, NULL);
|
||||||
if (!hKbSwitchWnd) return FALSE;
|
if (!hKbSwitchWnd)
|
||||||
break;
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -10,15 +10,15 @@
|
||||||
|
|
||||||
#define WM_NOTIFYICONMSG (WM_USER + 248)
|
#define WM_NOTIFYICONMSG (WM_USER + 248)
|
||||||
|
|
||||||
PROC KbSwitchSetHooks = NULL;
|
PKBSWITCHSETHOOKS KbSwitchSetHooks = NULL;
|
||||||
PROC KbSwitchDeleteHooks = NULL;
|
PKBSWITCHDELETEHOOKS KbSwitchDeleteHooks = NULL;
|
||||||
|
|
||||||
|
|
||||||
static BOOL
|
static BOOL
|
||||||
GetLayoutID(LPTSTR szLayoutNum, LPTSTR szLCID);
|
GetLayoutID(LPTSTR szLayoutNum, LPTSTR szLCID, SIZE_T LCIDLength);
|
||||||
|
|
||||||
static BOOL
|
static BOOL
|
||||||
GetLayoutName(LPTSTR szLayoutNum, LPTSTR szName);
|
GetLayoutName(LPTSTR szLayoutNum, LPTSTR szName, SIZE_T NameLength);
|
||||||
|
|
||||||
HINSTANCE hInst;
|
HINSTANCE hInst;
|
||||||
HANDLE hProcessHeap;
|
HANDLE hProcessHeap;
|
||||||
|
@ -41,9 +41,9 @@ CreateTrayIcon(LPTSTR szLCID)
|
||||||
if (GetLocaleInfo(lId,
|
if (GetLocaleInfo(lId,
|
||||||
LOCALE_SISO639LANGNAME,
|
LOCALE_SISO639LANGNAME,
|
||||||
szBuf,
|
szBuf,
|
||||||
sizeof(szBuf) / sizeof(TCHAR)) == 0)
|
ARRAYSIZE(szBuf)) == 0)
|
||||||
{
|
{
|
||||||
lstrcpy(szBuf, _T("??"));
|
StringCchCopy(szBuf, ARRAYSIZE(szBuf), _T("??"));
|
||||||
}
|
}
|
||||||
|
|
||||||
hdcsrc = GetDC(NULL);
|
hdcsrc = GetDC(NULL);
|
||||||
|
@ -103,9 +103,10 @@ AddTrayIcon(HWND hwnd)
|
||||||
TCHAR szLCID[CCH_LAYOUT_ID + 1];
|
TCHAR szLCID[CCH_LAYOUT_ID + 1];
|
||||||
TCHAR szName[MAX_PATH];
|
TCHAR szName[MAX_PATH];
|
||||||
|
|
||||||
GetLayoutID(_T("1"), szLCID);
|
GetLayoutID(_T("1"), szLCID, ARRAYSIZE(szLCID));
|
||||||
GetLayoutName(_T("1"), szName);
|
GetLayoutName(_T("1"), szName, ARRAYSIZE(szName));
|
||||||
|
|
||||||
|
memset(&tnid, 0, sizeof(tnid));
|
||||||
tnid.cbSize = sizeof(NOTIFYICONDATA);
|
tnid.cbSize = sizeof(NOTIFYICONDATA);
|
||||||
tnid.hWnd = hwnd;
|
tnid.hWnd = hwnd;
|
||||||
tnid.uID = 1;
|
tnid.uID = 1;
|
||||||
|
@ -113,7 +114,7 @@ AddTrayIcon(HWND hwnd)
|
||||||
tnid.uCallbackMessage = WM_NOTIFYICONMSG;
|
tnid.uCallbackMessage = WM_NOTIFYICONMSG;
|
||||||
tnid.hIcon = CreateTrayIcon(szLCID);
|
tnid.hIcon = CreateTrayIcon(szLCID);
|
||||||
|
|
||||||
lstrcpyn(tnid.szTip, szName, sizeof(tnid.szTip) / sizeof(TCHAR));
|
StringCchCopy(tnid.szTip, ARRAYSIZE(tnid.szTip), szName);
|
||||||
|
|
||||||
Shell_NotifyIcon(NIM_ADD, &tnid);
|
Shell_NotifyIcon(NIM_ADD, &tnid);
|
||||||
}
|
}
|
||||||
|
@ -123,6 +124,7 @@ DelTrayIcon(HWND hwnd)
|
||||||
{
|
{
|
||||||
NOTIFYICONDATA tnid;
|
NOTIFYICONDATA tnid;
|
||||||
|
|
||||||
|
memset(&tnid, 0, sizeof(tnid));
|
||||||
tnid.cbSize = sizeof(NOTIFYICONDATA);
|
tnid.cbSize = sizeof(NOTIFYICONDATA);
|
||||||
tnid.hWnd = hwnd;
|
tnid.hWnd = hwnd;
|
||||||
tnid.uID = 1;
|
tnid.uID = 1;
|
||||||
|
@ -135,6 +137,7 @@ UpdateTrayIcon(HWND hwnd, LPTSTR szLCID, LPTSTR szName)
|
||||||
{
|
{
|
||||||
NOTIFYICONDATA tnid;
|
NOTIFYICONDATA tnid;
|
||||||
|
|
||||||
|
memset(&tnid, 0, sizeof(tnid));
|
||||||
tnid.cbSize = sizeof(NOTIFYICONDATA);
|
tnid.cbSize = sizeof(NOTIFYICONDATA);
|
||||||
tnid.hWnd = hwnd;
|
tnid.hWnd = hwnd;
|
||||||
tnid.uID = 1;
|
tnid.uID = 1;
|
||||||
|
@ -142,13 +145,13 @@ UpdateTrayIcon(HWND hwnd, LPTSTR szLCID, LPTSTR szName)
|
||||||
tnid.uCallbackMessage = WM_NOTIFYICONMSG;
|
tnid.uCallbackMessage = WM_NOTIFYICONMSG;
|
||||||
tnid.hIcon = CreateTrayIcon(szLCID);
|
tnid.hIcon = CreateTrayIcon(szLCID);
|
||||||
|
|
||||||
lstrcpyn(tnid.szTip, szName, sizeof(tnid.szTip) / sizeof(TCHAR));
|
StringCchCopy(tnid.szTip, ARRAYSIZE(tnid.szTip), szName);
|
||||||
|
|
||||||
Shell_NotifyIcon(NIM_MODIFY, &tnid);
|
Shell_NotifyIcon(NIM_MODIFY, &tnid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL
|
static BOOL
|
||||||
GetLayoutID(LPTSTR szLayoutNum, LPTSTR szLCID)
|
GetLayoutID(LPTSTR szLayoutNum, LPTSTR szLCID, SIZE_T LCIDLength)
|
||||||
{
|
{
|
||||||
DWORD dwBufLen;
|
DWORD dwBufLen;
|
||||||
DWORD dwRes;
|
DWORD dwRes;
|
||||||
|
@ -178,7 +181,7 @@ GetLayoutID(LPTSTR szLayoutNum, LPTSTR szLCID)
|
||||||
if (RegQueryValueEx(hKey, szTempLCID, NULL, NULL, (LPBYTE)szLCID, &dwBufLen) != ERROR_SUCCESS)
|
if (RegQueryValueEx(hKey, szTempLCID, NULL, NULL, (LPBYTE)szLCID, &dwBufLen) != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
// No substitute found, then use the old LCID
|
// No substitute found, then use the old LCID
|
||||||
lstrcpy(szLCID, szTempLCID);
|
StringCchCopy(szLCID, LCIDLength, szTempLCID);
|
||||||
}
|
}
|
||||||
|
|
||||||
RegCloseKey(hKey);
|
RegCloseKey(hKey);
|
||||||
|
@ -186,24 +189,24 @@ GetLayoutID(LPTSTR szLayoutNum, LPTSTR szLCID)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Substitutes key couldn't be opened, so use the old LCID
|
// Substitutes key couldn't be opened, so use the old LCID
|
||||||
lstrcpy(szLCID, szTempLCID);
|
StringCchCopy(szLCID, LCIDLength, szTempLCID);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
GetLayoutIDByHkl(HKL hKl, LPTSTR szLayoutID)
|
GetLayoutIDByHkl(HKL hKl, LPTSTR szLayoutID, SIZE_T LayoutIDLength)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
FIXME!!! This way of getting layout ID incorrect!
|
FIXME!!! This way of getting layout ID incorrect!
|
||||||
This will not work correctly for 0001040a, 00010410, etc
|
This will not work correctly for 0001040a, 00010410, etc
|
||||||
*/
|
*/
|
||||||
wsprintf(szLayoutID, _T("%08x"), LOWORD(hKl));
|
StringCchPrintf(szLayoutID, LayoutIDLength, _T("%08x"), LOWORD(hKl));
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL
|
static BOOL
|
||||||
GetLayoutName(LPTSTR szLayoutNum, LPTSTR szName)
|
GetLayoutName(LPTSTR szLayoutNum, LPTSTR szName, SIZE_T NameLength)
|
||||||
{
|
{
|
||||||
HKEY hKey;
|
HKEY hKey;
|
||||||
DWORD dwBufLen;
|
DWORD dwBufLen;
|
||||||
|
@ -212,20 +215,22 @@ GetLayoutName(LPTSTR szLayoutNum, LPTSTR szName)
|
||||||
HANDLE hLib;
|
HANDLE hLib;
|
||||||
UINT i, j, k;
|
UINT i, j, k;
|
||||||
|
|
||||||
if(!GetLayoutID(szLayoutNum, szLCID))
|
if (!GetLayoutID(szLayoutNum, szLCID, ARRAYSIZE(szLCID)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
wsprintf(szBuf, _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s"), szLCID);
|
StringCchPrintf(szBuf, ARRAYSIZE(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 = sizeof(szBuf);
|
dwBufLen = sizeof(szDispName);
|
||||||
|
|
||||||
if (RegQueryValueEx(hKey, _T("Layout Display Name"), NULL, NULL, (LPBYTE)szDispName, &dwBufLen) == ERROR_SUCCESS)
|
if (RegQueryValueEx(hKey, _T("Layout Display Name"), NULL, NULL, (LPBYTE)szDispName, &dwBufLen) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
if (szDispName[0] == '@')
|
if (szDispName[0] == '@')
|
||||||
{
|
{
|
||||||
for (i = 0; i < _tcslen(szDispName); i++)
|
size_t len = _tcslen(szDispName);
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
if ((szDispName[i] == ',') && (szDispName[i + 1] == '-'))
|
if ((szDispName[i] == ',') && (szDispName[i + 1] == '-'))
|
||||||
{
|
{
|
||||||
|
@ -239,14 +244,14 @@ GetLayoutName(LPTSTR szLayoutNum, LPTSTR szName)
|
||||||
else szDispName[i] = szDispName[i + 1];
|
else szDispName[i] = szDispName[i + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ExpandEnvironmentStrings(szDispName, szPath, MAX_PATH))
|
if (ExpandEnvironmentStrings(szDispName, szPath, ARRAYSIZE(szPath)))
|
||||||
{
|
{
|
||||||
hLib = LoadLibrary(szPath);
|
hLib = LoadLibrary(szPath);
|
||||||
if (hLib)
|
if (hLib)
|
||||||
{
|
{
|
||||||
if (LoadString(hLib, _ttoi(szIndex), szPath, sizeof(szPath) / sizeof(TCHAR)) != 0)
|
if (LoadString(hLib, _ttoi(szIndex), szPath, ARRAYSIZE(szPath)) != 0)
|
||||||
{
|
{
|
||||||
_tcscpy(szName, szPath);
|
StringCchCopy(szName, NameLength, szPath);
|
||||||
RegCloseKey(hKey);
|
RegCloseKey(hKey);
|
||||||
FreeLibrary(hLib);
|
FreeLibrary(hLib);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -257,7 +262,7 @@ GetLayoutName(LPTSTR szLayoutNum, LPTSTR szName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dwBufLen = sizeof(szBuf);
|
dwBufLen = NameLength * 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)
|
||||||
{
|
{
|
||||||
|
@ -287,10 +292,10 @@ ActivateLayout(HWND hwnd, ULONG uLayoutNum)
|
||||||
TCHAR szLangName[MAX_PATH];
|
TCHAR szLangName[MAX_PATH];
|
||||||
|
|
||||||
_ultot(uLayoutNum, szLayoutNum, 10);
|
_ultot(uLayoutNum, szLayoutNum, 10);
|
||||||
GetLayoutID(szLayoutNum, szLCID);
|
GetLayoutID(szLayoutNum, szLCID, ARRAYSIZE(szLCID));
|
||||||
|
|
||||||
// Switch to the new keyboard layout
|
// Switch to the new keyboard layout
|
||||||
GetLocaleInfo((LANGID)_tcstoul(szLCID, NULL, 16), LOCALE_SLANGUAGE, (LPTSTR)szLangName, sizeof(szLangName) / sizeof(TCHAR));
|
GetLocaleInfo((LANGID)_tcstoul(szLCID, NULL, 16), LOCALE_SLANGUAGE, (LPTSTR)szLangName, ARRAYSIZE(szLangName));
|
||||||
UpdateTrayIcon(hwnd, szLCID, szLangName);
|
UpdateTrayIcon(hwnd, szLCID, szLangName);
|
||||||
hKl = LoadKeyboardLayout(szLCID, KLF_ACTIVATE);
|
hKl = LoadKeyboardLayout(szLCID, KLF_ACTIVATE);
|
||||||
|
|
||||||
|
@ -313,19 +318,19 @@ BuildLeftPopupMenu(VOID)
|
||||||
// Add the keyboard layouts to the popup menu
|
// 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++)
|
||||||
{
|
{
|
||||||
dwSize = sizeof(szLayoutNum);
|
dwSize = sizeof(szLayoutNum);
|
||||||
if(RegEnumValue(hKey, dwIndex, szLayoutNum, &dwSize, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
|
if (RegEnumValue(hKey, dwIndex, szLayoutNum, &dwSize, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if(!GetLayoutName(szLayoutNum, szName))
|
if (!GetLayoutName(szLayoutNum, szName, ARRAYSIZE(szName)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
AppendMenu(hMenu, MF_STRING, _ttoi(szLayoutNum), szName);
|
AppendMenu(hMenu, MF_STRING, _ttoi(szLayoutNum), szName);
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)CheckMenuItem(hMenu, ulCurrentLayoutNum, MF_CHECKED);
|
CheckMenuItem(hMenu, ulCurrentLayoutNum, MF_CHECKED);
|
||||||
|
|
||||||
RegCloseKey(hKey);
|
RegCloseKey(hKey);
|
||||||
}
|
}
|
||||||
|
@ -337,13 +342,18 @@ BOOL
|
||||||
SetHooks(VOID)
|
SetHooks(VOID)
|
||||||
{
|
{
|
||||||
hDllLib = LoadLibrary(_T("kbsdll.dll"));
|
hDllLib = LoadLibrary(_T("kbsdll.dll"));
|
||||||
if (!hDllLib) return FALSE;
|
if (!hDllLib)
|
||||||
|
{
|
||||||
KbSwitchSetHooks = (PROC) GetProcAddress(hDllLib, MAKEINTRESOURCEA(1));
|
|
||||||
KbSwitchDeleteHooks = (PROC) GetProcAddress(hDllLib, MAKEINTRESOURCEA(2));
|
|
||||||
|
|
||||||
if ((KbSwitchSetHooks == NULL)||(KbSwitchDeleteHooks == NULL))
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
KbSwitchSetHooks = (PKBSWITCHSETHOOKS) GetProcAddress(hDllLib, "KbSwitchSetHooks");
|
||||||
|
KbSwitchDeleteHooks = (PKBSWITCHDELETEHOOKS) GetProcAddress(hDllLib, "KbSwitchDeleteHooks");
|
||||||
|
|
||||||
|
if (KbSwitchSetHooks == NULL || KbSwitchDeleteHooks == NULL)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
return KbSwitchSetHooks();
|
return KbSwitchSetHooks();
|
||||||
}
|
}
|
||||||
|
@ -362,21 +372,21 @@ GetNextLayout(VOID)
|
||||||
ULONG Ret = ulCurrentLayoutNum;
|
ULONG Ret = ulCurrentLayoutNum;
|
||||||
|
|
||||||
_ultot(ulCurrentLayoutNum, szLayoutNum, 10);
|
_ultot(ulCurrentLayoutNum, szLayoutNum, 10);
|
||||||
if (!GetLayoutID(szLayoutNum, szLayoutID))
|
if (!GetLayoutID(szLayoutNum, szLayoutID, ARRAYSIZE(szLayoutID)))
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_ultot(Ret + 1, szLayoutNum, 10);
|
_ultot(Ret + 1, szLayoutNum, 10);
|
||||||
|
|
||||||
if (GetLayoutID(szLayoutNum, szLayoutID))
|
if (GetLayoutID(szLayoutNum, szLayoutID, ARRAYSIZE(szLayoutID)))
|
||||||
{
|
{
|
||||||
return (Ret + 1);
|
return (Ret + 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_ultot(Ret - 1, szLayoutNum, 10);
|
_ultot(Ret - 1, szLayoutNum, 10);
|
||||||
if (GetLayoutID(szLayoutNum, szLayoutID))
|
if (GetLayoutID(szLayoutNum, szLayoutID, ARRAYSIZE(szLayoutID)))
|
||||||
return (Ret - 1);
|
return (Ret - 1);
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -408,8 +418,8 @@ WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
|
||||||
|
|
||||||
case WM_LANG_CHANGED:
|
case WM_LANG_CHANGED:
|
||||||
{
|
{
|
||||||
GetLayoutIDByHkl((HKL)lParam, szLCID);
|
GetLayoutIDByHkl((HKL)lParam, szLCID, ARRAYSIZE(szLCID));
|
||||||
GetLocaleInfo((LANGID)_tcstoul(szLCID, NULL, 16), LOCALE_SLANGUAGE, (LPTSTR)szLangName, sizeof(szLangName) / sizeof(TCHAR));
|
GetLocaleInfo((LANGID)_tcstoul(szLCID, NULL, 16), LOCALE_SLANGUAGE, (LPTSTR)szLangName, ARRAYSIZE(szLangName));
|
||||||
UpdateTrayIcon(hwnd, szLCID, szLangName);
|
UpdateTrayIcon(hwnd, szLCID, szLangName);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -424,8 +434,8 @@ WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
|
||||||
|
|
||||||
case WM_WINDOW_ACTIVATE:
|
case WM_WINDOW_ACTIVATE:
|
||||||
{
|
{
|
||||||
GetLayoutIDByHkl(GetKeyboardLayout(GetWindowThreadProcessId((HWND)wParam, 0)), szLCID);
|
GetLayoutIDByHkl(GetKeyboardLayout(GetWindowThreadProcessId((HWND)wParam, 0)), szLCID, ARRAYSIZE(szLCID));
|
||||||
GetLocaleInfo((LANGID)_tcstoul(szLCID, NULL, 16), LOCALE_SLANGUAGE, (LPTSTR)szLangName, sizeof(szLangName) / sizeof(TCHAR));
|
GetLocaleInfo((LANGID)_tcstoul(szLCID, NULL, 16), LOCALE_SLANGUAGE, (LPTSTR)szLangName, ARRAYSIZE(szLangName));
|
||||||
UpdateTrayIcon(hwnd, szLCID, szLangName);
|
UpdateTrayIcon(hwnd, szLCID, szLangName);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -526,11 +536,11 @@ _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPTSTR lpCmdLine, INT nCmdSh
|
||||||
|
|
||||||
switch (GetUserDefaultUILanguage())
|
switch (GetUserDefaultUILanguage())
|
||||||
{
|
{
|
||||||
case MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT):
|
case MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT):
|
||||||
SetProcessDefaultLayout(LAYOUT_RTL);
|
SetProcessDefaultLayout(LAYOUT_RTL);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
hMutex = CreateMutex(NULL, FALSE, szKbSwitcherName);
|
hMutex = CreateMutex(NULL, FALSE, szKbSwitcherName);
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <windef.h>
|
#include <windef.h>
|
||||||
#include <winbase.h>
|
#include <winbase.h>
|
||||||
|
@ -7,6 +9,7 @@
|
||||||
#include <wingdi.h>
|
#include <wingdi.h>
|
||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
|
#include <strsafe.h>
|
||||||
|
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
|
||||||
|
@ -21,4 +24,7 @@
|
||||||
#define WM_WINDOW_ACTIVATE (WM_USER + 10300)
|
#define WM_WINDOW_ACTIVATE (WM_USER + 10300)
|
||||||
#define WM_LOAD_LAYOUT (WM_USER + 10400)
|
#define WM_LOAD_LAYOUT (WM_USER + 10400)
|
||||||
|
|
||||||
|
typedef BOOL (WINAPI *PKBSWITCHSETHOOKS) (VOID);
|
||||||
|
typedef VOID (WINAPI *PKBSWITCHDELETEHOOKS) (VOID);
|
||||||
|
|
||||||
TCHAR szKbSwitcherName[] = _T("kbswitcher");
|
TCHAR szKbSwitcherName[] = _T("kbswitcher");
|
||||||
|
|
Loading…
Reference in a new issue