Я пишу программу на C#, которая работает в фоновом режиме и позволяет пользователям использовать горячую клавишу для переключения раскладки клавиатуры в активном окне. (Windows поддерживает только CTRL + SHIFT и ALT + SHIFT)
Я использую RegisterHotKey, чтобы поймать горячую клавишу, и она работает нормально.
Проблема в том, что я не могу найти API для изменения раскладки клавиатуры для окна с фокусом.
ActivateKeyboardLayout и LoadKeyboardLayout могут изменять только раскладку клавиатуры для вызывающего потока.
Кто-нибудь знает, как изменить раскладку клавиатуры для другого потока (как это делает языковая панель)?
переключение раскладки клавиатуры по потоку? В отличие от общесистемного переключения раскладки? Что-то делаете с аккордами?
@drachenstern: не существует такой вещи, как общесистемное переключение раскладки клавиатуры; активная раскладка клавиатуры - это состояние для каждого потока пользовательского интерфейса. Я пытаюсь заменить Alt + Shift, чтобы случайно не нажать, поэтому аккорды не подходят (если я понимаю, что вы имели в виду).
Полагаю, вы знали, что я имел в виду в аккорде. Я просто подумал, что раскладка клавиатуры унаследована от системы, и мне было любопытно, почему вы захотите переопределить ее для каждого потока. Почему бы вам не использовать тот же макет в потоке, что и в системе? Вот что мне было любопытно. Полагаю, я просто хочу узнать больше о том, как увидеть мир.





Я думаю, уловка состоит в том, чтобы заставить ваш код выполняться в контексте потока, раскладку клавиатуры которого вы хотите изменить. Здесь вам нужно будет выполнить взаимодействие с win32 и узнать о внедрении DLL, чтобы ваш код выполнялся в удаленном потоке.
обработчик крючка клавиатуры выглядит здесь как хороший вариант.
Взгляни на http://www.codeproject.com/KB/threads/winspy.aspx
Другой способ, который может быть приемлемым, если вы пишете что-то только для себя: определите отдельную комбинацию клавиш для каждого макета (например, Alt + Shift + 1 и т. д.) И используйте SendInput для переключения между ними.
Обстоятельства, при которых это можно использовать, конечно, ограничены.
PostMessage(handle,
WM_INPUTLANGCHANGEREQUEST,
0,
LoadKeyboardLayout( StrCopy(Layout,'00000419'), KLF_ACTIVATE)
);
Это отлично работает с GetForegroundWindow для handle. Единственным исключением являются программы WPF, которые, похоже, блокируются в ответ на это сообщение.
@RomanStarkov Как узнать, какая версия WPF затронута и в чем причина?
@ Dims Я не знаю ни одного из них. Интересно, связана ли причина как-то с это (но это не поможет вам решить проблему)
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;
Когда вы переключаете языки с помощью встроенной в Windows горячей клавиши, это не влияет на разные потоки, не так ли?