Posts: 41
Threads: 11
Joined: Jul 2012
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.
Posts: 12,086
Threads: 142
Joined: Dec 2002
To remap a key to a character, use macro like this:
Function make_quote_key
Trigger `
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.
Posts: 41
Threads: 11
Joined: Jul 2012
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.
Posts: 12,086
Threads: 142
Joined: Dec 2002
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.
Posts: 12,086
Threads: 142
Joined: Dec 2002
A simple keyboard remapping function with a hook.
Function remap_keyboard
;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
;/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
;/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.
Posts: 12,086
Threads: 142
Joined: Dec 2002
Also you can create keyboard layouts with Microsoft Keyboard Layout Creator.
http://msdn.microsoft.com/en-us/goglobal/bb964665.aspx
Posts: 41
Threads: 11
Joined: Jul 2012
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:
Posts: 12,086
Threads: 142
Joined: Dec 2002
Assign trigger: QM events -> Startup -> QM file loaded. Don't check synchronous.
This code is little tested. Also would need to implement disabling temporarily.
Posts: 41
Threads: 11
Joined: Jul 2012
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.
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.
Posts: 12,086
Threads: 142
Joined: Dec 2002
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.
|