漢字変換候補一覧を得る

久しぶりに技術系エントリー。

C#で独自仕様のソフトウェアキーボードを作ってほしい、という依頼を受けたので、いまその仕事をしています。
UIはまぁ、独自仕様とはいうものの、要はケータイ入力方式なだけですけどね。
で、UI周りはサクサクと作れたわけです。いやまぁまだ完成してませんが。

一番の問題は漢字変換で、読み仮名から漢字の変換候補の一覧を得る方法。
よみがなの文字列を引数にセットしたら、変換候補一覧が返ってくるような関数が欲しいわけです。

てっきりWin32 APIで簡単にできるもんだと楽観視していたのですが、こいつがどうにも厄介で。
なかなか苦労させられました。

結果を言えば、条件付きで出来た。です。

もともと漢字変換周りの知識は皆無だったので、まずはどうやって実現したらいいのか調べるところから。
で調べた結果、いくつか見つかったのですが、どれも問題がありそう。

・IFELanguage(2)を使う
・ImmGetConversionListを使う
・ImmGetCandidateListを使う
・TSF(Text Service Framerowk)を使う

最初のIFELanguage(IFELanguage2)は、ひらがなを漢字に、または漢字の読み仮名を取得等が比較的簡単に実現できるものの、今回の目的である
変換候補一覧の取得には使えないっぽいです。
(もしかしたら出来るかもしれないけど、私が調べた限りでは無理っぽかった)
漢字の読み仮名取得が目的だったらこれでよかったんですけどね。
参考: Microsoft IME の IFELanguage を使用して 読み仮名から漢字、漢字から読み仮名変換を行う簡易プログラム :: Netplanetes Memo
C#でそのものずばりのサンプルコードが載ってます。

で、次のImmGetConversionListですが、試しに組んでみたら、変換候補っぽいのが取れるには取れたのですよ。
だけど何か少ない。変換候補ってもっと沢山あるんじゃないの?と。
どうやらImmGetConversionListは変換候補の一覧を得られるものではなく、変換履歴を取得する関数らしい。
これは目的に合わないので、却下。

ちなみにImmGetConversionListの実験を始めた当初、デフォルト設定のIMEをGoogle日本語入力(GoogleJapaneseInput-1.8.1310.0)にしていたのですが、
なかなか変換候補(実は変換履歴)が得られなくて、試しにMS-IME2010に切り替えたら、あっさり取得できました。
Googleェ・・・

次にImmGetCandidateListですが、本当はコレで変換候補一覧が取得できるはずなのですが、どう頑張っても取得できなくて諦めました。
どこかの掲示板の書き込みで「ImmGetCandidateListはIMEの入力に対する変換候補一覧の取得を行うものだから、独自の文字列から変換候補を得るのは無理」みたいなことが書いてあったりして、挫折しました。
正確には、変換前の文字列を設定するImmSetCompositionString関数の時点でどうしても失敗が返ってくる。
思いついたことは全部やったつもりだけど、上手くいかなかったので、とりあえずImmGetCandidateListを使う方法を探るのを一旦やめて、別の方法を探ることにしました。

で、最後にTSFです。
事前にちょろっとTSFについて調べた所、「うわっ、面倒くさそう」と思って後回しにしていたのでした。
TSFに関しては下記サイトが詳しいので見てもらうとして
TSF を使う (1) – Windows Input Method の歴史 :: Nyaruruが地球にいたころ

とりあえずTSFで本当に目的の変換候補一覧取得ができるのかを試すため、Windows SDKのtsfappをビルドしてみたりしたのですが
ここでもまたIMEの種類によって取得できたりできなかったり。
Google日本語入力だとReconvertが使えないとか・・・なんなのGoogle日本語入力。

でもまぁ、MS-IMEなら一応変換候補一覧取得は可能なのが解ったので、TSFでいくことに。
仕事の依頼内容は特定の機器での使用を前提にしているので、MS-IMEのみサポート対象ってのは通りそうだし。

さて、それでTSFですが、面倒くさいです。
単純に変換候補一覧が欲しいだけななのに、なんでこんなに面倒くさいことせにゃいかんのよ・・・
正直理解することを放棄しました。

で、サンプロコードを載せているサイトを見つけたので、丸パクリ参考にさせて頂きました。
Vista で読みから変換候補リストを取得する。 :: アレ用の何か
ここで公開されているコードをパクリって参考にして、DLLを作ってC#から呼び出すようにしたら、あらまぁあっさりと変換候補一覧が取得できました。

コールバック関数に候補をセットしている部分を、STLのvectorにセットして、別関数からリストの内容を参照できるようにしただけですが。
変換候補文字列はBSTR型なので、C#側からはIntPtrで受け取って、Marshal.PtrToStringBSTRでstringに変換するだけ。

相変わらずGoogle日本語入力だと取得できませんけどね・・・

長々と書きましたが、まとめると

Vista で読みから変換候補リストを取得する。 :: アレ用の何か
のサンプルが答えだ!(但しGoogle日本語入力、てめぇはダメだ)」

でした。

あ、いや、Google日本語入力でもどうにかする方法あると思うんだけどなぁ・・・。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

認証のために問題を解いて下さい * Time limit is exhausted. Please reload CAPTCHA.