第280章 IMEの操作 その3


今回は、IMEの変換状態を設定します。


IMEの変換状態を設定するにはImmSetConversionStatus関数を使います。

BOOL ImmSetConversionStatus( HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence );

hIMCには、入力コンテキストのハンドルを指定します。

fdwConversionには、入力モードを指定します。

fdwSentenceには、変換モードを指定します。

メニューの「IME」「入力文字種」から全角、半角、カタカナ、ひらかな、 英数などを選択します。全角はIME_CMODE_FULLSHAPEです。

カタカナはIME_CMODE_NATIVE | IME_CMODE_KATAKANAです。 これは、 IME_CMODE_LANGUAGEと同じです。



では、プログラムを見てみましょう。

// ime02.rcの一部 ///////////////////////////////////////////////////////////////////////////// // // Menu // MYMENU MENU DISCARDABLE BEGIN POPUP "ファイル(&F)" BEGIN MENUITEM "終了(&X)...", IDM_END END POPUP "IME(&I)" BEGIN MENUITEM "IMEの入り切り(&O)", IDM_ONOFF MENUITEM "コード入力(&C)", IDM_CODE POPUP "入力文字種(&L)" BEGIN MENUITEM "全角ひらかな(&H)", IDM_ZENHIRA MENUITEM "全角カタカナ(&K)", IDM_ZENKATA MENUITEM "半角カタカナ(&T)", IDM_HANKATA MENUITEM "全角英数(&E)", IDM_ZENEISU MENUITEM "半角英数(&S)", IDM_HANEISU END POPUP "変換モード(&M)" BEGIN MENUITEM "連文節(&R)", IDM_RENBUN MENUITEM "複合語(&P)", IDM_PLU MENUITEM "自動(&A)", IDM_AUTO MENUITEM "口語優先(&C)", IDM_CONV MENUITEM "無変換(&N)", IDM_NONCONV END END END

普通のメニューのリソース・スクリプトです。

// ime02.cpp #ifndef STRICT #define STRICT #endif #define ID_IME 100 #include <windows.h> #include <imm.h> #include "resource.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); ATOM InitApp(HINSTANCE); BOOL InitInstance(HINSTANCE, int); int Err(HWND, char *); char szClassName[] = "ime02"; //ウィンドウクラス

imm.hをインクルードするのを忘れないでください。また、imm32.libをプロジェクトに参加させるのも忘れないで ください。

int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { MSG msg; if (!InitApp(hCurInst)) return FALSE; if (!InitInstance(hCurInst, nCmdShow)) return FALSE; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } //ウィンドウ・クラスの登録 ATOM InitApp(HINSTANCE hInst) { WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; //プロシージャ名 wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst;//インスタンス wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = "MYMENU"; //メニュー名 wc.lpszClassName = (LPCSTR)szClassName; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); return (RegisterClassEx(&wc)); } //ウィンドウの生成 BOOL InitInstance(HINSTANCE hInst, int nCmdShow) { HWND hWnd; hWnd = CreateWindow(szClassName, "猫でもわかるIME", //タイトルバーにこの名前が表示されます WS_OVERLAPPEDWINDOW, //ウィンドウの種類 CW_USEDEFAULT, //X座標 CW_USEDEFAULT, //Y座標 CW_USEDEFAULT, //幅 CW_USEDEFAULT, //高さ NULL, //親ウィンドウのハンドル、親を作るときはNULL NULL, //メニューハンドル、クラスメニューを使うときはNULL hInst, //インスタンスハンドル NULL); if (!hWnd) return FALSE; ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; }

いつもと同じです。

//ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { int id; HIMC hImc; static HWND hEdit; HINSTANCE hInst; CREATESTRUCT *lpcs; DWORD dwConv, dwSent; switch (msg) { case WM_CREATE: lpcs = (CREATESTRUCT *)lp; hInst = lpcs->hInstance; hEdit = CreateWindow("edit", "", WS_CHILD | WS_BORDER | WS_VISIBLE | ES_MULTILINE | ES_WANTRETURN | WS_HSCROLL | WS_VSCROLL, 0, 0, 0, 0, hWnd, (HMENU)ID_IME, hInst, NULL); SetFocus(hEdit); break; case WM_SIZE: MoveWindow(hEdit, 0, 0, LOWORD(lp), HIWORD(lp), TRUE); break; case WM_COMMAND: if (LOWORD(wp) == IDM_END) { SendMessage(hWnd, WM_CLOSE, 0, 0); return 0; } hImc = ImmGetContext(hEdit); ImmGetConversionStatus(hImc, &dwConv, &dwSent); switch (LOWORD(wp)) { case IDM_ONOFF: if (ImmGetOpenStatus(hImc)) { ImmSetOpenStatus(hImc, FALSE); } else { ImmSetOpenStatus(hImc, TRUE); } break; case IDM_CODE: //コード入力 if (ImmSetConversionStatus(hImc, IME_CMODE_CHARCODE, IME_SMODE_NONE) == 0) Err(hWnd, "ImmSetConversionStatus"); break; case IDM_ZENHIRA: //全角ひらかな if (ImmSetConversionStatus(hImc, IME_CMODE_NATIVE | IME_CMODE_FULLSHAPE, dwSent) == 0) Err(hWnd, "ImmSetConversionStatus"); break; case IDM_ZENKATA: //全角カタカナ if (ImmSetConversionStatus(hImc, IME_CMODE_NATIVE | IME_CMODE_FULLSHAPE | IME_CMODE_KATAKANA, dwSent) == 0) Err(hWnd, "ImmSetConversionStatus"); break; case IDM_HANKATA: //半角カタカナ if (ImmSetConversionStatus(hImc, IME_CMODE_NATIVE | IME_CMODE_KATAKANA, dwSent) == 0) Err(hWnd, "ImmSetConversionStatus"); break; case IDM_ZENEISU: //全角英数 if (ImmSetConversionStatus(hImc, IME_CMODE_FULLSHAPE, dwSent) == 0) Err(hWnd, "ImmSetConversionStatus"); break; case IDM_HANEISU: //半角英数 if (ImmSetConversionStatus(hImc, IME_CMODE_ALPHANUMERIC, dwSent) == 0) Err(hWnd, "ImmSetConversionStatus"); break; case IDM_RENBUN: //連文節変換 if (ImmSetConversionStatus(hImc, dwConv, IME_SMODE_PHRASEPREDICT) == 0) Err(hWnd, "ImmSetConversionStatus"); break; case IDM_AUTO: //自動変換 if (ImmSetConversionStatus(hImc, dwConv, IME_SMODE_AUTOMATIC) == 0) Err(hWnd, "ImmSetConversionStatus"); break; case IDM_PLU: //複合語変換 if (ImmSetConversionStatus(hImc, dwConv, IME_SMODE_PLAURALCLAUSE) == 0) Err(hWnd, "ImmSetConversionStatus"); break; case IDM_CONV: //会話優先 if (ImmSetConversionStatus(hImc, dwConv, IME_SMODE_CONVERSATION) == 0) Err(hWnd, "ImmSetConversionStatus"); break; case IDM_NONCONV: //無変換(固定入力) if (ImmSetConversionStatus(hImc, dwConv, IME_SMODE_NONE) == 0) Err(hWnd, "ImmSetConversionStatus"); break; } SetFocus(hEdit); if (ImmReleaseContext(hEdit, hImc) == 0) Err(hWnd, "ImmReleaseConText"); break; case WM_CLOSE: id = MessageBox(hWnd, "終了してもよいですか", "終了確認", MB_YESNO | MB_ICONQUESTION); if (id == IDYES) { DestroyWindow(hEdit); DestroyWindow(hWnd); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0; }

メインウィンドウのプロシージャです。

WM_PAINTメッセージが来たらエディットコントロールを作って、フォーカスを そこに移します。 CREATESTRUCT構造体については第19章を参照してください。

WM_SIZEメッセージが来たらエディットコントロールの大きさを調整します。

メニューからそれぞれの項目が選択されたらImmSetConversionStatus関数でIMEの変換状態を 設定します。この関数の第2引数は前章で調べたものを利用します。 特にIME_CMODE_LANGUAGEには気を付けてください。

Err関数は自作関数です。

int Err(HWND hWnd, char *szStr) { char szBuf[256]; wsprintf(szBuf, "「%s」エラーです", szStr); MessageBox(hWnd, szBuf, "Error", MB_OK | MB_ICONEXCLAMATION); return 0; }

エラー表示用の自作関数です。

さて、こうやってみると今回のプログラムは簡単そうですが、筆者はIMM_CMODE_LANGUAGEで 引っかかって結構時間がかかってしまいました。


[SDK第3部 Index] [総合Index] [Previous Chapter] [Next Chapter]

Update 23/Jul/2000 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。