2016-12-26 15 views
0

Это продолжение из What is the correct, modern way to handle arbitrary text input in a custom control on Windows? WM_CHAR? IMM? TSF?.Поскольку TranslateMessage() безоговорочно возвращает ненулевое значение, как я могу сказать, до или после факта, что произошел перевод?

Итак, после экспериментирования с не-IME-макетом (US English), не-TSF IME (японский FAKEIME из Windows XP DDK) и текстовой службы 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; 

Стандартный способ обработки ввода текста, либо с клавиатуры или через не-ФБО IME, это позволить TranslateMessage() сделать перевод WM_KEYDOWN -До- WM_CHAR. Однако есть проблема: MSDN говорит

Если сообщение WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN или WM_SYSKEYUP, возвращаемое значение равно нулю, независимо от перевода.

Это означает, что я не могу использовать его, чтобы определить, произошел ли перевод.

После чтения некоторых сообщений в блоге Майкла Каплана я решил, что могу использовать ToUnicode() или ToUnicodeEx(), чтобы сделать преобразование самостоятельно, передавая в массиве состояний от GetKeyboardState(). The wine source code seems to agree, но у него есть два особых случай, что я не уверен, если они являются вином конкретного или должны быть сделаны на реальном Windows, а также:

  • VK_PACKET - генерирует WM_CHAR непосредственно из данного сообщения LPARAM
  • VK_PROCESS - вызывает функцию ImmTranslateMessage(), которая, как представляется, является винной функцией или недокументированной функцией imm32.dll; Я не могу сказать, что истинно

И вино также ничего не делает с WM_KEYUP и WM_SYSKEYUP; опять же, я не знаю, верно ли это только для вина.

Но мне даже нужно беспокоиться об этих случаях в программе, использующей TSF? И если я это сделаю, каков «официальный» способ сделать это? И даже тогда, что бы я сделал на WM_KEYUP/WM_SYSKEYUP; мне нужно отправить их на ToUnicode() тоже? Мне даже нужно поймать WM_KEYUP s в моих окнах, если есть WM_CHAR?

Или я пропустил что-то, что не входит в какие-либо образцы MSF TSF, которые позволят мне просто заставить TSF заботиться о процессорах TF_PROFILETYPE_KEYBOARDLAYOUT? Я думал, что TSF сделал прозрачную сквозную IME, но мой эксперимент с образцом FAKEIME показал иное ...? Я вижу, что Firefox и Chromium также проверяют на TF_PROFILETYPE_KEYBOARDLAYOUT и даже используют ImmGetIMEFileName(), чтобы узнать, поддерживается ли макет клавиатуры IME или нет, но я не знаю, действительно ли они заботятся о том, чтобы вводить себя в эти случаи ...

Моя минимальная версия прямо сейчас Windows 7

Спасибо.

ОБНОВЛЕНИЕ Оригинальная версия этого вопроса, который необходимо знать о связанных WM_KEYUP s; при втором просмотре моего эквивалентного кода на других платформах это не будет необходимо, за исключением деталей TranslateMessage(); Я соответствующим образом скорректировал вопрос. (В OS X вы даже не даете события с ключевыми релизами в систему ввода текста, а на GTK + вы делаете, но кажется, что нажатия клавиш, которые вставляют символы, не беспокоят выпуски, и поэтому они не обрабатываются в любом случае, по крайней мере, для методы ввода, которые я пробовал (могут быть некоторые, которые делают ...).) Говоря, если я что-то пропустил, я добавил еще один вопрос.

+0

Почему вы работаете с событиями «вверх/вниз», а не с событиями char? –

+0

@ EricBrown, потому что мне все равно придется обрабатывать такие вещи, как навигационная клавиша со стрелкой и выбор клавиатуры. Или есть другой способ сделать это, что мне не хватает? Извините, что, кстати, неоднократно приставал к вам с небольшими вопросами. – andlabs

ответ

1

В общем, не рекомендуется пытаться дублировать внутренние элементы Windows. Это утомительно, подвержено ошибкам и, вероятно, изменится без предупреждения.

Редактирование управляет тем, что у меня есть доступ к источнику, чтобы отбирать клавиши со стрелками (и другие конкретные ключи) в обработчике WM_KEYDOWN и передавать все остальное в обработчик по умолчанию, который (в конечном счете) генерирует входные вызовы WM_CHAR или TSF (если ваш контроль поддерживает TSF, который он должен).

Вам все равно понадобится WM_CHAR в случае, если не задействован обработчик TSF. Однако вы всегда можете, чтобы обработчик WM_CHAR вызывал ваш метод ITextStoreACP :: InsertTextAtSelection.

+0

Хорошо. Я использую TSF, а также примеры приложений tsfpad; Я просто не уверен, почему мне все равно понадобится WM_CHAR в обоих случаях. О, хорошо, что это не должно быть лишней работой. Поэтому я предполагаю, что мой пользовательский редактор должен был бы просто знать, что ключ никогда не будет способствовать внесению текста? (Для чего это стоит, все остальные ОС, которые мне нужны для поддержки, делают все наоборот: сначала обрабатывайте текст, затем обрабатывайте все ключи, поэтому я задаю этот вопрос. Я не уверен, что этот момент затерялся перетасовать, когда я задал оригинальный вопрос.) Спасибо, тем временем! – andlabs

+1

@andlabs Не уверен в вводе текста в других операционных системах, но в Windows вы можете иметь произвольное количество WM_KEYDOWN перед WM_CHAR. (Рассмотрите составление ключей для языков, отличных от IME, или ALT-numpad для ввода символов Unicode на английском языке.) Как это бывает, клавиши со стрелками никогда не компонуются, поэтому безопасно заранее выбирать их. –

+0

Справа. Другие ОС также позволяют вам это делать; это просто, что вы должны дать им нажатия клавиш, а не наоборот. (Вы создаете прокси-объект для диспетчера методов ввода, который, как я полагаю, динамически загружается в процесс, а затем передает ключевое событие им как самый первый шаг в обработчике ключевых событий. Они возвращают логическое значение, указывающее, обрабатывали ли они нажатие клавиши, вернувшись назад, даже если это только начало более длинной композиции.) Я, вероятно, просто слишком сильно задумываюсь об этом, и, может быть, я просто должен считать, что ключи без пишущей машинки в целом безопасны ... – andlabs

 Смежные вопросы

  • Нет связанных вопросов^_^