Смена раскладки клавиатуры в системе

Рейтинг: 2Ответов: 2Опубликовано: 02.04.2015

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

Что можете посоветовать?

Ответы

▲ 3Принят

Если нет функции "наделать дел в чужом процессе" (а обычно таких функций нет), то вам нужно загрузить свою динамическую библиотеку в чужой процесс и вызвать код "изнутри" него. Таким образом поступают всякого рода Пунто Свитчеры, файрволы и прочие утилиты.

C# использовать для таких вещей крайне не рекомендуется, потому что вместе с C# вы затащите в каждый процесс среду выполнения .NET. Это тяжеловесня штука, и не каждый процесс такому будет рад. Например, MS до сих пор не рекомендует писать расширения оболочки на управляемых языках (они реализованы как in-process COM-серверы, и грузятся во многие процессы в системе).

Ту часть приложения, которой нужно интимное взаимодействие со многими процессами, лучше написать, например, на C++.

[Добавлено]

Как выяснилось, вы можете воспользоваться PostMessage и WM_INPUTLANGCHANGEREQUEST. Пример на AutoHotKey.

▲ 3

Разобрался, вот результат:

Для начала цепляем две ф-ции WinAPI из user32.dll

[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();

[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool PostMessage(IntPtr hWnd, int Msg, int wParam, int lParam);

[DllImport("user32.dll")]
static extern int LoadKeyboardLayout(string pwszKLID, uint Flags);

Говорил о двух а написал три, первая - для поиска хендла активного в текущий момент окна

Далее все предельно просто, загружаем код раскладки и отправляем его с помощью WM_INPUTLANGCHANGEREQUEST (код 0x50) в активное окно:

string lang = "00000409";
int ret = LoadKeyboardLayout(lang, 1);
PostMessage(GetForegroundWindow(), 0x50, 1, ret);

Минимальный список языков:

"00000407" Немецкий (стандартный)
"00000409" Английский (США)
"0000040C" Французский (стандартный)
"0000040D" Финский
"00000410" Итальянский
"00000415" Польский
"00000419" Русский
"00000422" Украинский
"00000423" Белорусский
"00000425" Эстонский
"00000426" Латвийский
"00000427" Литовский

Я не совсем понял как, но код работает, а это главное! Спасибо @Athari за помощь и правильный пинок в правильном направлении!