Как получить макет IME в C # Winform специально в Wndproc?

У меня есть приложение winform, я хочу получить информацию о текущем языке ввода в C #. У меня машина с Windows 10, я выбрал корейский язык. На панели задач есть одна кнопка-переключатель, с помощью которой можно изменить язык ввода на английский или корейский после выбора корейского языка.

В следующем коде всегда отображается корейский язык, но он должен давать английский, когда я выбираю ввод на английском языке.

    [DllImport("user32.dll")]
    static extern IntPtr GetForegroundWindow();
    [DllImport("user32.dll")]
    static extern uint GetWindowThreadProcessId(IntPtr hwnd, IntPtr proccess);
    [DllImport("user32.dll")]
    static extern IntPtr GetKeyboardLayout(uint thread);
    public Form1()
    {
        InitializeComponent();
        IntPtr foregroundWindow = GetForegroundWindow();
        uint foregroundProcess = GetWindowThreadProcessId(foregroundWindow, IntPtr.Zero);
        int keyboardLayout = GetKeyboardLayout(foregroundProcess).ToInt32() & 0xFFFF;
        CultureInfo info = new CultureInfo(keyboardLayout);
        int keyboardLayoutId = info.KeyboardLayoutId;
        string name = info.Name;
    }

Есть ли другой способ получить информацию о языке ввода.

Вы можете найти прикрепленное изображение для того же. Я выделил A как ввод на английском языке. Ввод на английском языке: снимок экрана панели задач

Снимок экрана панели задач

Мне нужна эта информация в WndProc методе.

Краткое описание проблемы: Итак, я хочу обработать случай, когда пользователь переключил язык для ввода с помощью кнопки переключения, я хочу, чтобы любое сообщение wndproc или побочное событие окна получали информацию о языке, когда пользователь переключает язык с помощью кнопки переключения.


person vivek nuna    schedule 08.02.2017    source источник
comment
InputLanguage.CurrentInputLanguage   -  person Reza Aghaei    schedule 08.02.2017
comment
@RezaAghaei, как использовать InputLanguage.CurrentInputLanguage?   -  person vivek nuna    schedule 08.02.2017
comment
Я использовал такой сценарий: Как изменить язык ввода в приложении Windows Forms для определенного элемента управления?   -  person Reza Aghaei    schedule 08.02.2017
comment
Прочтите руководство: msdn.microsoft.com/en-us/library/   -  person Equalsk    schedule 08.02.2017
comment
@RezaAghaei InputLanguage.CurrentInputLanguage дает корейский язык, но мой язык ввода - английский   -  person vivek nuna    schedule 08.02.2017
comment
Вы действительно ожидаете, что форма, которую вы только что создаете, уже будет окном переднего плана? Возможно, вы захотите лучше понять, как работают Windows и Windows Forms - это довольно опасно наивный подход. И даже если вы действительно проверили правильную настройку формы, это вам не поможет - каждый поток имеет свой собственный язык ввода. Приложение, которое вы только что запустили, просто получит значение по умолчанию. Не существует глобального макета ввода.   -  person Luaan    schedule 08.02.2017
comment
Кнопка на панели инструментов изменяет выбранную раскладку клавиатуры для процесса, который находится на переднем плане. Учитывая, что ваш код запускается, ох, через микросекунду после запуска вашей программы, вы вряд ли сможете нажать эту кнопку на панели инструментов достаточно быстро. Так что это просто проблема pebkac. Рассмотрим, возможно, событие InputLanguageChanged.   -  person Hans Passant    schedule 08.02.2017
comment
@HansPassant Мне нужна эта информация в WndProc   -  person vivek nuna    schedule 08.02.2017
comment
Так? InputLanguage.CurrentInputLanguage отлично работает в WndProc. InputLanguageChanged позволяет реагировать на изменение языка ввода. Опять же, язык ввода - на поток. Тот факт, что одно приложение использует корейский язык, не означает, что ваше использует его (пока вы не измените его для своего приложения).   -  person Luaan    schedule 08.02.2017
comment
Сообщение WM_INPUTLANGUAGECHANGE. Уже завернутый в Winforms, он запускает событие InputLanguageChanged.   -  person Hans Passant    schedule 08.02.2017
comment
@Luaan InputLanguage.CurrentInputLanguage предоставляет корейский, а не английский язык в WndProc   -  person vivek nuna    schedule 08.02.2017
comment
И в той же форме, одновременно на панели задач отображается английский? Сомневаюсь. На ваших скриншотах приложение с фокусом - это Chrome, а не ваше приложение.   -  person Luaan    schedule 08.02.2017
comment
@Luaan да, только на английском. В центре внимания только мое приложение   -  person vivek nuna    schedule 08.02.2017
comment
@HansPassant WM_INPUTLANGUAGECHANGE срабатывает только тогда, когда я изменяю языковые предпочтения, а не кнопку переключения   -  person vivek nuna    schedule 08.02.2017
comment
Поэтому добавьте к своему вопросу это, а не снимок экрана Chrome. И добавьте реальный способ проверки языка ввода, а не фиктивный код в конструкторе форм. Создайте форму с помощью кнопки и, нажав кнопку, проверьте язык ввода (скажем, установите текст метки на InputLanguage.CurrentInputLanguage.LayoutName.   -  person Luaan    schedule 08.02.2017
comment
Я заметил на своем домашнем ПК с Windows 10 (та же ОС, что и OP), какой языковой переключатель больше не используется для каждого процесса / окна. Это довольно глобально (или, что более вероятно, для рабочего стола, поскольку вы можете создать несколько и переключаться между ними). Могут ли быть какие-то настройки для управления этим поведением?   -  person Sinatr    schedule 08.02.2017
comment
@Luaan также попробовал событие TextChanged, тот же результат также дал корейский   -  person vivek nuna    schedule 08.02.2017
comment
@all Прошу повторно открыть этот вопрос, я все перепробовал   -  person vivek nuna    schedule 08.02.2017
comment
Значит, если вы поместите текстовое поле в форму и наберете его, вы получите текст на английском языке, хотя InputLanguage.CurrentInputLanguage.LayoutName одновременно возвращает корейский? Вы используете встроенный IME в Windows или какое-то специальное программное обеспечение?   -  person Luaan    schedule 08.02.2017
comment
@Luaan Да, это точно так же. Я помещаю текстовое поле в форму и набираю его, вы получаете текст на английском языке, хотя InputLanguage.CurrentInputLanguage.LayoutName одновременно возвращает корейский   -  person vivek nuna    schedule 08.02.2017
comment
@Luaan, я использую только Windows IME   -  person vivek nuna    schedule 08.02.2017
comment
@Luaan После того, как вы выберете корейский язык, появится кнопка переключения между английским и корейским языками. Я также добавил изображение в вопросе.   -  person vivek nuna    schedule 08.02.2017
comment
Хорошо, это все объясняет. Это не язык ввода - это макет IME. Вы никогда не меняете язык ввода.   -  person Luaan    schedule 08.02.2017
comment
@Luaan, Да я не знаю, как это назвать, извините за это. Итак, у вас есть идеи, как это получить?   -  person vivek nuna    schedule 08.02.2017
comment
@all, через 2 дня начнется баунти за этот вопрос: P   -  person vivek nuna    schedule 08.02.2017


Ответы (1)


Ваш вопрос вызван путаницей в режиме IME и макете ввода. Ваш макет ввода корейский в обоих случаях - изменения в вашем режиме IME.

Вы можете найти режим IME элемента управления вводом с помощью Control.ImeMode (и проверить наличие изменений с помощью Control.ImeModeChanged). Это сообщит вам, что вы используете корейский - хангыль или корейский - альфа. РЕДАКТИРОВАТЬ: На самом деле, это позволяет вам только принудительно установить заданный параметр, а не читать указанный пользователем режим IME и, по-видимому, не должен ' т использоваться.

Еще одна сложность заключается в том, что у вас включен глобальный ввод (доступный с Windows 8), когда конфигурация ввода больше не сохраняется для каждого потока, а является глобальной. В этом случае ImeMode не работает и полностью игнорируется. Я не думаю, что вы можете что-то с этим поделать со стороны приложения - настройки больше не ваши, чтобы видеть или изменять. Согласно MSDN, правильной заменой будет ImmGetConversionStatus, но только для настольных приложений.

person Luaan    schedule 08.02.2017
comment
Он дает NoControl в каждом случае - person vivek nuna; 08.02.2017
comment
@viveknuna Да, потому что у вас включен глобальный ввод. Как я отмечал в третьем абзаце, это полностью отключает функцию ImeMode. - person Luaan; 08.02.2017
comment
это означает, что невозможно получить информацию о том, печатаете ли вы на корейском или английском языках. - person vivek nuna; 08.02.2017
comment
@viveknuna Лучшее, что я смог найти, это imm32.dll, но я не уверен, как это будет работать на практике, и стоит ли его использовать. В Windows кажется, что это не ваше дело, так сказать, это что-то для пользователя. И учитывая, насколько сложны IME, я не могу сказать, что не согласен: D - person Luaan; 08.02.2017
comment
начнёт баунти за этот вопрос через 2 дня: P - person vivek nuna; 08.02.2017
comment
попробовал ImmGetConversionStatus это тоже. но всегда возвращает истину - person vivek nuna; 08.02.2017
comment
Пожалуйста, помогите, в Интернете тоже нет поддержки IME. - person vivek nuna; 08.02.2017
comment
@viveknuna Он возвращается только в том случае, если запрос был успешным - вам нужно использовать аргументы out, чтобы получить сам статус преобразования. Использование out int в объявлении P / Invoke должно работать нормально. - person Luaan; 08.02.2017
comment
параметры out одинаковы в обоих случаях - person vivek nuna; 08.02.2017
comment
@viveknuna Странно. Возможно, imm32 не поддерживает корейский IME (похоже, он не указан в поддерживаемых статусах преобразования), или, может быть, он также не работает с глобальными режимами ввода. - person Luaan; 08.02.2017
comment
Я очень расстроен - person vivek nuna; 08.02.2017