10

C#.net3.5で独自の単一行テキストボックスコントロールを作成しました

自分の選択コード、スクロール、コピー/貼り付けなどを含めて、これを完全にゼロから作成しました。左から右のテキストを選択することもできますが、これまで使用したことはありません...

私が抱えている問題は、IME(入力方式エディター)の統合にあります。IMEはある程度機能しますが、いくつか問題があります。そのうちの1つをここにリストします。

通常、TextBoxを使用すると、IME構造はTextBox内にレンダリングされます。ただし、私のコントロールでは、IMEは画面の右下に表示されます。SharpDevelopで使用されているものを含む他のカスタムコントロールを見てみました。ただし、これには同じ問題がありました。中国語、日本語、または韓国語で入力すると、画面の右下でIME処理が実行されました。

自分のテキストボックスでこれを実行する方法についていくつかのポインタが必要です。IME用のWindowsAPIを調べましたが、関数が非常に多く、どこから始めればよいかわかりません。

それで、何かアイデアはありますか?

コードサンプルがC++(マネージド/アンマネージド)またはVB.netにある場合は問題ありません。簡単に移動できます。

4

1 に答える 1

11

OK、StackOverflowのIMEエキスパートはあまりいないようです...または誰も興味がありません。

とにかく、私はそれを理解しました。

基本的に、次のWindowsメッセージをトラップする必要があります。

WM_INPUTLANGCHANGE = 0x51
WM_KEYUP = 0x101
WM_CHAR = 0x102
WM_CONVERTREQUESTEX = 0x108
WM_IME_STARTCOMPOSITION = 0x10D
WM_IME_ENDCOMPOSITION = 0x10E
WM_IME_COMPOSITION = 0x10F
WM_IME_SETCONTEXT = 0x281
WM_IME_NOTIFY = 0x282
WM_IME_CONTROL = 0x283
WM_IME_COMPOSITIONFULL = 0x284
WM_IME_SELECT = 0x285
WM_IME_CHAR = 0x286
WM_IME_REQUEST = 0x0288
WM_IME_KEYDOWN = 0x290
WM_IME_KEYUP = 0x291

韓国語の文字を合成している途中でクリックしても、合成メッセージは表示されませんが、それでもテキストボックスにその文字を追加する必要があるためですWM_KEYUPWM_CHARこれは奇妙な振る舞いです、それはバグなのだろうかと思います。

それが起こると、韓国人、中国人、日本人の間で異なる行動があります。

韓国語は本当に簡単なものです(とにかくそれを使用する方法がわからないので、漢字変換についてはわかりません)。

基本的に、すべての言語で、を取得するたびに、この質問への回答で説明したように、Imm32.dllWM_IME_COMPOSITIONを呼び出す必要があります。次に、これを進行中のコンポジションとして表示しますが、保存したテキストには追加しません。ImmGetCompositionString

文字列が合成されると、WindowsからのメッセージはIMEごとに異なります。毎回、WM_IME_COMPOSITIONメッセージからそれを得ることができます。

韓国語でLParamは、単純にGCS_RESULTSTRWParam入力された文字になります。これをキャストするだけです。char

日本語では「LParam」になりますGCS_RESULTREADSTR | GCS_RESULTREADCLAUSE | GCS_RESULTSTR0 | GCS_RESULTCLAUSE。前のWM_IME_COMPOSITIONメッセージから保存した結果を使用する必要がImmGetCompositionStringあります。これは、現時点では空の文字列になるためです。

中国語では、LParamになりますGCS_RESULTREADCLAUSE | GCS_RESULTSTR0 | GCS_RESULTCLAUSEImmGetCompositionString以前に保存されたものが空の場合を除いて、日本語と同じです。その場合WParam、charにキャストする必要があります。

3つのケースすべてで、表示されている進行中のコンプがクリアされていることを確認する必要があります。

を受け取ったらWM_IME_STARTCOMPOSITION、合成フラグを設定します(そして、進行中の合成文字列を表示します)

受信した場合はWM_IME_ENDCOMPOSITION、そのフラグをクリアします(そして、進行中の合成文字列をクリアします)。

時々受信しないWM_IME_ENDCOMPOSITIONので、受信時にフラグをクリアしWM_CHARます。


全体として、それは非常に興味深い学習体験であり、まだ進行中ですが、IMEはついに私のコントロールで使用できるようになりました!私はそれを成し遂げるために午前1時まで仕事にとどまりました。

于 2010-07-21T01:43:02.167 に答える