无法将WM_INPUTLANGCHANGEREQUEST发送到某些控件
本文关键字:控件 INPUTLANGCHANGEREQUEST WM | 更新日期: 2023-09-27 18:35:49
我正在研究(另一个)键盘布局切换器,并在使用Skype窗口(win6.22 x62版本)时遇到了奇怪的麻烦。GetForegroundWindow()/GetFocus()/GetParentWindow() 的任何组合都无法成功更改仅在消息输入内部的布局,更奇怪的是,只有在输入多个字符时。其他情况效果很好,除了 wpf 应用程序拒绝服从没有专注处理的东西。
public static void SetNextKeyboardLayout()
{
IntPtr hWnd = GetForegroundWindow();
uint processId;
uint activeThreadId = GetWindowThreadProcessId(hWnd, out processId);
uint currentThreadId = GetCurrentThreadId();
AttachThreadInput(activeThreadId, currentThreadId, true);
IntPtr focusedHandle = GetFocus();
AttachThreadInput(activeThreadId, currentThreadId, false);
PostMessage(focusedHandle == IntPtr.Zero ? hWnd : focusedHandle, WM_INPUTLANGCHANGEREQUEST, INPUTLANGCHANGE_FORWARD, HKL_NEXT);
}
我是 winapi 的新手,所以任何帮助将不胜感激,谢谢。
在拆卸了一些工作产品后,我发现我接近正确的算法,如下所示:
public static void SetNextKeyboardLayout()
{
IntPtr hWnd = IntPtr.Zero;
var threadId = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero);
var currentThreadId = GetCurrentThreadId();
var info = new GUITHREADINFO();
info.cbSize = Marshal.SizeOf(info);
var success = GetGUIThreadInfo(threadId, ref info);
// target = hwndCaret || hwndFocus || (AttachThreadInput + GetFocus) || hwndActive || GetForegroundWindow
AttachThreadInput(threadId, currentThreadId, true);
IntPtr focusedHandle = GetFocus();
AttachThreadInput(threadId, currentThreadId, false);
if (success)
{
if (info.hwndCaret != IntPtr.Zero) { hWnd = info.hwndCaret; }
else if (info.hwndFocus != IntPtr.Zero) { hWnd = info.hwndFocus; }
else if (focusedHandle != IntPtr.Zero) { hWnd = focusedHandle; }
else if (info.hwndActive != IntPtr.Zero) { hWnd = info.hwndActive; }
}
else
{
hWnd = focusedHandle;
}
if (hWnd == IntPtr.Zero) { hWnd = GetForegroundWindow(); }
PostMessage(hWnd, WM_INPUTLANGCHANGEREQUEST, INPUTLANGCHANGE_FORWARD, HKL_NEXT);
}
但问题不在于找到PostMessage目标hWnd,而在于Skype的输入处理。我已经通过在WM_INPUTLANGCHANGEREQUEST
之前添加微小的延迟来解决它,以便 skype 可以正确处理发送给它的所有输入。现在我必须在没有延迟的情况下让事情顺利进行,但这是另一回事。
你应该试试这个: PostMessage(hWnd,WM_INPUTLANGCHANGEREQUEST,0,(LPARAM)HKL_NEXT);
附言:在Windows 10下,任何WM_ INPUTLANGCHANGEREQUEST
都会使Skype崩溃。
Windows 10的最佳方法是模拟切换键盘布局的按键,如下所示:
keybd_event(VK_LWIN, 0, KEYEVENTF_EXTENDEDKEY, 0);
keybd_event(VK_SPACE,0, KEYEVENTF_EXTENDEDKEY, 0);
Sleep(10);
keybd_event(VK_SPACE,0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
keybd_event(VK_LWIN, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);