0

In my application, we use Form as containers, then we make customized NativeWindow.

I need to show a popup with search textbox on it. Whenever I show this popup, my IME input would switch from Chinese/Japanese to English Mode. Based on articles like this, input context should be either per user or per thread, why would my input change within my same app? (I am testing on Windows 10)

I have tried to keep the main app active by doing this, this would prevent the input from switching, BUT then my search box will not get keyboard input anymore when I show it, so I cannot use this method:

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

It seems like the input switches as my active window changes. But my search box needs to grab keyboard, so I believe I have no chioce but to change the active window.

I have also tried to create my own input context, override CanEnableIme, and set ImeMode, none of these works perfectly, I can explain the details if that helps.

Note: my search box is a customized text editor, not the form textbox control; I made it handle IME input by processing system messages like this, but I am not modifying the input context, only reading from it.

How do I keep IME input mode stays the same when I change active window?

2
  • Can you make sure the main app and the popup box are in the same thread? Check it with GetWindowThreadProcessId return value. Commented Apr 25, 2019 at 10:07
  • Thank you @DrakeWu-MSFT, confirmed that they are on the same thread. Commented Apr 25, 2019 at 17:40

1 Answer 1

0

I still don't know why would my input switches within my app.

But to keep the IME mode stays the same after showing the popup with searchbox, I trap the IME status before the popup window gets activated, and after it's activated, I modify the IME status. Something like this:

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

In my app I have a disposable trapper, which make this a lot cleaner:

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

NOTE: ImmSetConversionStatus and ImmGetConversionStatus didn't work for me.

It's a hacky fix, but better than nothing :(

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.