Изменить раскладку клавиатуры для другого процесса
-
06-07-2019 - |
Вопрос
Я пишу программу на C #, которая работает в фоновом режиме и позволяет пользователям использовать горячие клавиши для переключения раскладок клавиатуры в активном окне. (Windows поддерживает только CTRL + SHIFT и ALT + SHIFT )
Я использую RegisterHotKey, чтобы поймать горячую клавишу, и она работает нормально.
Проблема в том, что я не могу найти API для изменения раскладки клавиатуры для сфокусированного окна.
ActivateKeyboardLayout и LoadKeyboardLayout могут изменять только раскладку клавиатуры для вызывающего потока.
Кто-нибудь знает, как изменить раскладку клавиатуры для другого потока (как это делает языковая панель)?
Решение
Другой способ, который может быть приемлем, если вы пишете что-то только для себя: определите отдельную комбинацию клавиш для каждого макета (например, Alt + Shift + 1 и т. д.) и используйте SendInput для переключения между ними.
Обстоятельства, при которых это можно использовать, ограничены, конечно.
Другие советы
PostMessage(handle,
WM_INPUTLANGCHANGEREQUEST,
0,
LoadKeyboardLayout( StrCopy(Layout,'00000419'), KLF_ACTIVATE)
);
Я думаю, что хитрость заключается в том, чтобы заставить ваш код выполняться в контексте потока, раскладку клавиатуры которого вы хотите изменить. Вам нужно будет поработать над Win32 и узнать об DLL-инъекциях, чтобы ваш код выполнялся в удаленном потоке.
обработчик перехвата клавиатуры выглядит следующим образом хороший вариант для вас здесь.
Посмотрите на http://www.codeproject.com/KB/threads/winspy.aspx р>
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;