netch80: (Default)
netch80 ([personal profile] netch80) wrote2009-05-09 03:02 pm

CapsLock как переключатель клавиатуры на Windows

Тема известная (просто нагуглив можно получить и монстров типа Punto, и лёгкий keyla, и простой как угол дома lswitch), но захотелось получить вариант как у меня на Unix - Caps переключает между английским и русским, а Ctrl+Caps - между русским и украинским.

Пока идеально не получилось: [UPD] на FAR какие-то странные эффекты. Впрочем, и там можно через родной переключатель (как Ctrl+Shift) выбрать любую.

Текущие результаты (исходник и экзешник). Исходник - слегка замученный lswitch.c от Haali. Caps крутит раскладки по кругу вперёд, Ctrl+Caps - назад. Командная строка с 'q' убирает резидент, с '3s' запускает в моём любимом режиме, в любом другом случае пытается ставить с переключением по кругу.

Уже удобнее, чем в Putty, и Caps тоже можно включать (имитируя блондинку;))

[identity profile] dmih.livejournal.com 2009-05-09 01:58 pm (UTC)(link)
Я пол года назад для одного человека пытался за 30 минут такое слепить.

Сначала получилось так:
ActivateKeyboardLayout ((IntPtr)1, 0);
это нормально, но не работало в службе терминалов.

Потом сделал по простому:
keybd_event (20, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, (UIntPtr)0);
keybd_event (20, 0x45, KEYEVENTF_EXTENDEDKEY, (UIntPtr)0);
keybd_event (20, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, (UIntPtr)0);

keybd_event (0xA4, 0x45, KEYEVENTF_EXTENDEDKEY, (UIntPtr)0);
keybd_event (0xA0, 0x45, KEYEVENTF_EXTENDEDKEY, (UIntPtr)0);
keybd_event (0xA4, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, (UIntPtr)0);
keybd_event (0xA0, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, (UIntPtr)0);

Тонкостей не помню, но идея понятна :) (это для Alt-Shift).

Ну и надо расшифровать это из .NET PInvoke до одноименных функций Win32.

Ну а потом да, тот человек нашел себе указанный выше вами файл, собрал, и пользуется :)

[identity profile] trivee.livejournal.com 2009-05-09 08:44 pm (UTC)(link)
GetWindowThreadProcessId
netch: (Default)

[personal profile] netch 2009-05-09 09:24 pm (UTC)(link)
Ага, спасибо. Теперь ситуация интереснее. Такое работает на всех проверенных приложениях, кроме FAR. На FAR, картина, словно у него всегда текущий английский несмотря на ввод и показания индикатора - в результате Caps всегда уводит на русский, Ctrl+Caps на украинский, а на английский можно вернуться только неотменённым Ctrl+Shift. Что-то в нём странное.

[identity profile] trivee.livejournal.com 2009-05-10 08:38 pm (UTC)(link)
Так и есть. Обработка клавиатуры для консольных приложений делается не в их потоке, а в потоке внутри CSRSS. Перебрав их вручную, его легко найти и убедиться, что GetKeyboardLayout изменяется вместе с переключением клавиатуры. Но вот как это делать автоматически, или получить текущую клавиатурную раскладку для консольного приложения, не знаю.
netch: (Default)

[personal profile] netch 2009-05-11 07:04 am (UTC)(link)
Нагуглилось вот такое:

"Вешается системный хук WH_SHELL (HSHELL_LANGUAGE)", подробнее не было

но по этим двум идентификаторам много разъяснений.

Впрочем, пока не буду этого делать - много кодить надо;)