2016-12-26 19 views
0

続きはWhat is the correct, modern way to handle arbitrary text input in a custom control on Windows? WM_CHAR? IMM? TSF?です。TranslateMessage()は無条件に0以外の値を返すので、翻訳の前か後に翻訳が行われたかをどのように伝えることができますか?

非IMEレイアウト(米国英語)、非TSF IME(Windows XP DDKの日本語FAKEIME)、TSFテキストサービス(Windows 7に付属するもの)を試した後、アクティブな入力プロセッサプロファイルがTSFテキストサービスでない場合(すなわち、TF_PROFILETYPE_KEYBOARDLAYOUT)、私はキー入力とWM_CHARのテキスト入力を処理する必要があります。

私のアーキテクチャでは、テキスト入力メッセージに変換されたため、現在のキーメッセージを無視できることを伝える方法が必要です。これが翻訳の前後に起こるかどうかは気にしません。そのような翻訳が起こるかどうかを知る必要があります。または擬似コードの用語で:

// if I can suppress WM_CHAR generation and synthesize it myself (including if the translation is just dead keys) 
case WM_KEYDOWN: 
case WM_SYSKEYDOWN: 
    if (WillTranslateMessage()) 
     InsertChar(GenerateEquivalentChar()); 
    else 
     HandleRawKeyEvent(); 
    break; 

// if I can know if a WM_CHAR was generated (or will be generated; for instance, in the case of dead keys) 
case WM_KEYDOWN: 
case WM_SYSKEYDOWN: 
    if (!DidTranslateMessage()) 
     HandleRawKeyEvent(); 
    break; 
case WM_CHAR: 
case WM_SYSCHAR: 
    InsertChar(wParam); 
    break; 

キーボードからまたは非TSF IMEのいずれかを介して、テキスト入力を処理する標準的な方法は、TranslateMessage()WM_KEYDOWN -to- WM_CHAR翻訳を行うようにすることです。しかし、問題があります:MSDNは、メッセージがWM_KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN、またはWM_SYSKEYUPである場合、戻り値は関係なく、翻訳の、ゼロでない

を言います。

つまり、翻訳が行われたかどうかを判断するために使用することはできません。

いくつかのマイケル・カプランのブログの記事を読んだ後、私は私がGetKeyboardState()から状態配列を渡し、変換を自分で行うことをToUnicode()またはToUnicodeEx()を使用することができます考え出しました。 The wine source code seems to agreeが、それは、彼らがワインに固有であるかだけでなく、実際のWindows上で実行する必要があれば、私はよく分からない2つの特殊なケースがあります。

  • VK_PACKETは - から直接WM_CHARを生成し、メッセージのLPARAM
  • VK_PROCESS - 関数ImmTranslateMessage()を呼び出します。これは、ワイン固有関数または文書化されていないimm32.dll関数のいずれかと思われます。私は本当であると言うことができません

また、ワインは何もしませんWM_KEYUPWM_SYSKEYUP;再び、私はこれがワインだけに当てはまるかどうかわかりません。

しかし、TSFを使用するプログラムでこれらのケースについても心配する必要はありますか?そしてもし私がそうしたら、それを行う "公式の"方法は何ですか?それでは、私は何をするでしょうかWM_KEYUP/WM_SYSKEYUP;それらをToUnicode()にも送信する必要がありますか? WM_CHARがあった場合は、特に私のウィンドウでWM_KEYUPをキャッチする必要がありますか?

または、私はTSFがTF_PROFILETYPE_KEYBOARDLAYOUTプロセッサの世話をすることを許可するMSDN TSFサンプルに含まれていないものを紛失していますか?私はTSFが透過的なIMEパススルーを行ったと思ったが、FAKEIMEサンプルを使った私の実験はそうでなければ...?私はFirefoxとChromiumの両方がTF_PROFILETYPE_KEYBOARDLAYOUTをチェックし、ImmGetIMEFileName()を使用してキーボードレイアウトがIMEでサポートされているかどうかを確認することもできますが、実際にこれらのケースで入力を処理するかどうかはわかりません...

私の最小バージョンは今のWindows 7

おかげです。

更新この質問のオリジナルバージョンは、関連するWM_KEYUPを知る必要があります。他のプラットフォームで同等のコードを2度目に見ると、後でTranslateMessage()の部分を除いて、これは必要ではありません。私はそれに応じて質問を調整しました。 (OS Xでは、キー入力イベントをテキスト入力システムに与えることさえできません; GTK +では、文字を挿入するキーが押されているように見えますが、リリースでは気にならず、とにかく処理されません。私が試したインプットメソッド(いくつかのことがあるかもしれません...)。)言われていることは、私が何かを見逃してしまったら、別のサブ質問を追加しました。

+0

なぜcharイベントではなく、キーup/downイベントを処理していますか? –

+0

@EricBrown私はまだ矢印キーのナビゲーションやキーボード駆動の選択などの操作を行う必要があるためです。それとも私が行方不明になっている別の方法がありますか?ちなみに、小さなフォローアップの質問で繰り返し迷惑をかけて申し訳ありません。 – andlabs

答えて

1

一般に、Windowsの内部構造を複製しようとするのは良い考えではありません。面倒で、エラーが起こりやすく、予告なく変更する可能性があります。

WM_KEYDOWNハンドラの矢印キー(および他の特定のキー)を選択してデフォルトのハンドラに渡すソースアクセス権を持っているエディットコントロールは、(最終的に)WM_CHARまたはTSF入力コールを生成します(ifあなたのコントロールはTSFをサポートしています)。

TSFハンドラが関与していない場合は、依然としてWM_CHARが必要です。ただし、いつでもWM_CHARハンドラにITextStoreACP :: InsertTextAtSelectionメソッドを呼び出させることができます。

+0

大丈夫です。私はTSFを使用しているので、サンプルのtsfpadアプリも使用します。私はどちらの場合でもなぜWM_CHARが必要なのかわかりません。ああ、扱いすぎる余分な作業ではないはずです。だから、私のカスタムエディタは、キーがテキスト入力に決して貢献しないことを知っていなければならないだろうと思いますか? (私がサポートする必要がある他のすべてのOSは、テキストを最初に処理し、残っているキーを処理するので、私はこの質問をしています。私は元の質問をしたときシャッフル。)その間にありがとう! – andlabs

+1

@andlabs他のOSのテキスト入力についてはわかりませんが、Windowsでは、WM_CHARの前に任意の数のWM_KEYDOWNを置くことができます。 (非IME言語のキーを作成するか、英語でUnicode文字をAltキーを押しながら入力することを検討してください)。矢印キーは決して構成されないため、早期に選択するのが安全です。 –

+0

右。他のOSもこれを可能にします。それはちょうどそれらにキーストロークを与えなければならない、それ以外の方法ではありません。 (入力メソッドマネージャへのプロキシオブジェクトを作成します。これは、プロセスに動的にロードされ、キーイベントハンドラの最初のステップとしてキーイベントを渡します。キーストローク、それは長い合成のちょうど始まりでもtrueを返す)私はおそらくこれをあまりにも懸命にoverthinkingしていると私はちょうど非typewriterキーが一般的に安全だと仮定する必要があります... – andlabs

関連する問題