how to remap keyboard?

Just starting out? Need help? Post your questions and find answers here.
gabriel
Enthusiast
Enthusiast
Posts: 137
Joined: Sat Aug 01, 2009 4:49 pm
Location: Beirut, Lebanon

how to remap keyboard?

Post by gabriel »

hello:
is it possible to remap some keys of keyboard, for example, on my french layout keyboard, I like to remap the "£" to "<", and "µ" to ">".
the program should be resident and active for all subsequent windows applications.
Thanks
User avatar
idle
Always Here
Always Here
Posts: 5927
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: how to remap keyboard?

Post by idle »

You should be able to do it a level with a low level keyboard hook
I'll post an example.
Windows 11, Manjaro, Raspberry Pi OS
Image
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: how to remap keyboard?

Post by IdeasVacuum »

Try something like KeyTweak (free):

http://www.pcworld.com/downloads/file/f ... ption.html
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
idle
Always Here
Always Here
Posts: 5927
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: how to remap keyboard?

Post by idle »

replaces A->S Z->X
but if you have mappings like A->Z and Z->A you will need to ignore the next keyevent or it'll switch it back to what it was

Code: Select all

#WH_KEYBOARD_LL = 13
#INPUT_HARDWARE = 2
#INPUT_KEYBOARD = 1
#KEYEVENTF_UNICODE = $4
#KEYEVENTF_SCANCODE = $8


Global myKeyHook

Structure KBDLLHOOKSTRUCT
 vkCode.l;
 scanCode.l;
 flags.l;
 time.l;
 dwExtraInfo.l;
EndStructure

Structure INPUT_DATA
type.l
  StructureUnion
     mi.MOUSEINPUT
     ki.KEYBDINPUT
     hi.HARDWAREINPUT
  EndStructureUnion
EndStructure

Procedure.l KeyProc(nCode.l,wParam.l,lParam.l)

    Protected *keyInput.KBDLLHOOKSTRUCT 
    Protected ret.l, hwnd.l
    Protected mkeyInput.KEYBDINPUT
    Protected InputData.INPUT_DATA
    
    Inputdata\type = #INPUT_KEYBOARD   
    *keyInput = lParam
   
    If nCode = #HC_ACTION 
      
      If *keyInput\vkCode =#VK_A
          inputdata\ki\wVk= #VK_S 
          
      ElseIf *keyInput\vkCode =#VK_Z
          inputdata\ki\wVk= #VK_X     
          
      EndIf 
      If inputdata\ki\wVk <> 0  
        
        inputdata\ki\wScan = 0
        inputdata\ki\time = *keyInput\time
        InputData\ki\dwExtraInfo = *keyInput\dwExtraInfo     
               
        If wParam = #WM_KEYUP
           InputData\ki\dwFlags = #KEYEVENTF_SCANCODE | #KEYEVENTF_KEYUP   
        EndIf
          
         SendInput_(1,InputData, SizeOf(INPUT_DATA))
           
          result =1   
       Else 
          result= CallNextHookEx_(myKeyhook, nCode, wParam, lParam)  
       EndIf
        
    Else
      result = CallNextHookEx_(myKeyhook, nCode, wParam, lParam)
    EndIf
 
    ProcedureReturn result
             
EndProcedure 

Procedure SetHook()
    hInstance = GetModuleHandle_(0)
    If hInstance 
       myKeyhook = SetWindowsHookEx_(#WH_KEYBOARD_LL, @KeyProc(),hInstance,0) 
    Else 
       MessageRequester("hook", "can't get module handle")
    EndIf       
EndProcedure 

Procedure KillHook()

   UnhookWindowsHookEx_(myKeyhook)
   myKeyHook = 0 
  
EndProcedure 


sethook()

OpenWindow(0,0,0,200,200,"test")

Repeat 
  ev=WaitWindowEvent()
Until ev= #PB_Event_CloseWindow 

killhook()
Windows 11, Manjaro, Raspberry Pi OS
Image
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: how to remap keyboard?

Post by IdeasVacuum »

Hi Idle, I got the impression that Gabriel is actually just looking for a one-off re-map for his own keyboard. That can be done in the registry if we are talking Windows, which is what KeyTweak does in a User friendly way..........
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
idle
Always Here
Always Here
Posts: 5927
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: how to remap keyboard?

Post by idle »

Didn't know you could do that through the registry?
for xp
http://msdn.microsoft.com/en-us/windows ... 63447.aspx
Windows 11, Manjaro, Raspberry Pi OS
Image
gabriel
Enthusiast
Enthusiast
Posts: 137
Joined: Sat Aug 01, 2009 4:49 pm
Location: Beirut, Lebanon

Re: how to remap keyboard?

Post by gabriel »

Thank you guys:
The situation is the following:
on my french layout keyboard, i don't have the "<" and ">" keys, I use for thar alt+60 and alt+62.
In the same time, I use very rarely "£" and "µ", so I thought may be it's possible to remap £ and µ to < and >.
I tried SharpKeys and similar, they want the virtual key number #VK_etc... I searched in the PB constants, I didn't find any virtual key for them.
The problem is that "£" is shift+"$", and "µ" is shift+"*", (the attached picture may help), so we need to bypass the shift :(
May be there is no solution for that.

edit: how to insert a picture??
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: how to remap keyboard?

Post by IdeasVacuum »

Did you try KeyTweak?

To insert an image, you need to upload the image to an image host (such as your own website), then use the Img button here to insert the URL to the image.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
gabriel
Enthusiast
Enthusiast
Posts: 137
Joined: Sat Aug 01, 2009 4:49 pm
Location: Beirut, Lebanon

Re: how to remap keyboard?

Post by gabriel »

KeyTweak, like others (SharpKeys, KeyExtender, etc...), accept only english keyboard layout, also the characters £,µ,<,> don't figure in the list of available keys.
Apparently, I should resign :(
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4955
Joined: Sun Apr 12, 2009 6:27 am

Re: how to remap keyboard?

Post by RASHAD »

Hi gabriel

Code by idle
Modified by RASHAD
Shift + 8 ----> ">"
Shift + 4 ----> "<"
Esc to end

Test and report

Code: Select all

#WH_KEYBOARD_LL = 13
#INPUT_HARDWARE = 2
#INPUT_KEYBOARD = 1
#KEYEVENTF_UNICODE = $4
#KEYEVENTF_SCANCODE = $8


Global myKeyHook,Quit

Structure KBDLLHOOKSTRUCT
vkCode.l;
scanCode.l;
flags.l;
time.l;
dwExtraInfo.l;
EndStructure

Structure INPUT_DATA
type.l
  StructureUnion
     mi.MOUSEINPUT
     ki.KEYBDINPUT
     hi.HARDWAREINPUT
  EndStructureUnion
EndStructure

Procedure.l KeyProc(nCode.l,wParam.l,lParam.l)

    Protected *keyInput.KBDLLHOOKSTRUCT
    Protected ret.l, hwnd.l
    Protected mkeyInput.KEYBDINPUT
    Protected InputData.INPUT_DATA
   
    Inputdata\type = #INPUT_KEYBOARD   
    *keyInput = lParam
   
    If nCode = #HC_ACTION
     If GetAsyncKeyState_(#VK_SHIFT)&32768
          If *keyInput\vkCode =#VK_8    ;Shift + 8
              inputdata\ki\wVk= #VK_OEM_PERIOD
             
          ElseIf *keyInput\vkCode =#VK_4    ;Shift + 4
              inputdata\ki\wVk= #VK_OEM_COMMA            
           
          EndIf
      EndIf
      If inputdata\ki\wVk <> 0        
          inputdata\ki\wScan = 0
          inputdata\ki\time = *keyInput\time
          InputData\ki\dwExtraInfo = *keyInput\dwExtraInfo     
                 
          If wParam = #WM_KEYUP
             InputData\ki\dwFlags = #KEYEVENTF_SCANCODE | #KEYEVENTF_KEYUP   
          EndIf
           
          SendInput_(1,InputData, SizeOf(INPUT_DATA))
             
          result =1   
       Else
          result= CallNextHookEx_(myKeyhook, nCode, wParam, lParam) 
       EndIf
       
    Else
      result = CallNextHookEx_(myKeyhook, nCode, wParam, lParam)
    EndIf
    
    If GetAsyncKeyState_(#VK_ESCAPE)&32768
      End
    EndIf

    ProcedureReturn result
             
EndProcedure

Procedure SetHook()
    hInstance = GetModuleHandle_(0)
    If hInstance
       myKeyhook = SetWindowsHookEx_(#WH_KEYBOARD_LL, @KeyProc(),hInstance,0)
    Else
       MessageRequester("hook", "can't get module handle")
    EndIf       
EndProcedure

Procedure KillHook()

   UnhookWindowsHookEx_(myKeyhook)
   myKeyHook = 0
 
EndProcedure


sethook()

OpenWindow(0,10,10,200,20,"test",#PB_Window_Invisible)

Repeat
  ev=WaitWindowEvent()
ForEver
killhook()
Egypt my love
gabriel
Enthusiast
Enthusiast
Posts: 137
Joined: Sat Aug 01, 2009 4:49 pm
Location: Beirut, Lebanon

Re: how to remap keyboard?

Post by gabriel »

Hi:
thanks RASHAD:
I tried your code and changed slightly, it works, except I don't know the VK number for "<" (on a french layout keyboard)

Code: Select all

    #WH_KEYBOARD_LL = 13
    #INPUT_HARDWARE = 2
    #INPUT_KEYBOARD = 1
    #KEYEVENTF_UNICODE = $4
    #KEYEVENTF_SCANCODE = $8

    Global myKeyHook,Quit

    Structure KBDLLHOOKSTRUCT
    vkCode.l;
    scanCode.l;
    flags.l;
    time.l;
    dwExtraInfo.l;
    EndStructure

    Structure INPUT_DATA
    type.l
      StructureUnion
         mi.MOUSEINPUT
         ki.KEYBDINPUT
         hi.HARDWAREINPUT
      EndStructureUnion
    EndStructure

    Procedure.l KeyProc(nCode.l,wParam.l,lParam.l)

        Protected *keyInput.KBDLLHOOKSTRUCT
        Protected ret.l, hwnd.l
        Protected mkeyInput.KEYBDINPUT
        Protected InputData.INPUT_DATA
       
        Inputdata\type = #INPUT_KEYBOARD   
        *keyInput = lParam
        
        Debug *keyInput\vkCode
        If nCode = #HC_ACTION
;          If *keyInput\vkCode =220
;             inputdata\ki\wVk= 226 
         If GetAsyncKeyState_(#VK_SHIFT)&32768
              If *keyInput\vkCode =186    ;Shift + £
                  inputdata\ki\wVk= 226   ; >        
              ElseIf *keyInput\vkCode =220    ;Shift + µ
                  inputdata\ki\wVk= ???   ; <
              EndIf
          EndIf
          If inputdata\ki\wVk <> 0       
              inputdata\ki\wScan = 0
              inputdata\ki\time = *keyInput\time
              InputData\ki\dwExtraInfo = *keyInput\dwExtraInfo     
                     
              If wParam = #WM_KEYUP
                 InputData\ki\dwFlags = #KEYEVENTF_SCANCODE | #KEYEVENTF_KEYUP   
              EndIf
               
              SendInput_(1,InputData, SizeOf(INPUT_DATA))
                 
              result =1   
           Else
              result= CallNextHookEx_(myKeyhook, nCode, wParam, lParam)
           EndIf
           
        Else
          result = CallNextHookEx_(myKeyhook, nCode, wParam, lParam)
        EndIf
       
        If GetAsyncKeyState_(#VK_ESCAPE)&32768
          End
        EndIf

        ProcedureReturn result
    EndProcedure

    Procedure SetHook()
        hInstance = GetModuleHandle_(0)
        If hInstance
           myKeyhook = SetWindowsHookEx_(#WH_KEYBOARD_LL, @KeyProc(),hInstance,0)
        Else
           MessageRequester("hook", "can't get module handle")
        EndIf       
    EndProcedure

    Procedure KillHook()
       UnhookWindowsHookEx_(myKeyhook)
       myKeyHook = 0
    EndProcedure

    sethook()

    OpenWindow(0,10,10,200,20,"test",#PB_Window_Invisible)

    Repeat
      ev=WaitWindowEvent()
    ForEver
    killhook()
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4955
Joined: Sun Apr 12, 2009 6:27 am

Re: how to remap keyboard?

Post by RASHAD »

gabriel
Use the next code with all your keyboard keys with Shift or Ctrl
till you get Less-Than"<" and Greater-Than">" and give us what you got

Code: Select all

OpenWindow(0, 0, 0,300,40, "", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
TextGadget(0, 0, 8, 300, 20, "Press any key.", #PB_Text_Center)

Repeat
  Event = WaitWindowEvent()
  
  If Event = #WM_CHAR
    key = EventwParam()
    Debug Str(KEY) + "    " + Chr(key)
    SetGadgetText(0, Str(KEY) + "    " + Chr(key))
    
  EndIf
  
Until Event = #PB_Event_CloseWindow

Egypt my love
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4955
Joined: Sun Apr 12, 2009 6:27 am

Re: how to remap keyboard?

Post by RASHAD »

@idle
As per idle suggest and what I prefer to end the program(From inside the loop)


@ gabriel

http://msdn.microsoft.com/en-us/library/ms892155.aspx


< = #VK_OEM_102
> = Shift + #VK_OEM_102

Use Ctrl-Q To quit

Code: Select all

#WH_KEYBOARD_LL = 13
#INPUT_HARDWARE = 2
#INPUT_KEYBOARD = 1
#KEYEVENTF_UNICODE = $4
#KEYEVENTF_SCANCODE = $8

Global myKeyHook,Quit

Structure KBDLLHOOKSTRUCT
vkCode.l;
scanCode.l;
flags.l;
time.l;
dwExtraInfo.l;
EndStructure

Structure INPUT_DATA
type.l
  StructureUnion
     mi.MOUSEINPUT
     ki.KEYBDINPUT
     hi.HARDWAREINPUT
  EndStructureUnion
EndStructure

Procedure.l KeyProc(nCode.l,wParam.l,lParam.l)

    Protected *keyInput.KBDLLHOOKSTRUCT
    Protected ret.l, hwnd.l
    Protected mkeyInput.KEYBDINPUT
    Protected InputData.INPUT_DATA
   
    Inputdata\type = #INPUT_KEYBOARD   
    *keyInput = lParam
   
    If nCode = #HC_ACTION
     If GetAsyncKeyState_(#VK_SHIFT)&32768
          If *keyInput\vkCode =#VK_8
              inputdata\ki\wVk= #VK_OEM_PERIOD
             
          ElseIf *keyInput\vkCode =#VK_4
              inputdata\ki\wVk= #VK_OEM_COMMA            
           
          EndIf
      EndIf
      If inputdata\ki\wVk <> 0        
          inputdata\ki\wScan = 0
          inputdata\ki\time = *keyInput\time
          InputData\ki\dwExtraInfo = *keyInput\dwExtraInfo     
                 
          If wParam = #WM_KEYUP
             InputData\ki\dwFlags = #KEYEVENTF_SCANCODE | #KEYEVENTF_KEYUP   
          EndIf
           
          SendInput_(1,InputData, SizeOf(INPUT_DATA))
             
          result =1   
       Else
          result= CallNextHookEx_(myKeyhook, nCode, wParam, lParam) 
       EndIf
       
    Else
      result = CallNextHookEx_(myKeyhook, nCode, wParam, lParam)
    EndIf
    
    ProcedureReturn result
             
EndProcedure

Procedure SetHook()
    hInstance = GetModuleHandle_(0)
    If hInstance
       myKeyhook = SetWindowsHookEx_(#WH_KEYBOARD_LL, @KeyProc(),hInstance,0)
    Else
       MessageRequester("hook", "can't get module handle")
    EndIf       
EndProcedure

Procedure KillHook()

   UnhookWindowsHookEx_(myKeyhook)
   myKeyHook = 0
 
EndProcedure


sethook()

OpenWindow(0,-200,10,120,20,"")
OpenWindow(1, 0, 0, 0, 0, "", #PB_Window_Invisible)
SetWindowLongPtr_(WindowID(0),#GWL_HWNDPARENT,WindowID(1))

Repeat
  If WaitWindowEvent() = #WM_CHAR
    Key = EventwParam()
  EndIf
Until Key = 17
KillHook()
End
Egypt my love
Post Reply