Главная » Delphi » Резидентный переключатель раскладки

0

Отметим для начала, что в Windows понятие "раскладка" достаточно размытое, и об этом подробнее мы будем говорить в следующей главе. Здесь мы только установим, что под "раскладкой" будем понимать то, что имелось в виду традиционно — а именно переключение вида отображаемых экранных символов при нажатин клавиш на клавиатуре.

Пользоваться предлагаемыми в Windows вариантами переключения раскладки при хоть сколько-нибудь профессиональной работе просто невозможно — во-первых, есть опасность, что пальцы навсегда останутся скрюченными, во-вторых, если без шуток, то стандартные комбинации клавиш <Alt>+<Shift> и <Ctrl>+<Shifi> задействованы и в некоторых других важных операциях. Например, при использовании первой из этих комбинаций всегда есть опасность, что вы отпустите клавишу <Shift> раньше, и тогда по <Alt> сработает пресловутая функция обращения к меню, а вторая комбинация задействована в операциях с выделением текста и вводом специальных символов в Word. Поэтому использовать отдельный переключатель раскладки — просто жизненная необходимость. Лучшая из готовых подобных программ но всеобщему признанию — Punto Switcher, однако, по личному мнению автора, она злостно нарушает принцип "программа не должна делать ничего лишнего" (см. главу I) — слишком много в ней наворочено функций, которые при ближайшем рассмотрении только мешаются. Поэтому мы создадим свою собственную "переключалку". которая только это и будет уметь.

Можно попробовать все сделать совсем просто: во-первых, использовать уже отработанный механизм горячих клавиш (можно даже не создавать новое приложение— просто зарегистрировать еще одну горячую клавишу в программе Layout из главы 5, присвоив ей номер 2) и по ее нажатию осуществлять процедуру, состоящую всего из одной строки:

ActivateKeyboardLayout(0,HKL_NEXT);

Эта функция будет переключать раскладку циклически. Можно усложнить дело, и переключать с помощью попеременных вызовов функции LoadKeyboardLayout{идентификатор языка>, KLF_ACTIVATE), подставляя в качестве идентификатора каждый раз либо ‘00000409’ , либо ‘00000419’ — так, как мы делали в примере из главы 5. Результат будет один — в Windows ХР это работать не будет. Более того, оно не должно работать и в Windows 98, т. к. в "пособии" — т. е. на том же сайте MSDN — про обе эти функции ясно написано "This function only affects the layout for the current process or thread" (Эта функция воздействует только на раскладку клавиатуры текущего процесса или потока). Просто реализация данных функций в Windows ХР и 98 разная: в первой текущим процессом, очевидно, считается тот, что вызывает функцию, а во второй — тот, что в данный момент активен (это отчасти логично— вспомните про различную реализацию многозадачности в данных системах).

Так что если вам потребуется переключать раскладку для текущего приложения, можно использовать указанный способ, он является общепринятым и официально рекомендованным к использованию. А для резидентного переключателя мы обратимся к первоисточнику, чтобы попытаться дополнительно понять, что происходит, и в какую сторону нам надо направить свои мысли. Открываем сайт MSDN Library [14] и на странице "About Keyboard Input" под заголовком "Languages, Locales, and Keyboard Layouts" читаем (привожу сразу в переводе на русский):

"Обычно не предполагается, что прикладные программы будут непосредственно управлять языками ввода. Вместо этого пользователь устанавливает комбинацию языка и рас/сладки, а затем переключается между ними. Когда пользователь щелкает мышью по тексту, имеющему знаки из другого языка, прикладная программа вызывает функцию ActivateKeyboardLayout, чтобы активизировать заданную по умолчанию раскладку пользователя для этого языка. Если пользователь редактирует текст на языке, которого нет в действующем списке, прикладная программа может вызывать функцию LoadKeyboardLayout с [этим] языком, чтобы получить раскладку, базирующуюся на этом языке."

Как видите, нам не доверяют управлять языком— вдруг мы еще какой- нибудь не тот язык включим в свою программу и осмелимся заговорить на суахили без санкции от Microsoft. С другой стороны, отсюда же следует, что в принципе пользовательские приложения в Windows могут устанавливать свою комбинацию языка и раскладки. Но реализовано это нагромождение понятий настолько запутанно, очень часто даже фирменные приложения выкидывают весьма забавные коленца (примеры см. в следующей главе). Но нам это не надо, зато нужно переключать раскладку для чужого приложения — а этого, как мы видим, "не предполагается". Так что придется опять "нажимать мышью на <Reset>" и имитировать нажатие клавиш переключения раскладки, зарегистрированных в системе — слава богу, надежный способ мы уже знаем!

Надумав такое, отвлечемся от собственно переключения: а так ли хорошо здесь использовать механизм горячих клавиш? Для того чтобы переключать раскладку, нам хотелось бы использовать какую-нибудь заведомо неиспользуемую в других программах клавишу, т. е. как раз здесь удобно выбрать либо из правых <Alt>, <Ctrl>, <Shift> или <Enter>, либо из почти неиспользуемых клавиш типа <Scroll Lock> или <Pause>. Механизм горячих клавиш в принципе не позволяет зарегистрировать в их качестве клавиши- модификаторы, но даже если и удастся (есть сведения, что это можно обойти вот таким хитрым способом: RegisterHotKey(FHandle, 1, MOD_CONTROL, 0), нам это мало поможет: правый-левый <Ctrl> тут все равно не отличишь.

Источник: Ревнч Ю. В.  Нестандартные приемы программирования на Delphi. — СПб.: БХВ-Петербург, 2005. — 560 е.: ил.

По теме:

  • Комментарии