Изменение макета клавиатуры для другого процесса
Я пишу программу на С#, которая работает в фоновом режиме, и позволяет пользователям использовать горячую клавишу для переключения раскладок клавиатуры в активном окне. (Windows поддерживает только CTRL + SHIFT и ALT + SHIFT)
Я использую RegisterHotKey, чтобы поймать горячую клавишу, и она работает нормально.
Проблема заключается в том, что я не могу найти какой-либо API для изменения раскладки клавиатуры для сфокусированного окна.
ActivateKeyboardLayout и LoadKeyboardLayout могут изменять только раскладку клавиатуры для вызывающего потока.
Кто-нибудь знает, как изменить раскладку клавиатуры для другого потока (как это делает языковая панель)?
Ответы
Ответ 1
Другой способ, который может быть приемлемым, если вы пишете что-то только для себя: определите отдельную комбинацию клавиш для каждого макета (например, Alt + Shift + 1 и т.д.) и используйте SendInput для переключения между ними.
Условия, в которых это возможно, ограничены, конечно.
Ответ 2
PostMessage(handle,
WM_INPUTLANGCHANGEREQUEST,
0,
LoadKeyboardLayout( StrCopy(Layout,'00000419'), KLF_ACTIVATE)
);
Ответ 3
Я думаю, что трюк заключается в том, чтобы заставить ваш код выполнять в контексте потока, раскладка клавиатуры которого вы хотите изменить. Вам нужно будет сделать несколько win32 interop здесь и узнать о DLL Injection, чтобы ваш код выполнялся в удаленном потоке.
A обработчик клавиатуры для клавиатуры выглядит для вас хорошим вариантом.
Взгляните на
http://www.codeproject.com/KB/threads/winspy.aspx
Ответ 4
function ChangeRemoteWndKeyboardLayoutToRussian(
const RemoteHandle: THandle): Boolean;
var
Dumme: DWORD;
Layout: HKL;
begin
Layout := LoadKeyboardLayout('00000419', KLF_ACTIVATE);
Result := SendMessageTimeOut(RemoteHandle, WM_INPUTLANGCHANGEREQUEST,
0, Layout, SMTO_ABORTIFHUNG, 200, Dumme) <> 0;
if Result then
Result := SendMessageTimeOut(RemoteHandle, WM_INPUTLANGCHANGEREQUEST,
RUSSIAN_CHARSET, Layout, SMTO_ABORTIFHUNG, 200, Dumme) <> 0;
end;