Page 1 of 1

how to remap keyboard?

Posted: Tue Apr 12, 2011 8:37 pm
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

Re: how to remap keyboard?

Posted: Tue Apr 12, 2011 9:43 pm
by idle
You should be able to do it a level with a low level keyboard hook
I'll post an example.

Re: how to remap keyboard?

Posted: Tue Apr 12, 2011 9:59 pm
by IdeasVacuum
Try something like KeyTweak (free):

http://www.pcworld.com/downloads/file/f ... ption.html

Re: how to remap keyboard?

Posted: Tue Apr 12, 2011 10:42 pm
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()

Re: how to remap keyboard?

Posted: Tue Apr 12, 2011 11:18 pm
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..........

Re: how to remap keyboard?

Posted: Tue Apr 12, 2011 11:38 pm
by idle
Didn't know you could do that through the registry?
for xp
http://msdn.microsoft.com/en-us/windows ... 63447.aspx

Re: how to remap keyboard?

Posted: Wed Apr 13, 2011 1:25 pm
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??

Re: how to remap keyboard?

Posted: Wed Apr 13, 2011 3:36 pm
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.

Re: how to remap keyboard?

Posted: Wed Apr 13, 2011 7:09 pm
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 :(

Re: how to remap keyboard?

Posted: Wed Apr 13, 2011 7:34 pm
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()

Re: how to remap keyboard?

Posted: Thu Apr 14, 2011 4:10 pm
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()

Re: how to remap keyboard?

Posted: Thu Apr 14, 2011 4:59 pm
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


Re: how to remap keyboard?

Posted: Thu Apr 14, 2011 9:25 pm
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