Как предотвратить переключение входа IME при отображении всплывающих окон? - PullRequest
0 голосов
/ 24 апреля 2019

В моем приложении мы используем Форма в качестве контейнеров, затем мы создаем NativeWindow .

Мне нужно показать всплывающее окно с текстовым полем поиска. Всякий раз, когда я показываю это всплывающее окно, мой ввод IME переключается с китайского / японского на английский режим. Исходя из таких статей, как this , контекст ввода должен быть либо для пользователя, либо для потока. Почему мой ввод изменится в моем приложении? (Я тестирую на Windows 10)

Я попытался сохранить основное приложение активным, выполнив это, это предотвратило бы переключение ввода, НО тогда мое окно поиска больше не будет получать ввод с клавиатуры, когда я его показываю, поэтому я не могу использовать этот метод:

       protected override void WndProc(ref System.Windows.Forms.Message m) {
            switch(m.Msg) {
                case (int)WM.ACTIVATE:
                    if(m.WParam.ToInt64() == 1) {
                        UserMethods.SetActiveWindow(PopupOwner.Handle);
                    }
                    break;
            }
            base.WndProc(ref m);
        }

Кажется, что вход переключается при изменении моего активного окна. Но мое окно поиска должно захватывать клавиатуру, поэтому я считаю, что у меня нет выбора, кроме как изменить активное окно.

Я также пытался создать свой собственный входной контекст , переопределить CanEnableIme и установить ImeMode, ни одна из этих функций не работает идеально, я могу объяснить детали, если это поможет.

Примечание: мое поле поиска - это настраиваемый текстовый редактор, а не элемент управления текстового поля формы; Я сделал так, чтобы он обрабатывал ввод IME, обрабатывая системные сообщения, такие как this , но я не изменяю контекст ввода, только чтение из него.

Как сохранить режим ввода IME неизменным при изменении активного окна?

1 Ответ

0 голосов
/ 01 мая 2019

Я до сих пор не знаю, почему мой вход переключается в моем приложении.

Но чтобы сохранить режим IME неизменным после отображения всплывающего окна с помощью окна поиска, я перехватываю состояние IME до того, как всплывающее окно получаетактивирован, и после его активации я изменяю статус IME.Примерно так:

var imeOpened = false;
//get ime status
var hImc = ImmGetContext(popup.handle);
if(hImc != IntPtr.Zero) {
  imeOpened = ImmGetOpenStatus(hImc);
}

Showpopup();

//open ime if it was opened
if(hImc != IntPtr.Zero) {
  if(imeOpened) ImmSetOpenStatus(hImc, true);
  ImmReleaseContext(popup.handle, hImc);
}

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

using(TrapOpenedIme(popup.handle)) Showpopup()

ПРИМЕЧАНИЕ: ImmSetConversionStatus иImmGetConversionStatus у меня не сработало.

Это хакерское исправление, но лучше, чем ничего: (

...