如何使用模态窗口将WM_INPUTLANGCHANGEREQUEST发送至应用程序? [英] How to send WM_INPUTLANGCHANGEREQUEST to app with modal window?

查看:486
本文介绍了如何使用模态窗口将WM_INPUTLANGCHANGEREQUEST发送至应用程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个键盘切换器,它工作正常,但是如果当前应用程序已打开模式窗口,则会失败.在键盘开关上,请执行以下操作

I wrote a keyboard switcher, which works well, but fails if current application has modal window opened. On keyboard switch I do the following

hwnd = GetForegroundWindow();
PostMessage(hwnd, WM_INPUTLANGCHANGEREQUEST, IntPtr.Zero, handle);

其中

[DllImport("User32.dll", EntryPoint = "PostMessage")]
private static extern int PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();

,但语言不会改变.

我该怎么做?

添加使root所有者的情况有所改善,但并没有完全解决问题.

Adding get root owner improved situation, but didn't help completely.

添加对GetDesktopWindow的呼叫没有帮助:

Adding call for GetDesktopWindow didn't help:

hwnd = GetDesktopWindow();
InputLangChangeRequest(hwnd, language);
hwnd = GetRootOwner();
InputLangChangeRequest(hwnd, language);


代码在此处 https://github.com/dims12/NormalKeyboardSwitcher

推荐答案

使用

通过遍历父级和子级链来检索拥有的根窗口 GetParent返回的所有者窗口.

Retrieves the owned root window by walking the chain of parent and owner windows returned by GetParent.

如果存在模态窗口或模态窗口链,则应该返回主UI窗口.

This should return the main UI window if there is a modal window, or a chain of modal window.

hwnd = GetForegroundWindow();
hwnd = GetAncestor(hwnd, GA_ROOTOWNER); //#define GA_ROOTOWNER 3


如果目标本身是基于对话框的应用程序,显然WM_INPUTLANGCHANGEREQUEST会失败(我不知道为什么!)要解决此问题,您可以将WM_INPUTLANGCHANGEREQUEST消息发布到对话框的后代(除了WM_INPUTLANGCHANGEREQUEST消息之外)


Apparently WM_INPUTLANGCHANGEREQUEST fails if the target itself is a dialog based application (I don't know why!) To solve the problem you can post WM_INPUTLANGCHANGEREQUEST message to dialog's descendants (in addition to WM_INPUTLANGCHANGEREQUEST message to the dialog itself)

static bool MyEnumProc(IntPtr hwnd, IntPtr lParam)
{
    PostMessage(hwnd, WM_INPUTLANGCHANGEREQUEST, IntPtr.Zero, lParam);
    return true;
}

static void Foo()
{
    //Greek input for testing:
    var hkl = LoadKeyboardLayout("00000408", KLF_ACTIVATE);
    var hwnd = GetForegroundWindow();
    if (hwnd != null)
    {
        hwnd = GetAncestor(hwnd, GA_ROOTOWNER);
        PostMessage(hwnd, WM_INPUTLANGCHANGEREQUEST, IntPtr.Zero, (IntPtr)hkl);

        StringBuilder buf = new StringBuilder(100);
        GetClassName(hwnd, buf, 100);

        //if this is a dialog class then post message to all descendants 
        if (buf.ToString() == "#32770")
            EnumChildWindows(hwnd, MyEnumProc, (IntPtr)hkl);
    }
}

这篇关于如何使用模态窗口将WM_INPUTLANGCHANGEREQUEST发送至应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆