C# Can';t向某些控件发送WM_INPUTLANGCHANGEREQUEST
我正在处理(另一个)Skype窗口(win7 x64上的6.22版)出现了奇怪的问题。GetForegroundWindow()/GetFocus()/GetParentWindow()的函数仅在消息输入内部更改布局,更奇怪的是,仅在输入多个字符时更改布局。除了wpf应用程序拒绝遵守而没有focusedHandle的东西外,其他的情况都非常好C# Can';t向某些控件发送WM_INPUTLANGCHANGEREQUEST,c#,windows,winapi,C#,Windows,Winapi,我正在处理(另一个)Skype窗口(win7 x64上的6.22版)出现了奇怪的问题。GetForegroundWindow()/GetFocus()/GetParentWindow()的函数仅在消息输入内部更改布局,更奇怪的是,仅在输入多个字符时更改布局。除了wpf应用程序拒绝遵守而没有focusedHandle的东西外,其他的情况都非常好 public static void SetNextKeyboardLayout() { IntPtr hWnd = GetFor
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\u INPUTLANGCHANGEREQUEST
之前添加一个微小的延迟来解决这个问题,这样skype就可以正确地处理发送给它的所有输入。现在,我必须毫不拖延地完成工作,但这是另一个故事。您应该尝试以下操作:PostMessage(hWnd,WM\u INPUTLANGCHANGEREQUEST,0,(LPARAM)HKL\u NEXT)代码>
另附:
在Windows 10下,任何WM\ucode>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);
请把你的密码寄出去。