カスタム入力方式エディター (IME) の要件
これらのガイドラインと要件は、カスタム入力方式エディター (IME) の開発に役立ちます。これにより、ユーザーは標準の QWERTY キーボードでは簡単に表現できない言語のテキストを入力できます。
IME の概要については、「入力方式エディター (IME)」を参照してください。
既定の IME
ユーザーは、任意のアクティブな IME を選択して ([設定] -> [時刻と言語] -> [言語] -> [優先する言語] -> [言語パック - オプション])、優先する言語の既定の IME にすることができます。
[言語オプション] の設定画面で、優先する言語の既定のキーボードを選択します。
重要
カスタム IME の既定のキーボードを設定するために、レジストリに直接書き込むことはお勧めしません。
互換性の要件
カスタム IME の基本的な互換性要件は次のとおりです。
IME は Windows アプリと互換性がある必要がある
Text Services Framework (TSF) を使用して IME を実装します。 以前は、入力サービスに対して入力方式マネージャー (IMM32) を使用するオプションがありました。 現在は、入力方式マネージャー (IMM32) を使用して実装された IME はシステムによってブロックされています。
アプリが起動すると、TSF によって、ユーザーが現在選択している IME の IME DLL が読み込まれます。 IME が読み込まれると、アプリと同じアプリ コンテナーの制限が適用されます。 たとえば、アプリがマニフェストでインターネット アクセスを要求していない場合、IME はインターネットにアクセスできません。 この動作により、IME がセキュリティ コントラクトに違反しないようにします。
TSF は、アプリと IME の仲介です。 TSF は入力イベントを IME に伝え、ユーザーが文字を選択した後、IME から入力文字を受け取ります。
この動作は以前のバージョンの Windows と同じですが、Windows アプリに読み込まれると、IME の機能に影響します。
IME が Windows アプリとデスクトップ アプリ間で異なる機能または UI を提供する必要がある場合は、TSF によって読み込まれる DLL が、読み込まれているアプリの種類を確認するようにしてください。 IME で ITfThreadMgrEx::GetActiveFlags メソッドを呼び出し、TF_TMF_IMMERSIVEMODE フラグをチェックします。これにより、結果に応じて、IME で異なるアプリケーション ロジックがトリガーされます。
Windows アプリでは、テーブル テキスト サービス (TTS) の IME はサポートされていません。
Note
TTS IME を生成するためのツールによっては、Windows によってマルウェアとしてマークされる IME が生成されます。
IME はシステム トレイと互換性がある必要がある
IME アイコンをホストする言語バーはありません。 代わりに、現在の入力オプションを示す入力インジケーターがシステム トレイに表示されます。 入力インジケーターには、現在実行中の IME を示す IME ブランド アイコンのみが表示されます。 また、IME をオンまたはオフにするなど、最も一般的に使用される IME モード スイッチをユーザーが実行するために、IME ブランド アイコンの左側に表示される IME モード アイコンが 1 つあります。
入力インジケーターには、互換性のある IME に対してのみ、IME ブランド アイコンとモード アイコンが表示されます。 互換性のない IME では、ブランド アイコンとモード アイコンがシステム トレイに表示されません。 代わりに、IME ブランド アイコンではなく、言語の省略形が入力インジケーターに表示されます。
IME アイコンは、スタンドアロンの .ico ファイルではなく、DLL または EXE ファイルに格納します。 IME アイコンのデザインは、次の「UI 設計ガイドライン」セクションで説明されているガイドラインに従う必要があります。
IME ブランド アイコン
入力インジケーターは、IME がシステムに登録されたときに IME によって定義されたリソース ID を使用して、IME DLL から IME ブランド アイコンを取得します。
IME モード アイコン
IME モード アイコンを表示するには、システム トレイに表示されている入力インジケーターに依存する必要がある場合があります。 この場合、IME は GUID_LBI_INPUTMODE を使用して IME モード アイコンを入力インジケーターに渡します。
IME モード アイコンをシステム トレイの入力インジケーターに渡すと、IME モード アイコンの既定のサイズは 16 x 16 ピクセルになります。 UI スケーリングは DPI に従います。
IME モード アイコンを UAC (セキュリティで保護されたデスクトップのユーザー アカウント制御) の入力インジケーターに渡すと、IME モード アイコンの既定のサイズは 20 x 20 ピクセルになります。 UAC 上の IME モード アイコンの UI スケーリングは、PPI に従います。
アプリ コンテナーで IME を使用する必要がある
IME の機能の一部は、アプリ コンテナーで影響を受けます。
- 辞書ファイル - 多くの場合、IME には、ユーザー入力を特定の文字にマップするための読み取り専用の辞書ファイルがあります。 アプリ コンテナー内からこれらのファイルにアクセスするには、IME を Program Files ディレクトリまたは Windows ディレクトリの下に配置する必要があります。 既定では、これらのディレクトリはアプリ コンテナーから読み取ることができるため、これらの場所に格納されている辞書ファイルには IME からアクセスできます。 IME で辞書ファイルを別の場所に保存する必要がある場合は、辞書ファイルのアクセス制御リスト (ACL) を明示的に操作して、アプリ コンテナーからのアクセスを許可する必要があります。
- インターネット更新 - IME でインターネットからのデータを使用して辞書を更新する必要がある場合、インターネット アクセスは常に許可されてはいないため、アプリ コンテナー内では確実に実行することができません。 代わりに、IME では、インターネットからのデータで辞書ファイルを更新する独立したデスクトップ プロセスを実行する必要があります。
- オンザフライの学習 - IME がインターネットにアクセス可能なアプリ コンテナーで実行されている場合、IME が通信できるエンドポイントに制限はありません。 この場合、IME はクラウド サーバーを使用して、オンザフライの学習サービスを提供できます。 一部の IME では、ユーザーが入力している間にユーザー入力をオンザフライでダウンロードおよびアップロードします。 アプリ コンテナーではインターネット アクセスが保証されないため、常に許可されるとは限りません。
- プロセス間での情報の共有 - IME は、異なるアプリ コンテナー内のアプリ間で、ユーザーの入力設定に関するデータを共有する必要がある場合があります。 Web サービスを使用して、アプリ間でデータを共有します。
重要
アプリ コンテナーのセキュリティ規則を回避しようとすると、IME はマルウェアとして扱われ、ブロックされる可能性があります。
IME とタッチ キーボード
IME は、候補ウィンドウの UI とその他の UI 要素がタッチ キーボードの下に描画されないようにする必要があります。 タッチ キーボードは、すべてのアプリよりも高い z オーダー バンドで表示され、IME の UI は、アクティブになっているアプリと同じ z オーダー バンドで表示されます。 その結果、タッチ キーボードが IME の UI と重複したり、IME の UI が隠れたりする場合があります。 ほとんどの場合、タッチ キーボードを考慮して、アプリのウィンドウのサイズを変更する必要があります。 アプリのサイズを変更しない場合でも、IME で InputPane API を使用すると、タッチ キーボードの位置を取得できます。 IME では、Location プロパティを照会するか、タッチ キーボードの Show イベントと Hide イベントのハンドラーを登録します。 Show イベントは、現在タッチ キーボードが表示されている場合でも、ユーザーが編集フィールドをタップするたびに発生します。 IME でこの API を使用すると、IME で候補 (または他の) UI を描画する前にタッチ キーボードで使用される画面領域を取得したり、タッチ キーボードの下に描画しないように IME の UI をリフローしたりすることができます。
優先するタッチ キーボード レイアウトの指定
IME では使用するタッチ キーボード レイアウトを指定でき、IME はタッチに最適化されたレイアウトで動作します。 この機能は、韓国語、日本語、簡体字中国語、繁体字中国語の入力言語の IME に限定されています。
タッチ キーボードでサポートされているレイアウトは 7 つあります。3 つはクラシック レイアウト、4 つはタッチ最適化レイアウトです。 クラシック レイアウトは、物理キーボードのように見え、同様に動作します。
次の 3 つのクラシック レイアウトは、繁体字中国語を異なる形式で入力するためのものです。
- 発音に基づく入力
- Changjie 入力
- Dayi 入力
クラシック レイアウトに加えて、韓国語、日本語、簡体字中国語、繁体字中国語の各入力言語に対して、タッチに最適化されたレイアウトが 1 つあります。
この機能を使用するには、IME で ITfFnGetPreferredTouchKeyboardLayout インターフェイスを実装する必要があります。これは、Text Services Framework の ITfFunctionProvider API を使用して IME によってエクスポートされます。
IME で ITfFnGetPreferredTouchKeyboardLayout インターフェイスがサポートされていない場合、IME を使用すると、タッチ キーボードによって表示される言語の既定のクラシック レイアウトが生成されます。
IME でいずれかのクラシック レイアウトを優先レイアウトとして設定する必要がある場合、ITfFnGetPreferredTouchKeyboardLayout インターフェイスおよび ITfFunctionProvider インターフェイスをサポートすること以外には、IME 側で追加の作業を行う必要はありません。 ただし、タッチに最適化されたレイアウトを操作するには、IME で追加の作業が必要です。これについては、次のセクションで説明します。
タッチに最適化されたレイアウト
韓国語、日本語、簡体字中国語、繁体字中国語の入力言語用のタッチに最適化されたキーボードでは、IME オンと IME オフの変換モードに対して、さまざまなレイアウトが表示されます。 タッチ キーボードには、IME 変換モードをオンまたはオフに設定するためのキーがありますが、エディット コントロール間でフォーカスが変更されると、キーボードの IME モードも変更される可能性があります。
日本語、簡体字中国語、繁体字中国語の入力言語のタッチに最適化されたキーボードには、候補ページ間を移動するために IME が使用する 1 つまたは複数のキーが含まれています。 日本語および簡体字中国語の場合、タッチに最適化されたレイアウトでは候補ページ キーが表示されます。 繁体字中国語の場合は、前の候補ページと次の候補ページに個別のキーがあります。
これらのキーが押されると、タッチ キーボードは SendInput 関数を呼び出して、次の Unicode プライベート使用領域文字をフォーカスされたアプリケーションに送信します。これは、IME がインターセプトして操作できます。
- 次のページ (0xF003) - 日本語と簡体字中国語のタッチ最適化キーボードで候補ページ キーが押されたとき、または繁体字中国語のタッチ最適化キーボードで次のページ キーが押されたときに送信されます。
- 前のページ (0xF004) - 日本語と簡体字中国語のタッチ最適化キーボードで候補ページ キーが Shift キーと同時に押されたとき、または繁体字中国語のタッチ最適化キーボードで前のページ キーが押されたときに送信されます。
これらの文字は、Unicode 入力として送信されます。 次の段落では、Text Services Framework の IME によって受信されるキー イベント シンク通知中に文字情報を抽出する方法について詳しく説明します。 これらの文字値は、どのヘッダー ファイルでも定義されていないため、コードで定義する必要があります。
キーボード入力を受け取るには、IME がキー イベント シンクとして登録されている必要があります。 SendInput 関数を使用して生成される Unicode 入力の場合、ITfKeyEventSink コールバック (OnKeyDown、OnKeyUp、OnTestKeyDown、OnTestKeyUp) の WPARAM パラメーターには常に仮想キー VK_PACKET が含まれるので、文字は直接識別されません。
文字にアクセスするには、次の呼び出しシーケンスを実装します。
// Keyboard state
BYTE abKbdState[256];
if (!GetKeyboardState(abKbdState))
{
return 0;
}
// Map virtual key to character code
WCHAR wch;
if (ToUnicode(VK_PACKET, 0, abKbdState, &wch, 1, 0) == 1)
{
return wch;
}
IME 検索の統合
検索コントラクトを使用してユーザーに検索機能を提供し、検索ウィンドウと統合します。
検索ウィンドウと IME の候補
検索ウィンドウは、ユーザーがすべてのアプリで検索を実行するための中央の場所です。 IME ユーザーには、Windows によって独自の検索エクスペリエンスが提供されます。これによって、互換性のある IME が Windows と統合され、効率と使いやすさが向上します。
検索と互換性のある IME を使用して入力するユーザーには、主に次の 2 つの利点があります。
- IME と検索エクスペリエンスの間のシームレスな操作。 IME 候補は、検索候補を閉じることなく、検索ボックスの下にインラインで表示されます。 ユーザーはキーボードを使用して、検索ボックス、IME 変換候補、検索候補の間をシームレスに移動できます。
- アプリケーションによって提供される関連性の高い結果と候補に迅速にアクセスできます。 より関連性の高い候補を提供するために、アプリは現在のすべての変換候補にアクセスできます。 検索候補により適切な優先順位を付けるために、変換は関連性の高い順にアプリに与えられます。 ユーザーは、発音を入力するだけで、変換せずに目的の結果を見つけて選択できます。
IME は、次の条件を満たしている場合、統合検索エクスペリエンスと互換性があります。
- Windows スタイル シェルと互換性がある。
- TSF UILess モード API を実装している。 詳細については、「UILess モードの概要」を参照してください。
- TSF 検索統合 API の ITfFnSearchCandidateProvider および ITfIntegratableCandidateListUIElement を実装している。
検索ウィンドウでアクティブ化すると、互換性のある IME が UIless モードに配置され、その UI を表示できません。 代わりに、前のスクリーンショットに示すように、Windows に変換候補が送信され、インライン候補リスト コントロールに表示されます。
また、IME は、現在の検索を実行するために使用する必要がある候補を送信します。 これらの候補は、変換候補と同じにすることも、検索用に調整することもできます。
良い検索候補は、次の条件を満たしています。
- プレフィックスの重複はありません。 たとえば、"北京大学" と "北京" は、一方がもう一方のプレフィックスなので冗長です。
- 冗長な候補はありません。 冗長な候補は、結果のフィルター処理には使用できないので、検索には役立ちません。 たとえば、"北京大学" に適合する結果は、"北京" にも適合します。
- 変換のみであり、予測候補はありません。 たとえば、ユーザーが "be" と入力した場合、IME は候補として "北京大学" ではなく "北" を返します。 通常、予測候補は限定的すぎます。
条件を満たしていない IME は、他のコントロールと同様に検索表示と互換性がありません。また、UI 統合と検索候補を利用できません。 アプリは、ユーザーが構成を完了した後にのみクエリを受け取ります。
検索コントラクトをサポートするアプリがクエリを受け取ると、クエリ イベントにはすべての既知の代替候補を含む "queryTextAlternatives" 配列が格納され、最も関連性の高い (可能性が高い) ものから最も関連性の低い (可能性が低い) ものの順にランクが付けられます。
代替候補が提供される場合、アプリは各代替候補をクエリとして扱い、任意の代替候補に一致するすべての結果を返す必要があります。 アプリはユーザーが複数のクエリを同時に発行した場合と同様に動作し、基本的に結果を提供する "または" クエリをサービスに発行する必要があります。 パフォーマンスに関する考慮事項として、多くの場合、アプリでは最も関連性の高い代替候補の 5 ~ 20 件に一致が制限されます。
UI 設計ガイドライン
すべての IME は、「Windows アプリの設計とコーディング」で説明されているユーザー エクスペリエンス ガイドラインに従う必要があります。
スティッキー ウィンドウを使用しない
IME ウィンドウは、常に表示されるのではなく、必要な場合にのみ表示される必要があります。 ユーザーが入力する必要がない場合に IME ウィンドウを表示する必要はありません。 IME ウィンドウを全画面ウィンドウにしないでください。 IME ウィンドウは互いに重ならないようにする必要があります。 ウィンドウは、Windows スタイルで設計し、UI スケーリングに従う必要があります。
IME アイコン
IME アイコンには、ブランド アイコンとモード アイコンの 2 種類があります。 すべての IME アイコンは、黒と白の色のみで設計する必要があります。 新しい IME アイコンは、システム トレイ アイコンのグリフの外観から借用されます。 このスタイルは、すべての言語でそれを使用して、相互に区別しながら外観を補完できるように作成されています。
IME アイコンのファイル形式は ICO です。 次のアイコン サイズを用意する必要があります。
- 16 x 16 ピクセル
- 20 x 20 ピクセル
- 24 x 24 ピクセル
- 32 x 32 ピクセル
- 40 x 40 ピクセル
- 48 x 48 ピクセル
アルファ チャネルを含む 32 ビット アイコンがすべての解像度で提供されていることを確認してください。
IME ブランド アイコンは、最新の書体にレンダリングされたタイポグラフィ グリフが配置された白いボックスで定義されます。 定義するグリフは、各言語チームによって選択されます。 グリフは黒です。 ボックスには、不透明度が 50% の黒い 1 ピクセルの外側のストロークが含まれています。 "新規" バージョンは、ボックスの左上にある丸い角で定義されます。
IME モード アイコンは、最新の書体の白いタイポグラフィ グリフで定義されます。これには、不透明度が 50% の黒い 1 ピクセルの外側のストロークが含まれます。
アイコン | 説明 |
---|---|
繁体字中国語 ChangeJie の IME ブランド アイコンの例。 | |
繁体字中国語 ChangeJie の IME ブランド アイコンの例。 | |
IME モード アイコンの例。 |
所有ウィンドウ
候補 UI を表示するには、IME がウィンドウを所有ウィンドウに設定して、現在実行中のアプリに表示できる必要があります。 所有するウィンドウを取得するには、ITfContextView::GetWnd メソッドを使用します。 GetWnd がエラーまたは NULLHWND を返す場合は、GetFocus 関数を呼び出します。
if (FAILED(pView->GetWnd(&parentWndHandle)) || (parentWndHandle == nullptr)) { parentWndHandle = GetFocus(); }
IME 候補ウィンドウとライト ディスミス サーフェスの操作
ポップアップ ウィンドウを閉じるモデルは、ユーザーがこのようなウィンドウを閉じるのは容易であるため、"ライト ディスミス" と呼ばれます。 IME が Windows の操作モデルで適切に機能するには、IME ウィンドウがライト ディスミス モデルに属している必要があります。
ライト ディスミス モデルに属するには、NotifyWinEvent 関数または同様の関数を使用して、IME で 3 つの新しい Windows イベントを発生させる必要があります。 これらの新しいイベントは次のとおりです。
- EVENT_OBJECT_IME_SHOW - IME が表示された時点でこのイベントを発生させます。
- EVENT_OBJECT_IME_HIDE - IME が非表示になった時点でこのイベントを発生させます。
- EVENT_OBJECT_IME_CHANGE - IME が移動するか、サイズが変更された時点でこのイベントを発生させます。
互換性の宣言
ITfCategoryMgr::RegisterCategory を使用して、IME のカテゴリ GUID_TFCAT_TIPCAP_IMMERSIVESUPPORT を登録することで、IME の互換性を宣言します。
既定の IME モードをオンに設定する
より優れた UX を IME に提供します。
デスクトップ アプリケーションの DPI スケーリングのサポート
拡張 DPI スケーリングのサポートにより、各デスクトップ プロセスの宣言された DPI 認識レベルに対してクエリを実行して、UI をスケーリングする必要があるかどうかを判断できます。 マルチモニター シナリオでは、各モニターで異なる DPI 設定に合わせて UI を適切にスケーリングできます。
IME は各アプリケーション プロセスのコンテキストで実行されます。このため、IME の DPI 認識レベルを宣言する必要はありません。 これにより、IME は現在のプロセスの DPI 認識レベルで実行されます。
すべての IME UI 要素が、実行しているプロセスの UI 要素とスケーリング パリティを持つには、異なる DPI 値に適切に応答する必要があります。
Note
新しいデスクトップ アプリケーションとのパリティを確保するために、IME はモニターごとの DPI 認識をサポートする必要がありますが、認識のレベル自体を宣言する必要はありません。 システムによって、各シナリオで適切なスケーリング要件が決定されます。
デスクトップ アプリケーションの DPI スケーリング サポート要件の詳細については、「高 DPI」を参照してください。
IME のインストール
Microsoft Visual Studio を使用して IME をビルドする場合は、Flexera Software の InstallShield など、サードパーティのインストーラーを使用して IME のインストール エクスペリエンスを作成します。
次の手順では、InstallShield を使用して、IME DLL のセットアップ プロジェクトを作成する方法を説明します。
- Visual Studio をインストールします。
- Visual Studio を起動します。
- [ファイル] メニューの [新規作成] をポイントし、[プロジェクト] を選択します。 [新しいプロジェクト] ダイアログ ボックスが開きます。
- 左側のウィンドウで、[テンプレート] > [その他のプロジェクトの種類] > [セットアップと配置] の順に移動し、[InstallShield Limited Edition の有効化] をクリックして、[OK] をクリックします。 インストール手順に従います。
- Visual Studio を再起動します。
- IME ソリューション (.sln) ファイルを開きます。
- ソリューション エクスプローラーで、ソリューションを右クリックし、[追加] をポイントして、[新しいプロジェクト] を選択します。 [新しいプロジェクトの追加] ダイアログが開きます。
- 左側のツリー ビュー コントロールで、[テンプレート] > [その他のプロジェクトの種類] > [InstallShield Limited Edition] の順に移動します。
- 中央のウィンドウで [InstallShield Limited Edition プロジェクト] をクリックします。
- [名前] テキスト ボックスに「SetupIME」と入力し、[OK] をクリックします。
- [プロジェクト アシスタント] ダイアログで、[アプリケーション情報] をクリックします。
- 会社名とその他のフィールドを入力します。
- [アプリケーション ファイル] をクリックします。
- 左側のウィンドウで、[INSTALLDIR] フォルダーを右クリックし、[新しいフォルダー] を選択します。 このフォルダーに「Plugins」という名前を付けます。
- [ファイルの追加] をクリックします。 IME DLL に移動し、[Plugins] フォルダーに追加します。 IME 辞書に対してこの手順を繰り返します。
- その IME DLL を右クリックし、[プロパティ] を選びます。 [プロパティ] ダイアログが開きます。
- [プロパティ] ダイアログの [COM & NET 設定] タブをクリックします。
- [登録の種類] で [自己登録] を選択し、[OK] をクリックします。
- ソリューションをビルドします。 IME DLL がビルドされ、InstallShield によって、ユーザーが Windows に IME をインストールできるようにする setup.exe ファイルが作成されます。
独自のインストール エクスペリエンスを作成するには、ITfInputProcessorProfileMgr::RegisterProfile メソッドを呼び出して、インストール時に IME を登録します。 レジストリ エントリを直接記述しないでください。
インストール後すぐに IME を使用する必要がある場合は、InstallLayoutOrTip を呼び出し、psz パラメーターに次の形式を使用して、ユーザーが有効にした入力方式に IME を追加します。
<LangID 1>:{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
IME のアクセシビリティ
IME がアクセシビリティ要件に準拠し、ナレーターを操作できるようにするには、次の規則を実装します。 候補リストをアクセス可能にするには、IME がこの規則に従う必要があります。
- 候補リストには、変換候補の一覧の "IME_Candidate_Window" または予測候補の一覧の "IME_Prediction_Window" に等しい UIA_AutomationIdPropertyId が設定されている必要があります。
- 候補リストが表示された場合および消えた場合には、それぞれ型 UIA_MenuOpenedEventId と UIA_MenuClosedEventId のイベントが生成されます。
- 現在選択されている候補が変更されると、候補リストによって、UIA_SelectionItem_ElementSelectedEventId が発生します。 選択した要素には、TRUE に等しい UIA_SelectionItemIsSelectedPropertyId プロパティが設定されている必要があります。
- 候補リストの各項目の UIA_NamePropertyId は、候補の名前である必要があります。 必要に応じて、UIA_HelpTextPropertyId を通じて候補を明確にするための追加情報を提供できます。
関連トピック
Windows developer