TSF を使う (1) - Windows Input Method の歴史

前回もお伝えしたように,そもそも TSF の話を急いでする必要はなくなりました.

  • Windows Vista で当初私が懸念していた Full IME-aware applications の UI ウィンドウ制御に関する互換性問題は,DirectX SDK のサンプルに存在していたバグが原因であり,Vista 開発陣は IMM32 の互換機能をきちんと実装していること
  • 現在いくつかの MMORPG 等で発生している Windows Vista での日本語入力に関する問題は,もし上記 DirectX SDK のバグと同じコードが使用されているのであれば,非常に簡単に修正可能であること

今後 Legacy IM が TSF で置き換えていく流れが確実になっているとはいえ,これで当面急いで TSF に乗り換える必要は無いと思います.
そういうわけでしばらく時間をおいてもいいのですが,いったんまとめかけていた資料を後でまた掘り起こすのが大変なので,ここで軽く書ききってしまうことにしました.全く持って需要がなさそうな記事ですが,しばらくおつきあいくださいませ.
まずは,Windows の Input Method の歴史から見ていきましょう.



ちょうどいい具合に Windows の Text Input の歴史が整理してある資料があります.
それが今や黒歴史の祭典ともいうべき PDC 03 の PPT というのは何とも皮肉な話ですが,この PPT の 8 枚目をご覧ください.
http://www.gotdotnet.com/team/PDC/4013/CLI351.ppt
ただしこの図ではテクノロジのリリース時期と対応 OS の関係が分かりにくいので,別の図を用意してみました.

いくつか注目すべき点を挙げておきましょう.

当初 IMM32 は東アジア版にのみ実装されていた

実は,英語圏を始めとした多くの地域で販売されていた Windows 9x や Windows NT 4.0 には IMM32 が搭載されていません.IMM32 API がどの国のエディションでも使用可能になったのは,Windows 2000 以降のことです*1
ただし,インターネットの普及で東アジア圏のサイトを利用する機会はこれら IMM32 非搭載の OS 環境にとっても無視できなくなりました.たとえばハワイのホテルの PC で日本への Web メールが書けないと困るというわけです.そういった流れの中で,繋ぎ技術として,Microsoft は Internet Explorer 4.0 と同時期に Global IME と呼ばれる特殊な IME をリリースしています.IMM32 の機能を担当するのは Active Input Method Manager (AIMM) と呼ばれる仕組みで,IMM32 の仕組みをほぼそのまま COM オブジェクトに移植したものになっています.
DirectX のようにリリース済みの OS に機能を付け足すかのような AIMM ですが,純粋な IMM32 対応環境のようにメッセージループ以前に仮想キーコードを得るためには何らかのトリックが必要になります.AIMM のチュートリアルを読むと,IActiveIMMMessagePumpOwner::Start というメソッドを事前に呼び出す必要があることから,恐らくメッセージフックを使用して WM_KEYDOWN / WM_KEYUP をフックしているものと思われます.
また IMM32 は WM_IME_XXXX への応答として DefWindowProc が呼び出されるか否か,呼び出された場合の lParam / wParam はどうなっているかを利用していますので,DefWindowProc についても対応を講じねばなりません.これについては,AIMM を使用するアプリケーションは,標準の DefWindowProc の代わりに,IActiveIMMApp::OnDefWindowProc Method を呼び出すべし,となっています.
このように,AIMM の利用にはソースコードへの修正が必要で,しかも標準のメッセージポンプに寄生するという特殊な対応が求められるものでした.こうしてみると,IMM32 のように,IME を意識しないアプリケーションについても変換結果だけは受け取れるという仕組みがいかに楽かがよく分かります.
もっとも,Microsoft 自身,AIMM が Windows 2000 までの限定的なもので,IMM32 を置き換えるものではないと当初から明言していました.とはいえ,IMM32 の後継たる TSF が,AIMM のように COM ベースで,かつ同様のメッセージループへの寄生を行う点から考えると,AIMM は TSF 0.5 とでも言うべき存在なのかもしれません.

TSF 1.0 の登場

Text Services Framework (TSF) は、IMM32 ラッパーに過ぎない AIMM とは異なり,いちから作られたとおぼしき次世代 (というか現世代) 汎用テキスト入力フレームワークです.開発コードネームは Cicero で,ちらほらと Cicero の名前がついたウィンドウや関連技術を目にします.
TSF はキーボード入力以外にも音声認識や手書き入力といった様々な入力方式に対応しており,非漢字圏にとっても重要な仕組みになっています.本社直轄で開発が行われているのは,そのような理由もあってのことでしょう.
TSF 1.0 は,Office XP と一緒に出荷されたものと記憶しています.AIMM 同様に COM ベースのフレームワークである TSF は,ランタイムライブラリをインストールすることで,既に出荷済みの Windows 9x / Windows NT 4.0 でも使用することができました.→(TSF 1.0 の再配布ファイル)
TSF を利用するには AIMM 同様にアプリケーション側の対応が必要だったわけですが,逆に言えば TSF に対応したアプリケーションは,ランタイムライブラリをインストールすることで,英語版の Windows 95 でも日本語版の Windows Vista でも同様に日本語入力が可能ということになります.
Windows XP 以降の Windows には標準で TSF がインストールされています (Windows Me は未調査).ただし互換性設定等でシステム単位またはアプリケーション単位で TSF が無効化されている場合もあり,これらの OS でも TSF が確実に利用できるとは限りません.
従来 IME と呼ばれていたものは,TSF では Text Input Processor (TIP) と呼ばれます.当然ながら TIP の実装も COM ベースで行います.TSF に対応した TIP は,IME 2002, IME 2003, Natural Input 2002, Natural Input 2003, SKKIME, Anthy for Windows (未公開) などがあります.
また TSF に対応したアプリケーションとしては,Microsoft Word や Wordpad,Internet Explorer などがあります.この他,ツールキットとして見た WPF は TSF に対応しているので,WPF アプリケーションも TSF 対応ということになります.既存のアプリケーションを修正することなく TIP で文字入力を可能にする仕組みとして後述の CUAS が存在します.
TSF 1.0 では,IMM32 のすべての機能を代替することができませんでした.変換候補ウィンドウの独自描画や候補リストの取得といった,フロントエンドの置き換えに機能が TSF 1.0 では使用できません.

CUAS

Cicero Unaware Application Support.
Microsoft Windows XP Service Pack 1 で導入された「詳細なテキスト サービスのサポートをプログラムのすべてに拡張する」のことです.
CUAS は,TSF ベースの TIP と,IMM32 ベースのアプリケーションの間に入って,それぞれを接続します.これには,アプリケーションからの IMM32 API 呼び出しを適切な TSF API 呼び出しに変換することや,本来 TSF 対応アプリケーションが備えるべきテキストストアを代わりに実装し,アプリケーションの代わりにプリエディットの更新管理や描画を行うこと,TIP からの応答を適切な IMM32 メッセージに変換することなど,様々な機能が含まれています.
なお TSF は,キー入力以外の Win32 のメッセージ機構にほとんど依存していないため,TSF のみでテキスト入力を行う場合は WM_IME 系のメッセージが生成されません.これはつまり,メッセージフックで WM_IME 系をすべてモニタリングしていても,TSF で行われた漢字変換は検知できないということを意味します.
ただし CUAS 有効時であれば,たとえ本来の TSF を利用した文字入力が行われている場合であっても,WM_IME 系のメッセージ自体は生成されウィンドウに送られるようになります.TSF TIP の利用が本格化する Windows Vista では,常に CUAS が働きますので,Vista でも TSF 以前のように WM_IME 系のメッセージが飛んでくると考えれば良いでしょう.
CUAS は,Windows XP SP 1 以降にリリースされた OS に搭載されていますが,TSF 1.0 で行われたような古い OS へのバックポートはありません.
当初,XP SP1 で CUAS はデフォルト Off のままリリースされました.CUAS は不具合が多かったことでも有名で,KB にもその痕跡を見ることができます.

一方で,Tablet PC ではデフォルトで On のまま出荷されました.これは手書き認識機能と音声認識機能に TSF を使用するためです.
また,Windows XP SP1 から Windows Server 2003 までの CUAS は,TSF 1.0 の機能不足から,IMM32 のフロントエンド差し替えを完全にエミュレートすることはできませんでした.混乱を避けるために,IMM32 のフロントエンド差し替えを行うアプリケーションは,ImmDisableTextFrameService API を呼び出してアプリケーション内での CUAS の使用を無効化しておくと良いでしょう*2
最近では,MSIME 2007 の予測変換機能を Microsoft Word 以外で使用するための TIPS として,CUAS 有効化を紹介している記事を目にします.

InputScope

InputScope は,手書き文字入力や音声認識の精度向上のために,テキスト入力エリアごとに属性や予想される単語集合を設定する API で,Tablet PC のリリースに合わせて整備されました.Windows XP SP2 以降で使用可能です.
InputScope Enumeration」を見ると,漢字変換にも有効そうな属性が並んでいますが,私が MSIME について調べた範囲内では,IS_KATAKANA_FULLWIDTH 設定時に文字設定がカタカナモードになる等の効果はあるものの,設定された文字属性以外が入力されるのを防ぐといった効果は特になさそうでした.また,漢字変換にこれらの設定を反映されるといったことも今のところなされていないように思えます.
一方で,英単語の Phrase List を設定したテキストエリアに,英語設定の Tablet PC Input Panel (ややこしいことにこれも TIP と呼ばれます) で入力した場合には,InputScope の効果を如実に体験することができます.残念ながら現時点で Phrase List に日本語を設定できないようですが*3Windows Vista では多くのエディションで TIP が標準搭載されていますから,皆さん是非一度試されてみてはいかがでしょうか? スタートメニューから「Tablet」で検索するとすぐに見つかるはずです.


Phrase List として,「Word」「Excel」「PowerPoint」という 3 つを与えたテキストボックスをフォーカスし,適当に落書きしてみたときの様子.手書き認識エンジンは,与えられた Phrase の中から候補を選ぶので,何を書いてもどれかが提示される.

Windows Vista と TSF のひとまずの完成

さて,Windows Vista では TSF に改良が加えられ,ついに念願の UILess Mode がサポートされました.それに伴い,CUAS の IMM32 エミュレーションもより完璧に近づき,IMM32 から TSF への移行がついに本格化する段階に入ったことかと思います.シェアという意味ではもう一つの雄,ATOK の TSF への移行がまだですが,状況を考えるに今後数年以内には TSF サポートが打ち出されるのではないかと予想しています.
TSF 自体はまあ COM に慣れない世代には遅れてきた亡霊に見えるかもしれませんが,IMM32 時代に比べて興味深い仕組みを多数備えており,登場後 5 年以上を経てやっとそのポテンシャルが生かされる時が来たかという感じです.これで Windows でも DDK といった足枷なしに気軽に IMEngine を発表してみたり, SCIM / uim とのブリッジの開発などが進むことを期待しています.
なお,「Windows Vista デベロッパー センター - 開発者向け互換性情報」で公開されている「アプリケーション互換性情報パック」の中に,CUAS による IMM32 エミュレーションに関する具体的な資料として「IMM32互換性情報.doc」というファイルが含まれています.CUAS に関する数少ない資料ですので,是非確保されておくことをおすすめします.

余談その 1 - 誰がプリエディットを描画しているか?

普段見ているようで見えていない日本語入力の世界.プリエディット (IME 用語では Composition String?) を IME が描画する場合と,アプリケーション自身で描画する場合があるのをご存じですか?
例えば次の図.

EmEditor 上に ATOK 2007 で入力しているところですが,変換中の文字列 (プリエディット) は実は ATOK 2007 自身によって管理されるウィンドウ (IME 用語では Composition Window) の上に描画されています.(XIM 用語でいうところの Over the Spot 方式)
IMM32 Legacy IM は,もちろんバックエンド型でも使用できるのですが,IME-unaware application のように何もしなければ,つまりデフォルトでは,アプリケーションはフロントエンド*4で文字変換を受けたかのように振る舞うことができます.ATOK にせよ MSIME にせよ,このときのためのデフォルトの Over-the-Spot 型 Composition Window と,Candidte Window を最初から内蔵しており,アプリケーションはコンポジション完了までの処理を IMM32 と IME に丸投げすることができます.上図のように Over the Spot でプリエディットが表示されるアプリケーションのほとんどは,このような IME-unaware application と考えられます.
一方,Microsoft Office 製品や,Internet ExplorerMozilla 系ブラウザなどは,プリエディットをアプリケーション側で描画しており,On-the-Spot 入力を可能にしています.試しに,入力済みの文字列の途中に Caret を合わせ,何か入力してみてください.On-the-Spot 入力では,プリエディットの伸張に合わせて Caret 右側の確定済み文字列も移動するかと思いますが,Over-the-Spot 型の場合は入力済み文字列に重なるように入力されているかと思います.以前紹介した,『Installing and Using Input Method Editors』の後半,『Japanese_IME』の部分を見ると,その重なりっぷりがよく分かります.
印象論でいえば,Windows で Legacy IM 使用時の On-the-Spot 入力に対応したアプリケーションというのは,意外と多くありません.日本語対応とうたうアプリケーションでも,その多くは IME-unaware application であり,普段の我々はそれほど違和感なく Over-the-Spot 入力を行っているはずです.
一方で TSF のネイティブアプリケーションは,ほぼ確実に On-the-Spot 入力を行います.これはそもそも TSF では,コンポジションが On-the-Spot にテキストストアに流し込まれるため,自然な描画スタイルとして On-the-Spot で描画することになるのでしょう.もちろん,アプリケーションがそのように実装すれば,Over-the-Spot 方式を行うことも可能です.TSF では,プリエディットの描画がアプリケーション側の責任であるということしか決まっていません.
さて,アーキテクチャ上 On-the-Spot が自然な TSF の TIP と,フロントエンド型に近い Over-the-Spot 型の従来型 IME-unaware application を CUAS でくっつけるとどうなるでしょうか? 答えはやはり Over-the-Spot 型でプリエディットが描画されます.このときのプリエディット描画ウィンドウは,CUAS が管理しています.
Windows 以外のプラットフォームでは,GTK+ や QT といった GUI ツールキットに IM 周りの処理を任せることができるため,実のところ近年の On-the-Spot 入力の普及率は Windows より上を行っているように思います.その意味では Windows の GUI ツールキットと言えなくもない Edit Control が,IM サポートをそれほど持っていないというのは興味深いところです*5.とはいえ,MSHTMLWPF で描画されるアプリケーションの増加とともに,PC 版の Windows でも On-the-Spot 入力が使用される場面は今後増えてくることでしょう.

余談その 2 - テキストストアを活用した変換候補の選択

TSF ではテキストストアと呼ばれる仕組みでテキストサービス (TIP などの入力サービス) がアプリケーション中のテキストデータにアクセスできるようにしています.
この仕組みの応用として誰でも考えつきそうなのが,入力箇所の前後のテキストを変換候補の評価材料に使用するというものです.当然のごとくこれは実装されているので,実際に実験してみましょう.
TSF に対応したアプリケーション,例えば Microsoft Word や Wordpad で,「危機」という単語を書いたファイルを開いて見てください.公正を期すためには,「危機」の入力は,コピーアンドペーストなど漢字変換を使用しない方法で入力した方が良いでしょう.
次にファイルを開き,「危機」の直後に caret を移動し,「いっぱつ」と入力して変換してみてください.MSIME ならば,おそらく「一髪」を変換候補として選ぶはずです.テキストストアを通じて caret 直前に「危機」という文字があることを MSIME は知っています.そのため,何もない箇所での変換候補第一位である「一発」ではなく,「危機一髪」が期待されている確率が高いと判断して「一髪」を選んだと考えられます.この機能,実は 5 年前の MSIME 2002 で既に実現されています.


左は TSF ネイティブ対応した Wordpad,右は TSF 未対応で CUAS 制御下の EmEditor 6.TSF に対応している場合としていない場合で変換結果が異なる.

残念ながら TSF に対応していない ATOK 2007 で実験すると,いずれの場合も候補として「一発」を提示しますが,それも ATOK が TSF に対応し,同じ条件に立つまでの話でしょう.TSF への対応によって,定評のある ATOK の漢字変換の精度がより向上するものと期待しています*6
(2011 年 2 月 13 日追記: IMM32 ベースの ATOK でも,設定の「入力・変換」→「変換補助」→「カーソル位置前後の文章を参照して変換する」を有効にすると,IMM32 の IMR_DOCUMENTFEED を利用した前後変換は可能です)
なお,このテキストストアという仕組みを自然に応用したのが,以前の Microsoft Office に付属していた Natural Input でした.Office に付属させるにしては明らかに従来の仕組みと違いすぎるという点では強く同意しますが,かといって完全に葬ってしまうのももったいない技術だったと思います.提供の仕方を間違えなければ,一定のファンは確保できたかもしれません.
(追記)なお,IMM32 ベースでも前後の文字列を変換に利用することは可能です.Word などはもちろんのこと,近年では 秀丸が対応した例 などがあります.



次回は Windows SDK に付属する TSF のサンプルの紹介と,Thread Manager の使い方について.

*1:もっとも,対応する言語の追加コンポーネントをインストールする必要があります

*2:CUAS を無効化できない Vista では,ImmDisableTextFrameService は無視されますが,IMM32 エミュレーションが向上しているため問題はおきにくくなっています

*3:[http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1133125&SiteID=1:title=Tablet PC Input Panel fails to recognize any writing after calling SetInputScopes API]

*4:フロントエンド,バックエンドについては『[http://kodou.net/unixuser/200405/part1.html:title=日本語入力に関する基礎知識]』等を参照のこと

*5:Windows CE では,『[http://msdn2.microsoft.com/en-us/library/aa913852.aspx:title=Japanese Edit Control]』 の Level 3 モードでプリエディットを Edit Control が描画してくれるようですね

*6:ちなみに私は TSF の実験をするとき以外は ATOK を使用しています