суббота, 20 ноября 2010 г.

Что сломало сообщения о языке ввода?

Это перевод What broke the input language messages?. Автор: Майкл Каплан.

Вчера, когда я говорил о роли сообщений, я сболтнул небольшой кусочек в конце:
Теперь нужно сказать, что этот процесс перестал был истиной в 100% случаев в Windows XP и выше; это так запланировано по дизайну, но, похоже, не указано ни в какой документации. Я объясню что сломало модель и почему (а также, как всё починить, чтобы работало!) завтра...
Не очень хорошо дразнить читателей, поэтому я объясню, что изменилось в XP и когда...

Вообще-то, произошли две вещи, обе из которых повлияли на составную часть Text Services Framework (TSF), известную как Text Services (определённых в словаре как:
Тип приложения, который позволяет вводить текст с помощью речи, многоязычной клавиатуры или устройства рукописного ввода. Text service также добавляет поддержку утилит редактирования текста вроде проверки грамматики.
Что изменилось? Поведение языковой панели (Language Bar), которая стала полностью программируемым COM-объектом, который документирован в MSDN здесь.

Конкретно, были сделаны такие изменения:
  1. Сообщение WM_INPUTLANGCHANGEREQUEST не отправляется, когда текущий язык ввода меняется на TSF Text Service;
  2. Если TSF Text Service был при этом активен, то не рассылается и сообщение WM_INPUTLANGCHANGE.
Несколько лет назад человек, ответственный за TSF на стороне приложений, сказал мне, что причиной для этого изменения было то, что многие приложения блокировали клавиатуру (не передавая сообщения ввода), что ломало поддержку всех новых текстовых служб, даже хотя пользователь явно указывал использовать их везде:


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

Сегодня многие из редакторов методов ввода (IME - Input Method Editor) были преобразованы в текстовые службы TSF. И, конечно же, кто угодно может теперь написать свой вариант (тут можно найти ссылки на примеры). В Vista в TSF Text Services было сконвертировано ещё несколько IME, а также как минимум два языка, которым нужен был метод ввода сложнее, чем обычная клавиатура, но проще, чем полноценный IME.

В итоге? Теперь вы не можете опираться на эти два оконных сообщения, потому что всё больше и больше вещей их не используют...

В качестве замены этим сообщениям, которая будет работать как для обычных клавиатур, так и для текстовых служб TSF, является интерфейс ITfLanguageProfileNotifySink и два его метода:
  • OnLanguageChange - вызывается перед сменой языкового профиля.
  • OnLanguageChanged - вызывается после смены языкового профиля.
Хотя первый метод возвращает только LANGID, а второй вообще ничего (старые сообщения возвращали HKL, а HKL в мире TSF не нужны), но если вам нужно узнать, что за изменение стоит за этим LANGID, вы можете использовать интерфейс ITfInputProcessorProfiles и его метод GetActiveLanguageProfile. Этот метод вернёт GUID, который используется для идентификации конкретной текстовой службы.

Куда вас это в итоге приведёт - вопрос, конечно, сложный. Потому что пока, кроме этих девяти примеров, больше нет ничего общедоступного - и ни один из примеров, не покрывает всех этих вопросов с языковой панелью :-(

Хотя, если вы хотите простой и красивый способ разобраться с этим (который документация описывает, но не рекомендует, поскольку вам придётся реализовать свой собственный подсчёт ссылок, вместо COM-ского!), вы можете вызвать TF_CreateThreadManager; это даст вам ITfThreadMgr, от которого вы можете запросить ITfSource. А затем вы можете установить advise sink через AdviseSink, чтобы получить полезный ITfActiveLanguageProfileNotifySink, который скажет вам, когда активный язык или текстовая служба изменились - через свой метод OnActivated, который, правда, не даст вам информации о языке (так что вам нужно будет сделать дополнительные вызовы, чтобы найти его!).

Если и существует область, для которой нужно написать больше примеров, так это она и есть - я так думаю. Хотя есть несколько людей, вроде Tavultesoft и Murasu, которые и сами разобрались, но их было бы больше, будь у нас готовы примеры.

This post brought to you by "" (U+a056, a.k.a. YI SYLLABLE BBIT)

Комментариев нет:

Отправить комментарий

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

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