imm.h,imm32.libを読み込み、ImmAssociateContextなどを使ってIMEへアクセスする。
#include <windows.h> #include <imm.h> #pragma comment(lib, "imm32.lib") LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { HIMC hIMC; int inx = 100; int iny = 100; switch (message) { case WM_CREATE:
// IMEを使用可能にする ImmAssociateContext(hWnd, ImmCreateContext()); break;
case WM_IME_STARTCOMPOSITION:
// IMEでの入力が開始される
OutputDebugString(L"IME 入力開始\n"); hIMC = ImmGetContext(hWnd); // IMEコンテキストを取得 if (hIMC) { // IMEのウィンドウ位置を設定 COMPOSITIONFORM cf2; cf2.dwStyle = CFS_POINT; cf2.ptCurrentPos.x = inx; cf2.ptCurrentPos.y = iny; ImmSetCompositionWindow(hIMC, &cf2); // IMEのウィンドウ位置を設定 ImmReleaseContext(hWnd, hIMC); } break;
case WM_IME_COMPOSITION:
// IMEの入力中の処理 hIMC = ImmGetContext(hWnd); if (hIMC) { if (lParam & GCS_RESULTSTR) { // GCS_RESULTSTR ... IMEの入力が確定されたフラグ // 確定した文字列のバイト数を取得(NULLは含まない) DWORD inputBytes = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, NULL, 0); if (inputBytes) { size_t U16Count = inputBytes / sizeof(wchar_t) + 1;// wchar_tでの、NULLを含んだ文字数 wchar_t* buffer = new wchar_t[U16Count]; // 確定した文字列を取得 ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, buffer, inputBytes); buffer[U16Count - 1] = L'\0'; // 確定した文字列を描画 HDC hdc = GetDC(hWnd); TextOutW(hdc, inx, iny, buffer, wcslen(buffer)); ReleaseDC(hWnd, hdc); delete[] buffer; } } ImmReleaseContext(hWnd, hIMC); } break;
case WM_IME_ENDCOMPOSITION:
OutputDebugString(L"IME 入力終了\n"); break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return DefWindowProc(hWnd, message, wParam, lParam);;
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) {
    WNDCLASS wc;
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = L"SZL-IME-TEST";
    RegisterClass(&wc);
    HWND hWnd = CreateWindowW(L"SZL-IME-TEST", L"title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, hInstance, NULL);
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    MSG msg = {};
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return (int)msg.wParam;
}
