UI Window

The IME windows of the IME class are created by applications or by the system. When the IME window is created, the UI window that is provided by IME itself is created and owned by the IME window. Each UI window has the current input context. You can retrieve the input context by calling the GetWindowLong function and specifying the IMMGWL_IMC index value when the UI window receives an IME message (WM_IME_*). The UI window can refer to this input context and handle the messages. The UI window can retrieve the input context at any time except in response to the WM_CREATE message.

The IME must not alter the extra window data of a UI window. If you need extra window data for an instance of a UI window, you can use SetWindowLong and GetWindowLong with IMMGWL_PRIVATE. The IMMGWL_PRIVATE value provides access to a LONG value of extra data for an instance of a UI window. If you need more than one LONG value of extra data, you can store the handle of a memory block into the IMMGWL_PRIVATE area.

The UI window procedure can use the DefWindowProc function, but the UI window must not pass IME messages to DefWindowProc. Even if an IME message is not handled by the UI window procedure, the UI window must not pass it to DefWindowProc.


LRESULT UIWndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    HIMC hIMC;
    HGLOBAL hMyExtra;

    switch(msg){
        case WM_CREATE:
            // Allocate the memory bloack for the window instance.
            hMyExtra = GlobalAlloc(GHND,size_of_MyExtra);
            if (!hMyExtra)
                MyError();

            // Set the memory handle into IMMGWL_PRIVATE
            SetWindowLong(hWnd, IMMGWL_PRIVATE, (LONG)hMyExtra);
                .
                .
                .
            break;

        case WM_IME_xxxx:
            // Get IMC;
            hIMC = GetWindowLong(hWnd,IMMGWL_IMC);

            // Get the memory handle for the window instance.
            hMyExtra = GetWindowLong(hWnd, IMMGWL_PRIVATE);

            lpMyExtra = GlobalLock(hMyExtra);
                .
                .
                .
            GlobalUnlock(hMyExtra);

            break;

            .
            .
            .

        case WM_DESTROY:
            // Get the memory handle for the window instance.
            hMyExtra = GetWindowLong(hWnd, IMMGWL_PRIVATE);

            // Free the memory block for the window instance.
            GlobalFree(hMyExtra);
            break;

        default:
            return DefWindowProc(hWnd, msg, wParam, lParam);

    }
}

The UI window must perform actions within the currently selected input context. When a window is activated, the UI window receives a message that provides the current input context. After this, the UI window runs on the currently selected input context. The input context must have all of the information needed by the UI window for showing the composition window, the status window, and so on.

The UI window refers to the input context, but the window doesn't need to update the context by itself. When the UI window needs to update the input context, it should call IMM functions because the input context is managed by IMM. When the input context changes, IMM and IME receive a notification.

For example, sometimes the UI window needs to change the conversion mode of the input context when the mouse is clicked. To set the conversion mode, the UI window calls the ImmSetConversionMode function, which generates a notification for NotifyIME and sends the WM_IME_NOTIFY message to the UI window. If the UI window changes the display of the conversion mode, the UI window should wait for the WM_IME_NOTIFY message.