Помещение IME в поле пользовательского текста, полученном из Управления

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

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

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

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

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

Так, какие-либо идеи?

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

8
задан Vincent McNabb 20 July 2010 в 05:12
поделиться

1 ответ

Хорошо, похоже, что на 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_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 в char.

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

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

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

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


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

10
ответ дан 5 December 2019 в 17:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: