Mudança de layout de teclado para outro processo
-
06-07-2019 - |
Pergunta
Eu estou escrevendo um programa em C # que é executado em segundo plano e permite aos usuários usar um atalho para layouts de teclado interruptor na janela ativa. (Somente para Windows suporta Ctrl + Shift e ALT + Shift )
Eu estou usando RegisterHotKey para pegar o atalho, e ele está funcionando bem.
O problema é que não consigo encontrar qualquer API para alterar o layout do teclado para a janela focada.
ActivateKeyboardLayout e LoadKeyboardLayout só pode alterar o layout do teclado para o segmento de chamada.
Alguém sabe como alterar o layout do teclado para um segmento diferente (a forma como a barra de idiomas faz)?
Solução
Outra forma que pode ser aceitável se você estiver escrevendo algo apenas para si mesmo: definir uma combinação de teclas separados para cada layout (como Alt + Shift + 1, etc), e uso SendInput para alternar entre eles.
As circunstâncias em que esta é utilizável são limitados, é claro.
Outras dicas
PostMessage(handle,
WM_INPUTLANGCHANGEREQUEST,
0,
LoadKeyboardLayout( StrCopy(Layout,'00000419'), KLF_ACTIVATE)
);
Eu acho que o truque é obter o seu código para executar no contexto do segmento, cujo layout de teclado que você deseja mudar. Você precisa fazer alguma interoperabilidade win32 aqui e aprender sobre DLL Injection para obter o seu código para executar o fio remoto.
A aparência do manipulador gancho de teclado como uma boa opção para você aqui.
Dê uma olhada 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;