![Se corrigió la ubicación física de los atajos deshacer (Ctrl-Z) y rehacer (Ctrl-Y) entre las distribuciones de teclado alemán y ruso en Windows.](https://rvso.com/image/1540070/Se%20corrigi%C3%B3%20la%20ubicaci%C3%B3n%20f%C3%ADsica%20de%20los%20atajos%20deshacer%20(Ctrl-Z)%20y%20rehacer%20(Ctrl-Y)%20entre%20las%20distribuciones%20de%20teclado%20alem%C3%A1n%20y%20ruso%20en%20Windows..png)
Estoy imitando a otra víctima del caos en la distribución del teclado, que sufre un problema similar pero ligeramente diferente.
Utilizo ampliamente las distribuciones de teclado alemán y ruso en mi estación de trabajo con Windows 10 y cambio a menudo entre ellas. El problema está relacionado con el hecho de que las letras Y y Z están cambiadas en el diseño del teclado alemán en comparación con el diseño QWERTY estándar en inglés.
Si uso el diseño alemán, el método abreviado Deshacer (Ctrl-Z) está vinculado a la tecla Z, que se encuentra en el medio de la primera fila de letras entre T y U. El método Rehacer (Ctrl-Y) está vinculado a la tecla Y. , que se encuentra a la izquierda de la X en la fila inferior de letras en el diseño QWERTZ alemán.
Si cambias el diseño al ruso, de repente sucede algo malo. Los atajos deshacer y rehacer cambian mutuamente su posición en el teclado. Deshacer (Ctrl-Z) se ubica ahora en Y (fila inferior, a la izquierda de X) y Rehacer en Z (fila superior, entre T y U). Esta ubicación es idéntica a la ubicación de Ctrl-Z y Ctrl-Y en la distribución de teclado estándar en inglés.
Eso significa que la ubicación de los atajos de Deshacer y Rehacer cambia al opuesto cada vez que cambio la distribución del teclado. Como puedes imaginar, siempre estoy presionando el atajo equivocado, porque es imposible aprender dos patrones oscilantes opuestos, al menos mi columna vertebral protesta. Como uso los atajos de Deshacer y Rehacer con mucha frecuencia, este comportamiento me irrita mucho.
Quiero arreglar la ubicación física (teclas) de los accesos directos Rehacer y Deshacer en todo el conjunto de aplicaciones de Windows, ya sea en formato alemán o mejor inglés.
Usar el diseño en inglés de forma permanente para todo tipo de textos en latín, aunque soluciona el problema con los accesos directos de Deshacer/Rehacer, pero no es una opción para mí, porque necesito escribir textos en alemán con todas las diéresis y ß (no sugiero un diseño internacional para ingresar acentos, porque el alemán es mi idioma principal y quiero escribir sus letras nativas con solo presionar una tecla).
Como ya mencionó el colega en la pregunta mencionada, no hay una respuesta obvia en Internet. El mismo problema se resuelve en Ubuntu creando una distribución de teclado personalizada. No puedo encontrar ninguna información sobre cómo crear un diseño personalizado para Windows o cómo parchear el actual.
Este comportamiento es consistente en todas las versiones de Windows que conozco y está profundamente relacionado con los diseños iniciales de distribución del teclado, que simplemente son incompatibles para los usuarios que usan el par de idiomas alemán-ruso como yo.
Una buena solución se implementará en Windows directamente sin ningún software adicional, o solo software gratuito de código abierto. Se aceptan soluciones funcionales que incluyan AutoHotKey.
Con la ayuda de @miroxlav se me ocurrió este script AHK que funciona a medias:
; Undo
$^z::
hWnd := WinExist("A")
ThreadID := DllCall("GetWindowThreadProcessId", "UInt", hWnd, "UInt", 0)
hKL := DllCall("GetKeyboardLayout", "UInt", ThreadID, "UInt")
If (hKL = 0x4070409) ; revert undo-redo hotkey mapping if in German layout
Send ^y
Else
Send ^н ; pass the keystroke through
Return
; Redo
$^y::
hWnd := WinExist("A")
ThreadID := DllCall("GetWindowThreadProcessId", "UInt", hWnd, "UInt", 0)
hKL := DllCall("GetKeyboardLayout", "UInt", ThreadID, "UInt")
If (hKL = 0x4070409) ; revert undo-redo hotkey mapping if in German layout
Send ^z
Else
Send ^я ; pass the keystroke through
Return
Este script reasigna perfectamente Ctrl-Y <-> Ctrl-Z en el diseño alemán, pero corrompe ambas teclas de acceso rápido en el diseño ruso. Utilizo ^н y ^я con la esperanza de emular los equivalentes de código de escaneo Ctrl-Y o Ctrl-Z para el diseño ruso, pero no funciona (genera н para Ctrl-Y y nada visible para Ctrl-Z). Usar ^z y ^y para ruso tampoco funciona, generando letras z e y respectivamente.
A diferencia de la respuesta de Miroxlav, tuve que usar el gancho del teclado ($) para evitar bucles y eliminar etiquetas (probablemente un error de copiar y pegar)
Solución sugerida por Williams:
^SC02c::Send ^y
^SC015::Send ^z
lamentablemente tampoco funciona. Genera letras simples 'y' y 'z' en el diseño ruso y ningún cambio en el diseño alemán (Ctrl-Z y Ctrl-Y pasaron en el mapeo original).
Sigo buscando la solución.
Respuesta1
Simplemente puede crear su propia distribución de teclado usandoMicrosoft Keyboard Layout Creator 1.4 del Centro de descarga oficial de Microsoft.
Youtube proporciona muchos tutoriales en vídeo sobre cómo usarlo (comoestecon configuración regional rusa), simplemente busque su nombre. Pero básicamente, clonas una de las distribuciones de teclado existentes y la modificas según tus necesidades.
Solución AutoHotKey:
(nota: reemplace 0x4090409
la constante (teclado de EE. UU.) con el valor que se aplique a su diseño)
$^z::
hWnd := WinExist("A")
ThreadID := DllCall("GetWindowThreadProcessId", "UInt", hWnd, "UInt", 0)
hKL := DllCall("GetKeyboardLayout", "UInt", ThreadID, "UInt")
If (hKL = 0x4090409)
Send ^z
Else
Send ^y
Return
$^y::
hWnd := WinExist("A")
ThreadID := DllCall("GetWindowThreadProcessId", "UInt", hWnd, "UInt", 0)
hKL := DllCall("GetKeyboardLayout", "UInt", ThreadID, "UInt")
If (hKL = 0x4090409)
Send ^y
Else
Send ^z
Return
Se necesita Hook ($) para evitar la recursividad, es decir, Send ^z
invocar Send ^y
simplemente otra macro AHK.
Probé esa condición de detección del teclado y funcionó bien.
Por supuesto, puede activar la detección del teclado y, por lo tanto, optimizar el código, etc. Me dio pereza hacer eso. :)
Respuesta2
Finalmente encontré una solución que funciona para mí (script AutoHotKey):
; Undo Ctrl-Z
^sc02C::
Send, ^{sc015}
Return
; Redo Ctrl-Y
^sc015::
Send, ^{sc02C}
Return
Mantiene perfectamente la tecla deshacer (Ctrl-Z) en su lugar lógico (fila inferior izquierda) independientemente de la distribución del teclado.
Gracias @Miroxlav y @Williams por aportar piezas para la solución.
Respuesta3
Según la respuesta de Anton, actualicé el código a AHK v2 y agregué soporte para la variante Ctrl+Shift, ya que muchos programas ahora lo usan para Rehacer.
#Requires AutoHotkey v2.0
;Remapping upper mid Y/Z key (Y in EN layout)
^sc015::Send "^{sc02C}"
^+sc015::Send "^+{sc02C}"
;Remapping lower left Y/Z key (Z in EN layout)
^sc02C::Send "^{sc015}"
^+sc02C::Send "^+{sc015}"
El objetivo de este script es arreglar la acción Deshacer en la tecla Y/Z inferior izquierda, ya que diferentes diseños (QWERTZ vs QWERTY) mueven la Z a la mitad superior, lo cual no es práctico. Lo mismo ocurre con Rehacer, que ahora está fijado en la tecla Y/Z media superior.
Dado que Deshacer/Rehacer generalmente se realiza mediante Ctrl+Z/Y, esto se puede lograr capturando la tecla presionada y reemitiendo la tecla "correcta". Esas son las ^sc0**
líneas. Las ^+sc0**
líneas son para reemitir eventos Ctrl+Shift+Z/Y, ya que muchos programas usan Ctrl+Shift+Z para Rehacer.
La clave "correcta" está entre comillas porque si miras el script, en realidad debería simplemente girar Ctrl(+Shift)+Y/Z en todas partes... por lo tanto, no logra nada. Sin embargo, eso no es lo que sucede y simplemente funciona... aunque yo y AFAIK, el autor original, no sabemos por qué.
Si tiene alguna idea de por qué esto funciona o no para usted... dígalo.
Respuesta4
A pesar de que la respuesta aceptada funciona, solo funciona si el diseño seleccionado en ese momento era el diseño alemán; de lo contrario, invierte la función de deshacer en todos los demás diseños.
Para solucionar esto sólo tienes que sustituir el código estadounidense 0x4090409
por el código alemán 0x4070407
. También ha cambiado la declaración if de esta manera:
$^z::
hWnd := WinExist("A")
ThreadID := DllCall("GetWindowThreadProcessId", "UInt", hWnd, "UInt", 0)
hKL := DllCall("GetKeyboardLayout", "UInt", ThreadID, "UInt")
If (hKL = 0x4070407)
Send ^y
Else
Send ^z
Return
$^y::
hWnd := WinExist("A")
ThreadID := DllCall("GetWindowThreadProcessId", "UInt", hWnd, "UInt", 0)
hKL := DllCall("GetKeyboardLayout", "UInt", ThreadID, "UInt")
If (hKL = 0x4070407)
Send ^z
Else
Send ^y
Return