Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Remapping Key to a certain character only,layout independent
#1
Greetings , i need to remap one key on my keyboard , to type --> " <-- double quote character , independent of keyboard layout German/English etc and it will also be sent as key.

I used to do this with other software but currently i cant do it with QM therefore i request some help.
There is an option in QM to remap keys but it remaps one key to other in its natural form , there is no key on my keyboard which sends " instead it sends ' , and only shift+' sends "

I also do not prefer remaps which require me to restart or logoff system .

And this isnt the only key i want to remap ,
win key
alt+tab -> to minimize current windows instead of randomly switching around (so far i couldnt remap this either)
right ctrl-> to del , natural delete button is far top right on my keyboard, this too should work as delete no matter where and when and on which application.

So learning the proper way to remap keys in QM is important for me , thanks for any help in advance.
#2
To remap a key to a character, use macro like this:
Function make_quote_key
Trigger `     Help - how to add the trigger to the macro
Code:
Copy      Help
key "''"
When you press ` key, it types " character.

However with some keyboard layouts it is other physical key. If it must always be the same physical key, probably it is possible with custom keyboard hook, although not tested. I'll try to create such function if you need.

To remap single Win key, only the remapping with restarting will be reliable. Because it is a special key - modifier, you cannot reliably remap it using a trigger or custom hook. Similar with Right Ctrl, although possibly can be used custom hook too.

Alt+Tab - use a macro with Alt+Tab trigger. Low level keyboard hook must be checked in Options/Triggers.
#3
Alright thanks for the answer .
Alt tab trigger now works with low level thingy checked. There are some problems with windows key remapping, ill get into that later.

However looks like im interested into that custom hook you mensioned because .
I want to remap a behavior to the key itself , not what it types depending on keyboard layout.

In that case, this piece of code exactly does what i need , used in autohotkey as script.
SC027::c
Return

In that example , 'c' character keysend behavior is mapped to the key's Scan code . And once i run the script , both for alttab, or some other key mapped to LWIN , works reliably without requiring me to restart anything.
From what i can think of is that , Macro eats given keycode and sends remapped keycode to applications. Which produces natural behavior.

Any further help is welcome.
#4
QM keyboard triggers use virtual key code. With most keyboard layouts physical keys are mapped to the same virtual key codes, although to different characters. With some keyboard layouts, some physical keys are mapped to other virtual key codes. Then as trigger need to use scan code. QM triggers don't support it, but it possible with custom keyboard hook.
#5
A simple keyboard remapping function with a hook.

Function remap_keyboard
Code:
Copy      Help
;Run this function to turn on remapping. Run again to turn off.


;if already running, end the thread and exit
if getopt(nthreads)>1
,shutdown -6 0 "remap_keyboard"
,ret

;set hook and wait
int keyhook=SetWindowsHookEx(WH_KEYBOARD_LL &remap_keyboard_hook _hinst 0)
MessageLoop ;;need to process messages
UnhookWindowsHookEx keyhook

Function remap_keyboard_hook
Code:
Copy      Help
;/remap_keyboard
function nCode wParam KBDLLHOOKSTRUCT&h

;This function runs as a hook procedure, called by Windows on each key down and up event.


if(nCode!=HC_ACTION) goto gRet ;;normally always HC_ACTION
if(h.flags&LLKHF_INJECTED) goto gRet ;;sent by a macro, not by the user

;call a function that returns a nonempty value if remapping needed for this key
VARIANT v=remap_keyboard_my_map(h)

if v.vt ;;remapping found
,;send the remap-key and "eat" the source-key
,int up=h.flags&LLKHF_UP
,opt keysync 1 ;;minimal synchronization; recommended in functions like this
,sel v.vt
,,case VT_I4 ;;virtual-key code etc
,,if(!up) key+ (v.lVal); else key- (v.lVal)
,,
,,case VT_BSTR ;;text
,,if(!up) _s=v; key (_s)
,,
,ret 1 ;;return 1 means "eat" the event, ie not pass to the foreground window as well as to other hooks

;gRet
ret CallNextHookEx(0 nCode wParam &h) ;;need this, otherwise other hooks (eg QM keyboard triggers) will not receive the event

Function remap_keyboard_my_map
Code:
Copy      Help
;/remap_keyboard
function` KBDLLHOOKSTRUCT&h

;Edit this function to create your remapping.

;h - contains user-pressed key info. Don't change it.

;If you want to remap this key, let this function return the remapping:
;;;To remap to a key, return the virtual-key code.
;;;To remap to a string (eg a character), return the string.

;You can also edit this function while remap_keyboard thread is running. To apply, click Save or Compile button. On syntax error remap_keyboard thread will end. You can run this function (click Run button) to launch remap_keyboard.


int up=h.flags&LLKHF_UP ;;0 down, 1 up

;;debug. Shows pressed keys, their virtual-key codes and scancodes. Disable when not needed.
FormatKeyString h.vkCode 0 &_s
out "%s %s, vk=0x%X, sc=0x%X%s" _s iif(up "up  " "down") h.vkCode h.scanCode iif(h.flags&LLKHF_EXTENDED ", extended" "")


;Examples:

;remap using scancodes; scancodes represent physical keys
sel h.scanCode
,case 0x5C ret VK_DELETE ;;WinR to Delete
,case 0xD ret "''" ;;key += to character "
,;...

;;remap using virtual-key codes; virtual-key codes represent logical keys on current keyboard layout; look for the table in QM Help
sel h.vkCode
,case 'Q' ret 'W' ;;key Q to W
,case 'W' ret 'Q' ;;key W to Q
,;...

#ret ;;everything you'll type below will not be included in the macro. Eg you can type any text here when testing.
#6
Also you can create keyboard layouts with Microsoft Keyboard Layout Creator.
http://msdn.microsoft.com/en-us/goglobal/bb964665.aspx
#7
Flawlessly coded , beautifully explained . Thanks a lot for the effort . This exactly does what i want .
Now only one thing left to complete this wonder .
How can i make it , so that ,
These hooks will be online everytime system restarts or as long as QM is up and running .
Or is there any startup folder inside QM for functions :mrgreen:
#8
Assign trigger: QM events -> Startup -> QM file loaded. Don't check synchronous.

This code is little tested. Also would need to implement disabling temporarily.
#9
Grettings , again .
I have been using the macro for a while and it works, however there is a problem with remapping one key to the windows key.
Code:
Copy      Help
sel h.scanCode
,case 0x29 ret 0x5B
Once remapped , windows key works but i cannot use it as modifier key.
Ie. If i click (remapped win key)+e This is what i get.

" down, vk=0xC0, sc=0x29
E down, vk=0x45, sc=0x12
E up , vk=0x45, sc=0x12
" up , vk=0xC0, sc=0x29

Operation log with natural win key

Win down, vk=0x5B, sc=0x5B, extended
E down, vk=0x45, sc=0x12
E up , vk=0x45, sc=0x12
Win up , vk=0x5B, sc=0x5B, extended

First log is produced from remapped key and it opens up start menu and types e inside the search box,
Second log is produced from natural win key and it properly opens up windows explorer . Need some help here.
#10
I updated function remap_keyboard_hook in previous post. Now should work.

But this method of remapping from/to modifier keys is not reliable and not recommended. For example, QM keyboard triggers may have problems with these keys.


Forum Jump:


Users browsing this thread: 1 Guest(s)