Jump to content
Sign in to follow this  
KaFu

Research - Map virtual-key code to character value...

Recommended Posts

KaFu

Hello Forum,

I'm currently researching, how to map a virtual-key code (like received by _IsPressed()) to the corresponding character value in the currents user environment (capital or non capital letter, special character, Unicode etc.)...

Here's how far I got

Documentation on MSDN:

http://msdn.microsoft.com/en-us/library/ms646307(VS.85).aspx

MapVirtualKeyEx()

MapVirtualKeyExW()

#include<array.au3>
#include<winapi.au3>
;#include<misc.au3>

;while 1
;   if _IsPressed('5a') then ConsoleWrite('z' & @crlf)
;WEnd

$hWnd_Desktop = _WinAPI_GetDesktopWindow()

;
; Z = 5A

$sHexKey = "31"

ConsoleWrite(_WinAPI_GetKeyboardLayout($hWnd_Desktop) & @CRLF)
$sKbLayout = _WinAPI_GetKeyboardLayout($hWnd_Desktop)
ConsoleWrite(_WinAPI_MapVirtualKeyEx($sHexKey, $sKbLayout) & @CRLF)
ConsoleWrite(Chr('0x' & _WinAPI_MapVirtualKeyEx($sHexKey, $sKbLayout)) & @CRLF)
ConsoleWrite(_LoWord('0x' & _WinAPI_MapVirtualKeyEx($sHexKey, $sKbLayout)) & @CRLF)
ConsoleWrite(_LoWord(Chr('0x' & _WinAPI_MapVirtualKeyEx($sHexKey, $sKbLayout))) & @CRLF)

Func _LoWord($x)
    Return BitAND($x, 0xFFFF)
EndFunc   ;==>_LoWord


; http://msdn.microsoft.com/en-us/library/ms646307(VS.85).aspx

Func _WinAPI_MapVirtualKeyEx($sHexKey, $sKbLayout)
    Local Const $MAPVK_VK_TO_VSC = 0
    Local Const $MAPVK_VSC_TO_VK = 1
    Local Const $MAPVK_VK_TO_CHAR = 2
    Local Const $MAPVK_VSC_TO_VK_EX = 3
    Local Const $MAPVK_VK_TO_VSC_EX = 4

    Local $Ret = DllCall('user32.dll', 'long', 'MapVirtualKeyExW', 'int', '0x' & $sHexKey, 'int', 2, 'int', '0x' & $sKbLayout)
    ;_ArrayDisplay($Ret)
    Return $Ret[0]
EndFunc   ;==>_WinAPI_MapVirtualKeyEx



; http://www.autoitscript.com/forum/index.php?showtopic=95883&view=findpost&p=690005
; by Yashied

Func _WinAPI_GetKeyboardLayout($hWnd)
    Local $Ret = DllCall('user32.dll', 'long', 'GetWindowThreadProcessId', 'hwnd', $hWnd, 'ptr', 0)
    If (@error) Or ($Ret[0] = 0) Then
        Return SetError(1, 0, 0)
    EndIf
    $Ret = DllCall('user32.dll', 'long', 'GetKeyboardLayout', 'long', $Ret[0])
    If (@error) Or ($Ret[0] = 0) Then
        Return SetError(1, 0, 0)
    EndIf
    ;Return '0000' & Hex($Ret[0], 4)
    Return Hex($Ret[0], 4)
EndFunc   ;==>_WinAPI_GetKeyboardLayout

Later this day I stumbled over this blog entry:

http://blogs.msdn.com/michkap/archive/2007...25/1948887.aspx

pointing to this function:

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

ToUnicodeEx()

This one looks even more promising then MapVirtualKeyEx() to me, but didn't give it try until now.

Would be glad about any input :D .

Best Regards

Share this post


Link to post
Share on other sites
Malkey

I recently came across 'GetKeyNameText' from 'user32.dll'.

You might find it interesting. In that it returns the name of the key pressed.

All output is to console.

;
;#include <misc.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <sendmessage.au3>

;Global Const $WM_KEYDOWN = 0x0100
;Global Const $WM_KEYUP = 0x0101

Global $sKeyName
$Gui = GUICreate("Key Name Demo (Esc to exit)", 400, 100, 100, 100, $WS_POPUP, $WS_EX_TOPMOST)
GUISetBkColor(0xFF0000, $Gui)

;$Lab = GUICtrlCreateLabel("Please press a keyboard key",20,50)
GUISetState(@SW_SHOW, $Gui)

GUIRegisterMsg($WM_NCLBUTTONUP, "WindowEvents")
;GUIRegisterMsg($WM_KEYDOWN, "WindowEvents")
GUIRegisterMsg($WM_KEYUP, "WindowEvents")
HotKeySet("{Esc}", "Quit");  Esc to Exit
Local $iOld = 0

While 1
    _SendMessage($Gui, $WM_SYSCOMMAND, 0xF012, 0)
    If $sKeyName = "Enter" Then MsgBox(0, "Test", "Enter Pressed", 1, $Gui)
    If $sKeyName = "Num Enter" Then MsgBox(0, "Test", "Num Enter Pressed", 1, $Gui)
    $sKeyName = ""
    Sleep(10)
WEnd


Func Quit()
    Exit
EndFunc  ;==>Quit

Func WindowEvents($hWnd, $Msg, $wParam, $lParam)
    Switch $Msg
        Case $WM_KEYUP
            $aRet = DllCall('user32.dll', 'int', 'GetKeyNameText', 'int', $lParam, 'str', "", 'int', 256)
            $sKeyName = $aRet[2]
    EndSwitch
    ConsoleWrite($sKeyName & @CRLF)
    ConsoleWrite(" $hWnd " & $hWnd & " $Msg " & $Msg & " $wParam " & $wParam & " $lParam " & $lParam & "  Key Name = " & $aRet[2] & @CRLF)
;Return 'GUI_RUNDEFMSG'
EndFunc  ;==>WindowEvents
;

Share this post


Link to post
Share on other sites
KaFu

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
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.