Jump to content

Keyboard remapping


Recommended Posts

Hello everyone. I am a new user of AutoIt, and I want to use it to remap my keyboard. I am a Colemak Keyboard Layout user, and enjoyed it for several years. However, it is still needed to prepare a Colemak -> QWERTY script in case other people want to use my computer, enter password, etc. Colemak official website has a AutoHotkey ahk script to do so, and works neatly in general case. Unfortunately I find that AutoHotkey would occasionally fail to block the source key, thus send out both the source key and target key in my key press. Moreover, the remapped key are often "sticked", meaning even I have released the source key, the target key is still in "key down" state. Therefore I want to give a try on AutoIt.

The requirement is simple: for a set of "source" keys and "target" keys, once the source key is down or up, the system receive the key down and key up event of the corresponding target key, not the source key. The remapping should be in low level, so that even modifier keys are combined, it still works. Below is the example AutoHotkey script. After running the script, whenever the user press the "f" key in the keyboard, the system gets "e". When shift+f, it is remapped to shift+e. Circular remapping should be avoided, thus the f -> e -> k -> n -> ... chain must NOT occur.

#SingleInstance force
#NoEnv
SendMode Input
SetTitleMatchMode 3

f::e
p::r
g::t
j::y
l::u
u::i
y::o
`;'::'
r::s
s::d
t::f
d::g
n::j
e::k
i::l
o::`
k::n

I did some research before posting this thread. In the forum, the most similar request I found is Keymapping (*NOT* logging), but it seems no complete solution is given and the scripts are huge. I also tried the "HotKeySet" function and HotKey.au3 script, but they require the modifier keys be explicitly hard coded, therefore have to write a function for each combination of modifier keys.

Is there a existing solution for keyboard remapping with AutoIt? Thank you for your help!

P.S. Is there a way to change my display name in the forum, not the user name? Is it limited? I see a "Display name history" in the control panel, indicating the possibility. Thanks!

Edited by CrendKing
Link to comment
Share on other sites

P.S. Is there a way to change my display name in the forum, not the user name? Is it limited? I see a "Display name history" in the control panel, indicating the possibility. Thanks!

Sure it's possible, just go to settings, instead of the profile.

Posted Image

Edited by AdmiralAlkex
Link to comment
Share on other sites

I have to admit, I like the way AHK lets you do that Posted Image

Right, so you want to remap keys? OK, sure so you have two good options:

  • Use HotKeySet and just re-send the key you want it to equal (first thought is "that's a long way about it", wrong :D)
  • Use _IsPressed() to capture the keys and practically do the same as HotKeySet
Thinking about it, in 2007 I wrote a script to move my keys 8 places to the right, Origin Keyboard Layout. It's messy yes, can I do it better now? Yes.

I'd use the basic code from OKL, but use two arrays, one for the original character codes and another for the output codes. Each time a key is pressed, I'd look for the corresponding key code and send that.

James

Link to comment
Share on other sites

Sure it's possible, just go to settings, instead of the profile.

Posted Image

Thanks for pointing out. Apparently, new user cannot change the display name for a period of time after registering.

I have to admit, I like the way AHK lets you do that Posted Image

Right, so you want to remap keys? OK, sure so you have two good options:

  • Use HotKeySet and just re-send the key you want it to equal (first thought is "that's a long way about it", wrong :D)
  • Use _IsPressed() to capture the keys and practically do the same as HotKeySet
Thinking about it, in 2007 I wrote a script to move my keys 8 places to the right, Origin Keyboard Layout. It's messy yes, can I do it better now? Yes.

I'd use the basic code from OKL, but use two arrays, one for the original character codes and another for the output codes. Each time a key is pressed, I'd look for the corresponding key code and send that.

James

This is resourceful! I'm sure I can turn it into a Colemak <-> QWERTY script. Once done, I will upload here. Thank you very much!

Link to comment
Share on other sites

Here is what I made:

#cs
    Name: Colemak to QWERTY
    Author: Crend King
    Description: Based on JBr00ks's Original Keyboard Layout
    Thanks to: JBr00ks, Toady and RazerM!
#ce

#include <Misc.au3>
#include <vkConstants.au3>

If _Singleton("C2Q", 1) = 0 Then
    MsgBox(262144, "Error", "Colemak to QWERTY is already running!")
    Exit
EndIf

$DLL = DllOpen("user32.dll")
$key_count = 17 ; number of key to remap
Dim $lower_src_keys[$key_count] = ["f", "p", "g", "j", "l", "u", "y", "r", "s", "t", "d", "n", "e", "i", "o", "k", ";"]
Dim $upper_src_keys[$key_count] = ["F", "P", "G", "J", "L", "U", "Y", "R", "S", "T", "D", "N", "E", "I", "O", "K", ":"]
Dim $lower_dest_keys[$key_count] = ["e", "r", "t", "y", "u", "i", "o", "s", "d", "f", "g", "j", "k", "l", ";", "n", "p"]
Dim $upper_dest_keys[$key_count] = ["E", "R", "T", "Y", "U", "I", "O", "S", "D", "F", "G", "J", "K", "L", ":", "N", "P"]
Dim $key_code[$key_count]   ; key code for _IsPressed()

; get key codes
For $i = 0 To ($key_count - 2)
    $key_code[$i] = Hex(Execute("$VK_" & $upper_src_keys[$i]))
Next
$key_code[$key_count - 1] = "BA"    ; special case for the semicolon key

For $i = 0 To ($key_count - 1)
    HotKeySet($lower_src_keys[$i], "Block")
    HotKeySet($upper_src_keys[$i], "Block")
Next

While 1
    Sleep(1)
    CheckKeys()
WEnd

Func Block()
EndFunc   ;==>Block

Func CheckKeys()
    For $i = 0 To ($key_count - 1)
        If _IsPressed($key_code[$i], $DLL) Then
            If _IsPressed(10, $DLL) = _GetCapsState() Then
                HotKeySet($lower_dest_keys[$i])
                Send($lower_dest_keys[$i], 1)
                HotKeySet($lower_dest_keys[$i],d "Block")
            Else
                HotKeySet($upper_dest_keys[$i])
                Send($upper_dest_keys[$i], 1)
                HotKeySet($upper_dest_keys[$i], "Block")
            EndIf
            
            ; interruptable repeat when key is down and not up
            For $j = 0 To 24
                If _IsPressed($key_code[$i], $DLL) Then
                    Sleep(1)
                Else
                    ExitLoop
                EndIf
            Next
        EndIf
    Next
EndFunc   ;==>CheckKeys

Func _GetCapsState()
    $av_ret = DllCall($DLL, "int", "GetKeyState", "int", $VK_CAPITAL)
    Return $av_ret[0]
EndFunc   ;==>_GetCapsState

The virtual key code definition (vkConstants.au3) from http://www.autoitscript.com/forum/index.php?showtopic=90492 is used.

I tried to use just two arrays, but the special case of the semicolon key force me to make another two, to keep the code simple and neat. Obviously, it is still too complicated than the AutoHotkey approach. Maybe AutoIt is not suitable for keyboard remapping. Never mind, hope the script useful to someone interested.

C2Q.au3

vkConstants.au3

Edited by CrendKing
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...