Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Can';t向某些控件发送WM_INPUTLANGCHANGEREQUEST_C#_Windows_Winapi - Fatal编程技术网

C# Can';t向某些控件发送WM_INPUTLANGCHANGEREQUEST

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

我正在处理(另一个)Skype窗口(win7 x64上的6.22版)出现了奇怪的问题。GetForegroundWindow()/GetFocus()/GetParentWindow()的函数仅在消息输入内部更改布局,更奇怪的是,仅在输入多个字符时更改布局。除了wpf应用程序拒绝遵守而没有focusedHandle的东西外,其他的情况都非常好

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);

请把你的密码寄出去。