Помещение IME в пользовательское текстовое поле, полученное из Control - PullRequest
7 голосов
/ 20 июля 2010

Я создал свой собственный однострочный текстовый элемент управления в C # .net 3.5

Я написал это полностью с нуля, включая мой собственный код выбора, прокрутку, копирование / вставку и т. Д. Он даже может выбратьтекст слева направо, не то, чтобы я когда-либо использовал это ...

Проблема, с которой я столкнулся, заключается в интеграции IME (редактор метода ввода).IME работает в определенной степени, но у меня есть несколько проблем.Я просто перечислю один из них здесь.

Обычно, используя TextBox, конструкция IME отображается внутри TextBox.Однако в моем элементе управления IME отображается в правом нижнем углу экрана.Я попытался посмотреть на другие пользовательские элементы управления, включая тот, который использовался в SharpDevelop.Однако с этим была та же проблема.При вводе текста на китайском, японском или корейском языке в IME выполнялось что-то в правом нижнем углу экрана.

Мне нужно несколько указателей о том, как это сделать, в моем собственном текстовом поле, и я посмотрелв Windows API для IME, но функций так много, и я понятия не имею, с чего начать.

Итак, есть идеи?

Хорошо, если какие-либо примеры кода есть в C ++ (управляемый / неуправляемый) или VB.net.Я могу переместить это достаточно легко.

1 Ответ

10 голосов
/ 21 июля 2010

ОК, похоже, что не так много экспертов по IME в StackOverflow ... или никто не заинтересован.

Во всяком случае, я понял это.

По сути, я должен перехватить следующие сообщения 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_KEYUP и WM_CHAR, потому что, если я нажимаю где-нибудь в середине компоновки корейского символа, я не получаю составного сообщения, но тем не менее мне нужно добавить этот символ в мое текстовое поле. Это странное поведение, интересно, если это ошибка.

Как только это произойдет, между корейским, китайским и японским языками будет другое поведение.

Корейский язык действительно прост (хотя я не уверен насчет конвертации ханджи, потому что я все равно не знаю, как его использовать).

По сути, для всех языков, когда я получаю WM_IME_COMPOSITION, я должен вызывать ImmGetCompositionString в Imm32.dll, как я описал в ответе на этот вопрос . Затем я отображаю это как композицию в процессе, но не добавляю ее в свой сохраненный текст.

Когда строка составлена, сообщение от Windows отличается для каждого IME. Каждый раз я могу получить его из сообщения WM_IME_COMPOSITION.

В корейском LParam будет просто GCS_RESULTSTR, а WParam будет введенным символом, который я могу просто привести к char

В японском языке "LParam" будет GCS_RESULTREADSTR | GCS_RESULTREADCLAUSE | GCS_RESULTSTR0 | GCS_RESULTCLAUSE. Я должен использовать результат ImmGetCompositionString, который я сохранил из предыдущего сообщения WM_IME_COMPOSITION, потому что в это время это будет пустая строка.

На китайском LParam будет GCS_RESULTREADCLAUSE | GCS_RESULTSTR0 | GCS_RESULTCLAUSE. Это то же самое, что и японский, за исключением случаев, когда ранее сохраненное ImmGetCompositionString пусто, и в этом случае мне нужно привести WParam к символу.

Во всех трех случаях я должен убедиться, что мой отображаемый комп в процессе очищается.

Если я получаю WM_IME_STARTCOMPOSITION, я устанавливаю флаг композитинга (и отображаю строку композитинга в процессе)

Если я получаю WM_IME_ENDCOMPOSITION, я сбрасываю этот флаг (и очищаю текущую строку компоновки).

Иногда я не получаю WM_IME_ENDCOMPOSITION, поэтому я очищаю свой флаг при получении WM_CHAR.


В целом, это был очень интересный опыт обучения, который еще продолжается - но IME теперь можно использовать под моим контролем, наконец-то! Я остался на работе до 1 часа ночи, чтобы сделать это.

...