2008-11-04 14 views
13

Estoy escribiendo un programa en C# que se ejecuta en segundo plano y permite a los usuarios utilizar una tecla de acceso rápido para cambiar los diseños de teclado en la ventana activa. (Windows sólo admite CTRL +SHIFT y ALT +SHIFT)Cambiar diseño de teclado para otro proceso

estoy usando RegisterHotKey para atrapar la tecla de acceso directo, y está funcionando bien.

El problema es que no puedo encontrar ninguna API para cambiar el diseño del teclado para la ventana enfocada.

ActivateKeyboardLayout y LoadKeyboardLayout solo pueden cambiar el diseño del teclado para el hilo de llamada.

¿Alguien sabe cómo cambiar el diseño del teclado para un hilo diferente (como lo hace la barra de idioma)?

+0

Al cambiar idiomas usando una tecla de acceso directo ventanas-incorporadas, que no afecta a diferentes hilos, lo hace? – JXG

+0

por cambio de distribución de teclado de hilo? A diferencia de la conmutación de diseño en todo el sistema? Hacer algo con Chording? – jcolebrand

+0

@drachenstern: no existe la conmutación de disposición del teclado en todo el sistema; el diseño del teclado activo es un estado por subproceso de UI. Estoy tratando de reemplazar Alt + Shift para que no lo presione por accidente, por lo que no es una opción (si entiendo lo que quiso decir). – SLaks

Respuesta

1

Otra forma en que puede ser aceptable si está escribiendo algo sólo por sí mismo: definir una combinación de teclas separadas para cada diseño (como + Shift Alt + 1, etc), y use SendInput para cambiar entre ellos.

Las circunstancias en las que esto se puede utilizar están limitadas por supuesto.

2

Creo que el truco está en hacer que su código se ejecute en el contexto del hilo cuyo diseño de teclado desea cambiar. Tendrá que hacer algo de interoperabilidad de win32 aquí y aprender sobre la inyección de DLL para que su código se ejecute en el hilo remoto.

A keyboard hook handler parece una buena opción para usted aquí.

Tome un vistazo a http://www.codeproject.com/KB/threads/winspy.aspx

8
PostMessage(handle, 
    WM_INPUTLANGCHANGEREQUEST, 
    0, 
    LoadKeyboardLayout(StrCopy(Layout,'00000419'), KLF_ACTIVATE) 
); 
+0

Esto funciona perfectamente usando 'GetForegroundWindow' para el' handle'. Una excepción son los programas de WPF, que parecen bloquearse en respuesta a este mensaje. –

0
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; 
+0

Esto no funciona en todos los procesos, si no recuerdo mal. – SLaks

Cuestiones relacionadas