とある都合でWinRTからIMEの状態を読み出したい。具体的には、IMEがいま変換中であるのかどうかが知りたい。という状況に遭遇しました。
なんかいろいろ調べてみると、得られた回答は次の通り。
それC++でできるよ!
たかだかIMEが変換中かどうかを調べるのにC++でCOMを叩かないとダメだそうです。これだからWinRTは
実装編
C++叩かないといけないのは前述の通り。使うものは、ITfThreadMgr2インターフェースからスタートして、以下のインターフェースにアクセスします。
IEnumTfDocumentMgrsITfDocumentMgrIEnumTfContextsITfContextITfContextOwnerCompositionServicesIEnumITfCompositionViewITfCompositionView
すでにこのあたりで力尽きそうです。
さて、普通のSDKプログラミングではTF_GetThreadMgrという便利なのがあって、スレッドマネージャがなかったら作る。とかしてくれますが、残念ながらWinRTからは叩けません。そもそもTF_GetThreadMgrで取得出来るITfThreadMgrインターフェースはWinRTからは使用できず、使えるのはITfThreadMgr2です。2がついてる別物。とりあえず試したところ、何も考えずにとりあえずCoCreateInstanceして良さそうだったのでそのまま叩いています。
あとは、このインターフェースから上述のインターフェースを取得したりしていくと、最終的にIEnumITfCompositionViewインターフェースが取得できます。このインターフェースで列挙された、ITfCompositionViewが1以上なら、IMEが変換中。ということがわかるわけです。
正直、あーめんどくさ。って思いましたね。IMEの状態ぐらい.NETから叩かせてほしい。WinRTはなにかあるとすぐに「それC++でできるよ!」っていうところがめんどくさい。
いちおうできあがったものをGithubに置いておきました。エラー処理全然してないので実際に使うときはエラー処理を入れるなどして使ってください。