2009年2月1日日曜日

日本語入力



クロスプラットフォームで作りたいと言った端からいきなり機種依存なところです。(^_^;

普通にWindowsアプリとか作る場合は、OSやコントロールが標準で提供してくれる機能を使って普通に日本語入力できるんですが、OpenGLみたいなグラフィクスライブラリを使って一からアプリを作る場合(特にフルスクリーン対応の場合)は、文字の入力機能も自前で作らなければなりません。それ以前にまず、描画するためのウィンドウを用意しないといけません。OpenGLを使う場合の定番といえば、glutというクロスプラットフォームなウィンドウシステム用のライブラリがあるんですが、本格的に使うには少し機能が貧弱なのと、日本語入力に対応していないという問題があります。他にもSDLというこれまた有名なライブラリもありますが、こちらもどうやら日本語入力に対応していないようです。

ということなので、ここは涙を飲んで、おもいっきし機種依存のコードを書くことにします。WindowsだとWindowsAPI、Macだと、CocoaとかCarbon、Linuxだと、GTK+とかQT使ったり直にXlib使ったりでしょうか。ひとまずここは馴染みのあるWindowsでやってみることにします。

というこで、久しぶりにWindowsAPIと格闘です。といっても一から書くのは面倒くさいので、これまた有名なNeHeから適当にテンプレートを拝借してきました。ついでにフォント表示についてもここのチュートリアルを参考にしました。

日本語入力に対応するためには、WM_IME_NOTIFYとか、WM_IME_COMPOSITIONなどのIME用のメッセージに応答しなければなりません。http://www.kumei.ne.jp/c_lang/sdk3/sdk_278.htm をとっても参考にさせて頂きました。m__m

...んで、悪戦苦闘の末、なんとか入力できるようになったんですが、OSが自動的に出す変換候補のリストを出さないようにすることができません。これを出さないようにしないと特にフルスクリーンの場合画面がちらついてしまいます。ちゃんと、メッセージ補足してデフォルトの処理を呼ばないようにしてるはずなのに、うまくいかない...と諦めかけていたところ、この記事を見つけました。そもそもやり方が間違ってたんですね。

デフォルトの処理を呼ばないようにするんじゃなくて、フラグを落としてデフォルトの処理を呼ぶのが正解と...


case WM_IME_SETCONTEXT:
{
// return 0; <== これじゃダメ
lParam &= ~ISC_SHOWUIALL;
break;
}
:
return DefWindowProc(hWnd, uMsg, wParam, lParam);


ったく紛らわしい。

とりあえず、リスト表示はされなくなりました。まだリスト表示っぽいタイミングで画面のちらつき(フルスクリーンの場合)があったりとか、フォントをビットマップ描画しているので粗いとか、入力の都度ビットマップ生成しているのでキャッシュとか使うようにしないと効率悪いとか、いろいろ問題があるんですが、まぁ今日の所はひとまずよしとしときます。

はぁ、ちかれた。

0 件のコメント: