Faça uma tecla shift se comportar como uma tecla de seta

6

Eu tenho um laptop Windows 10 com um teclado projetado por idiotas. Eles tentaram encaixar as teclas de seta onde eles não pertencem, com o resultado de que a tecla de seta para cima é entre a tecla shift direita e a tecla / (layout de teclado US). Essa é uma das coisas mais estúpidas que os designers poderiam ter feito, porque significa que quando eu clico na tecla Shift direita (que é a maior parte do tempo), eu acabo acertando a flecha. Isso é incrivelmente chato.

Eu encontrei um programa chamado Sharp Keys que me permite remapear as teclas de modo que a seta para cima se comporte como shift e o shift direito se comporte como seta para cima. Agora, pelo menos eu posso digitar. No entanto, agora perdi funcionalidades importantes para a tecla de seta para cima. A seta para cima (agora chamada de "shift" no meu teclado) não se repete. Então, não posso simplesmente segurar a tecla para subir. Em vez disso, tenho que apertar a tecla repetidamente. Como posso consertar isso, então minha tecla de shift direita se comporta como seta para cima e minha tecla de seta para cima se comporta como o shift direito?

EDITAR

Seguindo uma sugestão dos comentários, instalei o AutoHotkey. Eu tenho o seguinte script:

RShift::Up
Up::RShift

Eu tenho o mesmo problema de antes. Mas, como o AHK é uma linguagem de script, é possível usá-lo para alterar o comportamento de repetição?

    
por Scott Severance 24.11.2016 / 00:26

3 respostas

0

Enquanto a resposta de JJohnston2 me dava parte da solução, acabei perguntando a vários outros lugares e fazendo muita experimentação. Aqui está o que eu finalmente acabei com:

Up::RShift
*RShift::
    delay=400
    While GetKeyState("RShift", "P") {
        Send {Blind}{Up}
        Sleep %delay%    ; Set delay to taste
        delay=30
    }
    Return

Isso resolve os problemas de repetição de chave e permite que o shift + up funcione como esperado. Existem dois problemas pendentes que eu não resolvi, mas que são suficientemente baixos em prioridade e que vou considerar essa questão resolvida de qualquer maneira:

  1. A condição de corrida não está resolvida. Eu tentei colocar a primeira iteração fora do loop, como JJohnston2 fez, mas não teve efeito observável para mim.
  2. A causa raiz de todo esse problema é que o sistema não parece repetir as teclas shift, Ctrl ou Alt, mesmo que as outras repetam. Então, AHK não pode repetir o que nunca vê. Já que todos que eu pedi ajuda não tiveram esse problema, deve haver algo interessante com a minha configuração, mas eu não tenho a menor ideia do que isso possa ser.
por 28.11.2016 / 05:38
2

Eu tentei os hotkeys que você listou ... eles funcionaram bem para mim e repetiram automaticamente bem quando pressionados ...

#Persistent
Return

#IfWinActive    ; Make replacement operate globally
RShift::Up
Up::RShift

Você pode experimentar diferentes SendMode

RShift::SendInput {Up}
Up::SendInput {RShift}

ou ...

RShift::SendPlay {Up}
Up::SendPlay {RShift}

Você tem outros programas que estão interceptando estes ou algo assim? A repetição da chave funciona normalmente quando o script não está em execução?

A configuração de um loop personalizado pode ser algo assim ...

RShift::
    While GetKeyState("RShift", "P") {
        Send {Up}
        Sleep 50    ; Set delay to taste
    }
Return

EDITAR

Para lidar com a necessidade de outros modificadores funcionarem, um '*' pode ser usado com a tecla de atalho, embora no caso de ter duas teclas de shift, pode não funcionar corretamente por padrão. Eu adicionei um caso especial para a detecção de teclas shift, mas eu não sei como isso funcionaria se você colocasse outros modificadores na mistura ... nesse caso, você poderia adicionar o modificador {blind} ao Send declarações para ver se você poderia fazê-lo funcionar corretamente.

Para resolver a 'condição de corrida', outro atraso de pré-repetição também pode ser adicionado antes do loop de repetição junto com uma instrução de envio inicial (veja abaixo).

*Up::SendInput {blind}{RShift Down}
*Up Up::SendInput {blind}{RShift Up}

*RShift::
    Send % GetKeyState("LShift", "P") ? "+{Up}" : "{Up}"
    Sleep 250           ; Initial delay before repeat
    While GetKeyState("RShift", "P") {
        Send % GetKeyState("LShift", "P") ? "+{Up}" : "{Up}"
        Sleep 100    ; Repeat delay
    }
Return
    
por 25.11.2016 / 10:17
2

O problema com todas as outras respostas é que repetidas pressões de shift serão ignoradas porque a sub-rotina de teclas de atalho anterior ainda está sendo executada. Por definição, #MaxThreadsPerHotkey é 1, e # MaxThreads é 10.

Abaixo estão duas soluções possíveis. Ambos funcionam bem para mim.

Aumentar #MaxThreadsPerHotkey (e #MaxThreads)

SendMode Input
#MaxThreads 150
#MaxThreadsPerHotkey 150

; return the send command including any pressed modifier keys
getSendCommand() {
    sendCmd = {Up}
    sendCmd = % GetKeyState("LAlt", "P") ? "!" . sendCmd : sendCmd
    sendCmd = % GetKeyState("LCtrl", "P") ? "^" . sendCmd : sendCmd
    sendCmd = % GetKeyState("LShift", "P") ? "+" . sendCmd : sendCmd
    sendCmd = % GetKeyState("Win", "P") ? "#" . sendCmd : sendCmd
    return sendCmd
}

*$RShift::
    ; Immediately send an up key
    Send % getSendCommand()
    Sleep, 450

    While GetKeyState("RShift", "P") {  ; while key remains pressed
        Send % getSendCommand()  ; keep sending up keys
        Sleep, 30
    }
    Return

Anula imediatamente a execução quando a tecla shift é liberada

SendMode Input

; return the send command including any pressed modifier keys
getSendCommand() {
    sendCmd = {Up}
    sendCmd = % GetKeyState("LAlt", "P") ? "!" . sendCmd : sendCmd
    sendCmd = % GetKeyState("LCtrl", "P") ? "^" . sendCmd : sendCmd
    sendCmd = % GetKeyState("LShift", "P") ? "+" . sendCmd : sendCmd
    sendCmd = % GetKeyState("Win", "P") ? "#" . sendCmd : sendCmd
    return sendCmd
}

*$RShift::
    ; Immediately send an up key
    Send % getSendCommand()

    ; Initial wait period (sleep time = 350 ms, execution time ~450 ms)
    Loop 35 {  ; Check keystate every 10 ms, abort execution as soon as shift is released
        Sleep, 10  ; 10 ms is the shortest possible sleep interval
        if not GetKeyState("RShift", "P") {
            return
        }
    }

    ; Start repeating if and while key is still pressed. Stop execution as soon as shift is released
    While GetKeyState("RShift", "P") {
        Send % getSendCommand()

        Loop 2 {
            if not GetKeyState("RShift", "P") {
                return
            }
            Sleep, 10
        }
    }
    Return
    
por 12.06.2018 / 19:24