Cambia layout tastiera per altri processi
-
06-07-2019 - |
Domanda
Sto scrivendo un programma in C # che viene eseguito in background e consente agli utenti di utilizzare un tasto di scelta rapida per cambiare il layout della tastiera nella finestra attiva. (Windows supporta solo CTRL + SHIFT e ALT + SHIFT )
Sto usando RegisterHotKey per catturare il tasto di scelta rapida e funziona bene.
Il problema è che non riesco a trovare alcuna API per modificare il layout della tastiera per la finestra focalizzata.
ActivateKeyboardLayout e LoadKeyboardLayout possono solo modificare il layout della tastiera per il thread chiamante.
Qualcuno sa come modificare il layout della tastiera per un thread diverso (come fa la barra della lingua)?
Soluzione
Un altro modo che può essere accettabile se stai scrivendo qualcosa solo per te stesso: definisci una combinazione di tasti separata per ogni layout (come Alt + Maiusc + 1, ecc.) e usa SendInput per passare da uno all'altro.
Le circostanze in cui questo è utilizzabile sono ovviamente limitate.
Altri suggerimenti
PostMessage(handle,
WM_INPUTLANGCHANGEREQUEST,
0,
LoadKeyboardLayout( StrCopy(Layout,'00000419'), KLF_ACTIVATE)
);
Penso che il trucco sia far eseguire il codice nel contesto del thread di cui desideri modificare il layout di tastiera. Dovrai fare un po 'di interoperabilità win32 qui e conoscere l'iniezione DLL per far eseguire il tuo codice nel thread remoto.
Un gestore di ganci per tastiera sembra una buona opzione per te qui.
Dai un'occhiata 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;