https://git.reactos.org/?p=reactos.git;a=commitdiff;h=36f7d1a953698157dddb7…
commit 36f7d1a953698157dddb723506453039b9dcf11d
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sat Oct 29 07:35:19 2022 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Sat Oct 29 07:35:19 2022 +0900
[KBSWITCH][CPL:INPUT][NTUSER][EXPLORER] Fix keyboard layout icon (#4815)
Fix keyboard layout icon in taskbar notification area. JIRA issue: CORE-11700,
CORE-2699, CORE-18546
- Call ActivateKeyboardLayout to select the keyboard layout correctly.
- Modify WM_INPUTLANGCHANGEREQUEST parameter.
- Modify BroadcastSystemMessageW parameter.
- Revert Taskbar Notification Area MA_NOACTIVATE HACK 8344291 . This fixes Context
Menu display.
- Load the "IME File" value and set the IME icon if necessary.
- Correctly implement global hooks.
---
base/applications/kbswitch/CMakeLists.txt | 2 +-
base/applications/kbswitch/kbsdll/kbsdll.c | 36 ++-
base/applications/kbswitch/kbswitch.c | 328 ++++++++++++++++++----
base/applications/kbswitch/kbswitch.h | 1 -
base/shell/explorer/trayntfy.cpp | 6 -
dll/cpl/input/input_list.c | 7 +-
win32ss/user/ntuser/defwnd.c | 2 +-
win32ss/user/winsrv/consrv/frontends/gui/conwnd.c | 5 +
8 files changed, 317 insertions(+), 70 deletions(-)
diff --git a/base/applications/kbswitch/CMakeLists.txt
b/base/applications/kbswitch/CMakeLists.txt
index 2b735411437..ede579f6181 100644
--- a/base/applications/kbswitch/CMakeLists.txt
+++ b/base/applications/kbswitch/CMakeLists.txt
@@ -2,7 +2,7 @@
add_rc_deps(kbswitch.rc ${CMAKE_CURRENT_SOURCE_DIR}/res/kbswitch.ico)
add_executable(kbswitch kbswitch.c kbswitch.rc)
set_module_type(kbswitch win32gui UNICODE)
-add_importlibs(kbswitch advapi32 user32 shell32 gdi32 msvcrt kernel32)
+add_importlibs(kbswitch advapi32 imm32 user32 shell32 gdi32 msvcrt kernel32)
add_cd_file(TARGET kbswitch DESTINATION reactos/system32 FOR all)
add_subdirectory(kbsdll)
diff --git a/base/applications/kbswitch/kbsdll/kbsdll.c
b/base/applications/kbswitch/kbsdll/kbsdll.c
index 6afb63a08c5..ffcc0344d6d 100644
--- a/base/applications/kbswitch/kbsdll/kbsdll.c
+++ b/base/applications/kbswitch/kbsdll/kbsdll.c
@@ -13,7 +13,7 @@ HINSTANCE hInstance = NULL;
HWND hKbSwitchWnd = NULL;
static VOID
-SendMessageToMainWnd(UINT Msg, WPARAM wParam, LPARAM lParam)
+PostMessageToMainWnd(UINT Msg, WPARAM wParam, LPARAM lParam)
{
PostMessage(hKbSwitchWnd, Msg, wParam, lParam);
}
@@ -21,36 +21,40 @@ SendMessageToMainWnd(UINT Msg, WPARAM wParam, LPARAM lParam)
LRESULT CALLBACK
WinHookProc(int code, WPARAM wParam, LPARAM lParam)
{
- int id = GlobalAddAtom(_T("KBSWITCH"));
+ if (code < 0)
+ {
+ return CallNextHookEx(hWinHook, code, wParam, lParam);
+ }
switch (code)
{
case HCBT_SETFOCUS:
{
- if ((HWND)wParam != NULL)
+ HWND hwndFocus = (HWND)wParam;
+ if (hwndFocus && hwndFocus != hKbSwitchWnd)
{
- if ((HWND)wParam != hKbSwitchWnd)
- {
- SendMessageToMainWnd(WM_WINDOW_ACTIVATE, wParam, lParam);
- }
+ PostMessageToMainWnd(WM_WINDOW_ACTIVATE, wParam, lParam);
}
}
break;
}
- GlobalDeleteAtom(id);
-
return CallNextHookEx(hWinHook, code, wParam, lParam);
}
LRESULT CALLBACK
ShellHookProc(int code, WPARAM wParam, LPARAM lParam)
{
+ if (code < 0)
+ {
+ return CallNextHookEx(hShellHook, code, wParam, lParam);
+ }
+
switch (code)
{
case HSHELL_LANGUAGE:
{
- SendMessageToMainWnd(WM_LANG_CHANGED, wParam, lParam);
+ PostMessageToMainWnd(WM_LANG_CHANGED, wParam, lParam);
}
break;
}
@@ -75,8 +79,16 @@ KbSwitchSetHooks(VOID)
VOID WINAPI
KbSwitchDeleteHooks(VOID)
{
- if (hWinHook) UnhookWindowsHookEx(hWinHook);
- if (hShellHook) UnhookWindowsHookEx(hShellHook);
+ if (hWinHook)
+ {
+ UnhookWindowsHookEx(hWinHook);
+ hWinHook = NULL;
+ }
+ if (hShellHook)
+ {
+ UnhookWindowsHookEx(hShellHook);
+ hShellHook = NULL;
+ }
}
BOOL WINAPI
diff --git a/base/applications/kbswitch/kbswitch.c
b/base/applications/kbswitch/kbswitch.c
index 6e301ee5207..5bad013d964 100644
--- a/base/applications/kbswitch/kbswitch.c
+++ b/base/applications/kbswitch/kbswitch.c
@@ -8,6 +8,21 @@
*/
#include "kbswitch.h"
+#include <imm.h>
+
+/*
+ * This program kbswitch is a mimic of Win2k's internat.exe.
+ * However, there are some differences.
+ *
+ * Comparing with WinNT4 ActivateKeyboardLayout, WinXP ActivateKeyboardLayout has
+ * process boundary, so we cannot activate the IME keyboard layout from the outer
process.
+ * It needs special care.
+ *
+ * We use global hook by our kbsdll.dll, to watch the shell and the windows.
+ *
+ * It might not work correctly on Vista+ because keyboard layout change notification
+ * won't be generated in Vista+.
+ */
#define WM_NOTIFYICONMSG (WM_USER + 248)
@@ -20,6 +35,7 @@ HANDLE hProcessHeap;
HMODULE g_hHookDLL = NULL;
ULONG ulCurrentLayoutNum = 1;
HICON g_hTrayIcon = NULL;
+HWND g_hwndLastActive = NULL;
static BOOL
GetLayoutID(LPCTSTR szLayoutNum, LPTSTR szLCID, SIZE_T LCIDLength)
@@ -65,6 +81,17 @@ GetLayoutID(LPCTSTR szLayoutNum, LPTSTR szLCID, SIZE_T LCIDLength)
return TRUE;
}
+static BOOL
+GetSystemLibraryPath(LPTSTR szPath, SIZE_T cchPath, LPCTSTR FileName)
+{
+ if (!GetSystemDirectory(szPath, cchPath))
+ return FALSE;
+
+ StringCchCat(szPath, cchPath, TEXT("\\"));
+ StringCchCat(szPath, cchPath, FileName);
+ return TRUE;
+}
+
static BOOL
GetLayoutName(LPCTSTR szLayoutNum, LPTSTR szName, SIZE_T NameLength)
{
@@ -131,18 +158,86 @@ GetLayoutName(LPCTSTR szLayoutNum, LPTSTR szName, SIZE_T
NameLength)
/* Otherwise, use "Layout Text" value as an entry name */
dwBufLen = NameLength * sizeof(TCHAR);
if (RegQueryValueEx(hKey, _T("Layout Text"), NULL, NULL,
- (LPBYTE)szName, &dwBufLen) == ERROR_SUCCESS)
+ (LPBYTE)szName, &dwBufLen) != ERROR_SUCCESS)
{
RegCloseKey(hKey);
- return TRUE;
+ return FALSE;
}
RegCloseKey(hKey);
- return FALSE;
+ return TRUE;
+}
+
+static BOOL GetImeFile(LPTSTR szImeFile, SIZE_T cchImeFile, LPCTSTR szLCID)
+{
+ HKEY hKey;
+ DWORD dwBufLen;
+ TCHAR szBuf[MAX_PATH];
+
+ szImeFile[0] = UNICODE_NULL;
+
+ if (_tcslen(szLCID) != CCH_LAYOUT_ID)
+ return FALSE; /* Invalid LCID */
+
+ if (szLCID[0] != TEXT('E') && szLCID[0] != TEXT('e'))
+ return FALSE; /* Not an IME HKL */
+
+ StringCchPrintf(szBuf, ARRAYSIZE(szBuf),
+ _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard
Layouts\\%s"), szLCID);
+
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szBuf, 0, KEY_QUERY_VALUE, &hKey) !=
ERROR_SUCCESS)
+ {
+ return FALSE;
+ }
+
+ dwBufLen = cchImeFile * sizeof(TCHAR);
+ if (RegQueryValueEx(hKey, _T("IME File"), NULL, NULL,
+ (LPBYTE)szImeFile, &dwBufLen) != ERROR_SUCCESS)
+ {
+ szImeFile[0] = UNICODE_NULL;
+ }
+
+ RegCloseKey(hKey);
+
+ return (szImeFile[0] != UNICODE_NULL);
+}
+
+typedef struct tagLOAD_ICON
+{
+ INT cxIcon, cyIcon;
+ HICON hIcon;
+} LOAD_ICON, *PLOAD_ICON;
+
+static BOOL CALLBACK
+EnumResNameProc(
+ HMODULE hModule,
+ LPCTSTR lpszType,
+ LPTSTR lpszName,
+ LPARAM lParam)
+{
+ PLOAD_ICON pLoadIcon = (PLOAD_ICON)lParam;
+ pLoadIcon->hIcon = (HICON)LoadImage(hModule, lpszName, IMAGE_ICON,
+ pLoadIcon->cxIcon, pLoadIcon->cyIcon,
+ LR_DEFAULTCOLOR);
+ if (pLoadIcon->hIcon)
+ return FALSE; /* Stop enumeration */
+ return TRUE;
+}
+
+static HICON FakeExtractIcon(LPCTSTR szIconPath, INT cxIcon, INT cyIcon)
+{
+ LOAD_ICON LoadIcon = { cxIcon, cyIcon, NULL };
+ HMODULE hImeDLL = LoadLibraryEx(szIconPath, NULL, LOAD_LIBRARY_AS_DATAFILE);
+ if (hImeDLL)
+ {
+ EnumResourceNames(hImeDLL, RT_GROUP_ICON, EnumResNameProc,
(LPARAM)&LoadIcon);
+ FreeLibrary(hImeDLL);
+ }
+ return LoadIcon.hIcon;
}
static HICON
-CreateTrayIcon(LPTSTR szLCID)
+CreateTrayIcon(LPTSTR szLCID, LPCTSTR szImeFile OPTIONAL)
{
LANGID LangID;
TCHAR szBuf[4];
@@ -155,6 +250,13 @@ CreateTrayIcon(LPTSTR szLCID)
HICON hIcon;
INT cxIcon = GetSystemMetrics(SM_CXSMICON);
INT cyIcon = GetSystemMetrics(SM_CYSMICON);
+ TCHAR szPath[MAX_PATH];
+
+ if (szImeFile && szImeFile[0])
+ {
+ if (GetSystemLibraryPath(szPath, ARRAYSIZE(szPath), szImeFile))
+ return FakeExtractIcon(szPath, cxIcon, cyIcon);
+ }
/* Getting "EN", "FR", etc. from English, French, ... */
LangID = LANGIDFROMLCID(_tcstoul(szLCID, NULL, 16));
@@ -236,12 +338,14 @@ AddTrayIcon(HWND hwnd)
{
NOTIFYICONDATA tnid = { sizeof(tnid), hwnd, 1, NIF_ICON | NIF_MESSAGE | NIF_TIP };
TCHAR szLCID[CCH_LAYOUT_ID + 1], szName[MAX_PATH];
+ TCHAR szImeFile[80];
GetLayoutID(_T("1"), szLCID, ARRAYSIZE(szLCID));
GetLayoutName(_T("1"), szName, ARRAYSIZE(szName));
+ GetImeFile(szImeFile, ARRAYSIZE(szImeFile), szLCID);
tnid.uCallbackMessage = WM_NOTIFYICONMSG;
- tnid.hIcon = CreateTrayIcon(szLCID);
+ tnid.hIcon = CreateTrayIcon(szLCID, szImeFile);
StringCchCopy(tnid.szTip, ARRAYSIZE(tnid.szTip), szName);
Shell_NotifyIcon(NIM_ADD, &tnid);
@@ -268,9 +372,12 @@ static VOID
UpdateTrayIcon(HWND hwnd, LPTSTR szLCID, LPTSTR szName)
{
NOTIFYICONDATA tnid = { sizeof(tnid), hwnd, 1, NIF_ICON | NIF_MESSAGE | NIF_TIP };
+ TCHAR szImeFile[80];
+
+ GetImeFile(szImeFile, ARRAYSIZE(szImeFile), szLCID);
tnid.uCallbackMessage = WM_NOTIFYICONMSG;
- tnid.hIcon = CreateTrayIcon(szLCID);
+ tnid.hIcon = CreateTrayIcon(szLCID, szImeFile);
StringCchCopy(tnid.szTip, ARRAYSIZE(tnid.szTip), szName);
Shell_NotifyIcon(NIM_MODIFY, &tnid);
@@ -289,12 +396,12 @@ GetLayoutIDByHkl(HKL hKl, LPTSTR szLayoutID, SIZE_T LayoutIDLength)
static BOOL CALLBACK
EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
- PostMessage(hwnd, WM_INPUTLANGCHANGEREQUEST, 0, lParam);
+ PostMessage(hwnd, WM_INPUTLANGCHANGEREQUEST, INPUTLANGCHANGE_SYSCHARSET, lParam);
return TRUE;
}
static VOID
-ActivateLayout(HWND hwnd, ULONG uLayoutNum)
+ActivateLayout(HWND hwnd, ULONG uLayoutNum, HWND hwndTarget OPTIONAL)
{
HKL hKl;
TCHAR szLayoutNum[CCH_ULONG_DEC + 1], szLCID[CCH_LAYOUT_ID + 1],
szLangName[MAX_PATH];
@@ -311,10 +418,24 @@ ActivateLayout(HWND hwnd, ULONG uLayoutNum)
/* Switch to the new keyboard layout */
GetLocaleInfo(LangID, LOCALE_SLANGUAGE, szLangName, ARRAYSIZE(szLangName));
UpdateTrayIcon(hwnd, szLCID, szLangName);
+
+ if (hwndTarget)
+ SetForegroundWindow(hwndTarget);
+
hKl = LoadKeyboardLayout(szLCID, KLF_ACTIVATE);
+ if (hKl)
+ ActivateKeyboardLayout(hKl, KLF_SETFORPROCESS);
- /* Post WM_INPUTLANGCHANGEREQUEST to every top-level window */
- EnumWindows(EnumWindowsProc, (LPARAM) hKl);
+ /* Post WM_INPUTLANGCHANGEREQUEST */
+ if (hwndTarget)
+ {
+ PostMessage(hwndTarget, WM_INPUTLANGCHANGEREQUEST,
+ INPUTLANGCHANGE_SYSCHARSET, (LPARAM)hKl);
+ }
+ else
+ {
+ EnumWindows(EnumWindowsProc, (LPARAM) hKl);
+ }
ulCurrentLayoutNum = uLayoutNum;
}
@@ -411,8 +532,16 @@ SetHooks(VOID)
VOID
DeleteHooks(VOID)
{
- if (KbSwitchDeleteHooks) KbSwitchDeleteHooks();
- if (g_hHookDLL) FreeLibrary(g_hHookDLL);
+ if (KbSwitchDeleteHooks)
+ {
+ KbSwitchDeleteHooks();
+ KbSwitchDeleteHooks = NULL;
+ }
+ if (g_hHookDLL)
+ {
+ FreeLibrary(g_hHookDLL);
+ g_hHookDLL = NULL;
+ }
}
ULONG
@@ -436,7 +565,7 @@ GetNextLayout(VOID)
return ulCurrentLayoutNum;
}
-LRESULT
+UINT
UpdateLanguageDisplay(HWND hwnd, HKL hKl)
{
TCHAR szLCID[MAX_PATH], szLangName[MAX_PATH];
@@ -450,12 +579,76 @@ UpdateLanguageDisplay(HWND hwnd, HKL hKl)
return 0;
}
-LRESULT
-UpdateLanguageDisplayCurrent(HWND hwnd, WPARAM wParam)
+HWND
+GetTargetWindow(HWND hwndFore)
+{
+ TCHAR szClass[64];
+ HWND hwndIME;
+ HWND hwndTarget = hwndFore;
+ if (hwndTarget == NULL)
+ hwndTarget = GetForegroundWindow();
+
+ GetClassName(hwndTarget, szClass, ARRAYSIZE(szClass));
+ if (_tcsicmp(szClass, szKbSwitcherName) == 0)
+ hwndTarget = g_hwndLastActive;
+
+ hwndIME = ImmGetDefaultIMEWnd(hwndTarget);
+ return (hwndIME ? hwndIME : hwndTarget);
+}
+
+UINT
+UpdateLanguageDisplayCurrent(HWND hwnd, HWND hwndFore)
{
- DWORD dwThreadID = GetWindowThreadProcessId((HWND)wParam, 0);
+ DWORD dwThreadID = GetWindowThreadProcessId(GetTargetWindow(hwndFore), NULL);
HKL hKL = GetKeyboardLayout(dwThreadID);
- return UpdateLanguageDisplay(hwnd, hKL);
+ UpdateLanguageDisplay(hwnd, hKL);
+
+ if (IsWindow(g_hwndLastActive))
+ SetForegroundWindow(g_hwndLastActive);
+
+ return 0;
+}
+
+static UINT GetCurLayoutNum(HKL hKL)
+{
+ UINT i, nCount;
+ HKL ahKL[256];
+
+ nCount = GetKeyboardLayoutList(ARRAYSIZE(ahKL), ahKL);
+ for (i = 0; i < nCount; ++i)
+ {
+ if (ahKL[i] == hKL)
+ return i + 1;
+ }
+
+ return 0;
+}
+
+static BOOL RememberLastActive(HWND hwnd, HWND hwndFore)
+{
+ TCHAR szClass[64];
+
+ hwndFore = GetAncestor(hwndFore, GA_ROOT);
+
+ if (!IsWindowVisible(hwndFore) || !GetClassName(hwndFore, szClass,
ARRAYSIZE(szClass)))
+ return FALSE;
+
+ if (_tcsicmp(szClass, szKbSwitcherName) == 0 ||
+ _tcsicmp(szClass, TEXT("Shell_TrayWnd")) == 0)
+ {
+ return FALSE; /* Special window */
+ }
+
+ /* FIXME: CONWND is multithreaded but KLF_SETFORPROCESS and
+ DefWindowProc.WM_INPUTLANGCHANGEREQUEST won't work yet */
+ if (_tcsicmp(szClass, TEXT("ConsoleWindowClass")) == 0)
+ {
+ HKL hKL = GetKeyboardLayout(0);
+ UpdateLanguageDisplay(hwnd, hKL);
+ }
+
+ g_hwndLastActive = hwndFore;
+ return TRUE;
}
LRESULT CALLBACK
@@ -471,31 +664,30 @@ WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
case WM_CREATE:
{
if (!SetHooks())
+ {
+ MessageBox(NULL, TEXT("SetHooks failed."), NULL,
MB_ICONERROR);
return -1;
+ }
AddTrayIcon(hwnd);
- ActivateLayout(hwnd, ulCurrentLayoutNum);
+ ActivateLayout(hwnd, ulCurrentLayoutNum, NULL);
s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
break;
}
- case WM_LANG_CHANGED:
- {
- return UpdateLanguageDisplay(hwnd, (HKL)lParam);
- }
-
- case WM_LOAD_LAYOUT:
+ case WM_LANG_CHANGED: /* Comes from kbsdll.dll and this module */
{
- ULONG uNextNum = GetNextLayout();
- if (ulCurrentLayoutNum != uNextNum)
- ActivateLayout(hwnd, uNextNum);
+ UpdateLanguageDisplay(hwnd, (HKL)lParam);
break;
}
- case WM_WINDOW_ACTIVATE:
+ case WM_WINDOW_ACTIVATE: /* Comes from kbsdll.dll and this module */
{
- return UpdateLanguageDisplayCurrent(hwnd, wParam);
+ HWND hwndFore = GetForegroundWindow();
+ if (RememberLastActive(hwnd, hwndFore))
+ return UpdateLanguageDisplayCurrent(hwnd, hwndFore);
+ break;
}
case WM_NOTIFYICONMSG:
@@ -537,32 +729,73 @@ WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
case ID_EXIT:
{
- SendMessage(hwnd, WM_CLOSE, 0, 0);
+ PostMessage(hwnd, WM_CLOSE, 0, 0);
break;
}
case ID_PREFERENCES:
{
- SHELLEXECUTEINFO shInputDll = { sizeof(shInputDll) };
- shInputDll.hwnd = hwnd;
- shInputDll.lpVerb = _T("open");
- shInputDll.lpFile = _T("rundll32.exe");
- shInputDll.lpParameters = _T("shell32.dll,Control_RunDLL
input.dll");
- if (!ShellExecuteEx(&shInputDll))
- MessageBox(hwnd, _T("Can't start input.dll"), NULL,
MB_OK | MB_ICONERROR);
-
+ INT_PTR ret = (INT_PTR)ShellExecute(hwnd, NULL,
+ TEXT("control.exe"),
TEXT("input.dll"),
+ NULL, SW_SHOWNORMAL);
+ if (ret <= 32)
+ MessageBox(hwnd, _T("Can't start input.dll"), NULL,
MB_ICONERROR);
break;
}
case ID_NEXTLAYOUT:
{
- ActivateLayout(hwnd, GetNextLayout());
+ HWND hwndTarget = (HWND)lParam, hwndTargetSave = NULL;
+ DWORD dwThreadID;
+ HKL hKL;
+ UINT uNum;
+ TCHAR szClass[64];
+ BOOL bCONWND = FALSE;
+
+ if (hwndTarget == NULL)
+ hwndTarget = g_hwndLastActive;
+
+ /* FIXME: CONWND is multithreaded but KLF_SETFORPROCESS and
+ DefWindowProc.WM_INPUTLANGCHANGEREQUEST won't work yet
*/
+ if (hwndTarget &&
+ GetClassName(hwndTarget, szClass, ARRAYSIZE(szClass)) &&
+ _tcsicmp(szClass, TEXT("ConsoleWindowClass")) == 0)
+ {
+ bCONWND = TRUE;
+ hwndTargetSave = hwndTarget;
+ hwndTarget = NULL;
+ }
+
+ if (hwndTarget)
+ {
+ dwThreadID = GetWindowThreadProcessId(hwndTarget, NULL);
+ hKL = GetKeyboardLayout(dwThreadID);
+ uNum = GetCurLayoutNum(hKL);
+ if (uNum != 0)
+ ulCurrentLayoutNum = uNum;
+ }
+
+ ActivateLayout(hwnd, GetNextLayout(), hwndTarget);
+
+ /* FIXME: CONWND is multithreaded but KLF_SETFORPROCESS and
+ DefWindowProc.WM_INPUTLANGCHANGEREQUEST won't work yet
*/
+ if (bCONWND)
+ {
+ ActivateLayout(hwnd, ulCurrentLayoutNum, hwndTargetSave);
+ }
break;
}
default:
{
- ActivateLayout(hwnd, LOWORD(wParam));
+ if (1 <= LOWORD(wParam) && LOWORD(wParam) <= 1000)
+ {
+ if (!IsWindow(g_hwndLastActive))
+ {
+ g_hwndLastActive = NULL;
+ }
+ ActivateLayout(hwnd, LOWORD(wParam), g_hwndLastActive);
+ }
break;
}
}
@@ -570,13 +803,10 @@ WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
case WM_SETTINGCHANGE:
{
- if (wParam == SPI_SETDEFAULTINPUTLANG)
- {
- //FIXME: Should detect default language changes by CPL applet or by other
tools and update UI
- }
if (wParam == SPI_SETNONCLIENTMETRICS)
{
- return UpdateLanguageDisplayCurrent(hwnd, wParam);
+ PostMessage(hwnd, WM_WINDOW_ACTIVATE, wParam, lParam);
+ break;
}
}
break;
@@ -597,9 +827,13 @@ WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
AddTrayIcon(hwnd);
break;
}
- else if (Message == ShellHookMessage && wParam == HSHELL_LANGUAGE)
+ else if (Message == ShellHookMessage)
{
- PostMessage(hwnd, WM_LANG_CHANGED, wParam, lParam);
+ if (wParam == HSHELL_LANGUAGE)
+ PostMessage(hwnd, WM_LANG_CHANGED, wParam, lParam);
+ else if (wParam == HSHELL_WINDOWACTIVATED)
+ PostMessage(hwnd, WM_WINDOW_ACTIVATE, wParam, lParam);
+
break;
}
return DefWindowProc(hwnd, Message, wParam, lParam);
diff --git a/base/applications/kbswitch/kbswitch.h
b/base/applications/kbswitch/kbswitch.h
index 10d295401fb..91906a08e6b 100644
--- a/base/applications/kbswitch/kbswitch.h
+++ b/base/applications/kbswitch/kbswitch.h
@@ -22,7 +22,6 @@
#define WM_KEY_PRESSED (WM_USER + 10100)
#define WM_LANG_CHANGED (WM_USER + 10200)
#define WM_WINDOW_ACTIVATE (WM_USER + 10300)
-#define WM_LOAD_LAYOUT (WM_USER + 10400)
typedef BOOL (WINAPI *PKBSWITCHSETHOOKS) (VOID);
typedef VOID (WINAPI *PKBSWITCHDELETEHOOKS) (VOID);
diff --git a/base/shell/explorer/trayntfy.cpp b/base/shell/explorer/trayntfy.cpp
index 94dd369103b..9a279240f3c 100644
--- a/base/shell/explorer/trayntfy.cpp
+++ b/base/shell/explorer/trayntfy.cpp
@@ -124,11 +124,6 @@ public:
return TRUE;
}
- LRESULT OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
- {
- return MA_NOACTIVATE;
- }
-
BOOL GetMinimumSize(IN OUT PSIZE pSize)
{
SIZE szClock = { 0, 0 };
@@ -350,7 +345,6 @@ public:
BEGIN_MSG_MAP(CTrayNotifyWnd)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
- MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate)
MESSAGE_HANDLER(WM_THEMECHANGED, OnThemeChanged)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
MESSAGE_HANDLER(WM_SIZE, OnSize)
diff --git a/dll/cpl/input/input_list.c b/dll/cpl/input/input_list.c
index ec415b372fe..49347d841dc 100644
--- a/dll/cpl/input/input_list.c
+++ b/dll/cpl/input/input_list.c
@@ -423,6 +423,9 @@ InputList_Process(VOID)
{
bRet = InputList_SetFontSubstitutes(pCurrent->pLocale->dwId);
InputList_AddInputMethodToUserRegistry(hPreloadKey, hSubstKey, 1, pCurrent);
+
+ /* Activate the DEFAULT entry */
+ ActivateKeyboardLayout(pCurrent->hkl, KLF_RESET);
break;
}
}
@@ -450,12 +453,12 @@ InputList_Process(VOID)
/* Change the default keyboard language */
if (SystemParametersInfoW(SPI_SETDEFAULTINPUTLANG, 0, &pCurrent->hkl, 0))
{
- DWORD dwRecipients = BSM_ALLCOMPONENTS | BSM_ALLDESKTOPS;
+ DWORD dwRecipients = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
BroadcastSystemMessageW(BSF_POSTMESSAGE,
&dwRecipients,
WM_INPUTLANGCHANGEREQUEST,
- 0,
+ INPUTLANGCHANGE_SYSCHARSET,
(LPARAM)pCurrent->hkl);
}
diff --git a/win32ss/user/ntuser/defwnd.c b/win32ss/user/ntuser/defwnd.c
index 9d2021a70eb..e9a44f44bd9 100644
--- a/win32ss/user/ntuser/defwnd.c
+++ b/win32ss/user/ntuser/defwnd.c
@@ -960,7 +960,7 @@ IntDefWindowProc(
if (hwndSwitch)
{
#define ID_NEXTLAYOUT 10003
- UserPostMessage(hwndSwitch, WM_COMMAND, ID_NEXTLAYOUT, 0);
+ UserPostMessage(hwndSwitch, WM_COMMAND, ID_NEXTLAYOUT,
(LPARAM)UserHMGetHandle(Wnd));
}
}
}
diff --git a/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c
b/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c
index 8b6f67c7e9d..d265711f261 100644
--- a/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c
+++ b/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c
@@ -2356,6 +2356,11 @@ ConWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
return DefWindowProcW(hWnd, msg, wParam, lParam);
}
+ /* Detect Alt+Shift */
+ if (wParam == VK_SHIFT && (msg == WM_SYSKEYDOWN || msg ==
WM_SYSKEYUP))
+ {
+ return DefWindowProcW(hWnd, msg, wParam, lParam);
+ }
OnKey(GuiData, msg, wParam, lParam);
break;