3

Question

On Windows, if a program does not use one of the native APIs to produce a GUI, then Windows IME shows a tiny Textbox in the upper left corner to input IME strings, as is the case with Japanese.

enter image description here

Can this textbox be moved programmatically via the Windows API? I just want it moved roughly where the text input happens, so it's not so jarring having to look in the upper left corner all the time. Can someone point me in the right direction, what to read where to search?

Details

I have an OpenGL Program with a simple Immediate-Mode GUI Toolkit on top. As such this program does not interface with the OS's GUI capabilities in any meaningful way to provide OS native behaviour or accessibility functions. For my use-case, similar to many video games, this is fine. If I have textboxes inside the program however, inputting text via Windows or Google IME is an awful experience and I would like to improve it. I am not looking to integrate with Windows any more that this, just moving the IME Textbox roughly to the correct position of the "in program" textbox. It is compiled with MinGW64 and I already used Win32 API functions like changing the program's window and taskbar icon. Is this a possibility via the Win32 api?

FrostKiwi
  • 741
  • 1
  • 6
  • 16
  • 2
    [Your application can direct an IME window to carry out a command, for example, change the position of a composition window, by using the `WM_IME_CONTROL` message.](https://learn.microsoft.com/en-us/windows/win32/intl/ime-messages) – IInspectable Nov 10 '21 at 11:41
  • @IInspectable Many thanks for the super quick response! `Your application can direct an IME window to carry out a command, for example, change the position of a composition window` looks to be spot on. Be sure to make this comment an answer so I can close the question. – FrostKiwi Nov 10 '21 at 12:28
  • 1
    You are encouraged to [answer your own question](https://stackoverflow.com/help/self-answer). Since you have all the code, you are in a far better position to derive and verify a solution. – IInspectable Nov 10 '21 at 12:31
  • @IInspectable True, makes sense, will do. Thanks – FrostKiwi Nov 10 '21 at 16:57

1 Answers1

1

The following code works in moving the IME position from default to current cursor position:

     if (msg.message == WM_IME_STARTCOMPOSITION) { // msg is windows message 
            HIMC imc = ImmGetContext(msg.hwnd);
            COMPOSITIONFORM cf;
            cf.dwStyle = CFS_FORCE_POSITION;
            POINT ptPos;
            bool ret = GetCursorPos(&ptPos);
            if (ret)
            {
                cf.ptCurrentPos.x = ptPos.x;
                cf.ptCurrentPos.y = ptPos.y;
            }
            ImmSetCompositionWindow(imc, &cf);
            ImmReleaseContext(msg.hwnd, imc);
        }

WM_IME_STARTCOMPOSITION is a message type which windows sends to application when it starts IME. In your application when you peek or process windows messages try to catch for WM_IME_STARTCOMPOSITION and then force set the IME composition window position.

Kanchana
  • 11
  • 2